# データベース設計書

## 概要

本ドキュメントは、Roslyn（.NET Compiler Platform）プロジェクトで使用されるSQLiteベースの永続化ストレージシステムのデータベース設計について記述しています。このストレージシステムは、Visual Studioのワークスペース機能において、ソリューション、プロジェクト、ドキュメントに関連するキャッシュデータを永続化するために使用されます。

## テーブル一覧

| テーブル名 | 対応エンティティ | 説明 |
| --- | --- | --- |
| StringInfo7 | 文字列マスタ | 文字列とそのIDのマッピングを管理するマスタテーブル |
| SolutionData7 | ソリューションデータ | ソリューションレベルのキャッシュデータを格納 |
| ProjectData7 | プロジェクトデータ | プロジェクトレベルのキャッシュデータを格納 |
| DocumentData7 | ドキュメントデータ | ドキュメント（ソースファイル）レベルのキャッシュデータを格納 |

※テーブル名の末尾の「7」はスキーマバージョンを表します。

## 各テーブル定義

### 1. StringInfo7（文字列情報テーブル）

文字列とその一意のIDのマッピングを管理するマスタテーブルです。ファイルパスやプロジェクト名などの文字列を効率的にIDで参照するために使用されます。これにより、同じ文字列を複数箇所で使用する際のストレージの肥大化を防ぎます。

| カラム名 | データ型 | NULL | 説明 |
| --- | --- | --- | --- |
| StringDataId | integer | NOT NULL | 主キー（自動採番）。文字列を一意に識別するID |
| Data | varchar | NOT NULL | 格納される文字列データ（ファイルパス、プロジェクト名等） |

**インデックス:**
- `StringInfo7_Data` - Dataカラムに対するユニークインデックス（重複文字列の登録を防止）

### 2. SolutionData7（ソリューションデータテーブル）

ソリューションレベルのキャッシュデータを格納するテーブルです。ソリューション全体に関連するデータを名前（DataNameId）をキーとして格納します。

| カラム名 | データ型 | NULL | 説明 |
| --- | --- | --- | --- |
| DataNameId | integer | NOT NULL | 主キー。データ名のStringInfo7への参照ID |
| Checksum | blob | NOT NULL | データの整合性検証用チェックサム（16バイト） |
| Data | blob | NOT NULL | 格納されるバイナリデータ |

**主キー構成:**
- DataNameId

### 3. ProjectData7（プロジェクトデータテーブル）

プロジェクトレベルのキャッシュデータを格納するテーブルです。プロジェクトパスとプロジェクト名の組み合わせでプロジェクトを一意に識別します。これにより、異なるターゲットフレームワーク（TFM）のプロジェクトを区別できます。

| カラム名 | データ型 | NULL | 説明 |
| --- | --- | --- | --- |
| ProjectPathId | integer | NOT NULL | プロジェクトファイルパスのStringInfo7への参照ID |
| ProjectNameId | integer | NOT NULL | プロジェクト名のStringInfo7への参照ID |
| DataNameId | integer | NOT NULL | データ名のStringInfo7への参照ID |
| Checksum | blob | NOT NULL | データの整合性検証用チェックサム（16バイト） |
| Data | blob | NOT NULL | 格納されるバイナリデータ |

**主キー構成:**
- ProjectPathId + ProjectNameId + DataNameId（複合主キー）

### 4. DocumentData7（ドキュメントデータテーブル）

ドキュメント（ソースファイル）レベルのキャッシュデータを格納するテーブルです。プロジェクト情報に加えて、ドキュメントのフォルダパスと名前でドキュメントを一意に識別します。

| カラム名 | データ型 | NULL | 説明 |
| --- | --- | --- | --- |
| ProjectPathId | integer | NOT NULL | プロジェクトファイルパスのStringInfo7への参照ID |
| ProjectNameId | integer | NOT NULL | プロジェクト名のStringInfo7への参照ID |
| DocumentFolderId | integer | NOT NULL | ドキュメントのフォルダパスのStringInfo7への参照ID |
| DocumentNameId | integer | NOT NULL | ドキュメント名のStringInfo7への参照ID |
| DataNameId | integer | NOT NULL | データ名のStringInfo7への参照ID |
| Checksum | blob | NOT NULL | データの整合性検証用チェックサム（16バイト） |
| Data | blob | NOT NULL | 格納されるバイナリデータ |

**主キー構成:**
- ProjectPathId + ProjectNameId + DocumentFolderId + DocumentNameId + DataNameId（複合主キー）

## データベース構成

### メインデータベース（main）

ディスク上に永続化されるデータベースです。SQLiteのWAL（Write-Ahead Logging）モードを使用し、書き込みパフォーマンスを最適化しています。

### ライトキャッシュデータベース（writecache）

インメモリデータベースとして動作し、書き込みをバッファリングします。定期的にメインデータベースにフラッシュされ、書き込みパフォーマンスを大幅に向上させています。

- 共有キャッシュモードで動作（複数接続から同じインメモリDBにアクセス可能）
- Visual Studioセッション終了時に自動的に破棄される

## バージョン履歴

| バージョン | 変更内容 |
| --- | --- |
| 1 | SQLiteを永続化レイヤーとして初期導入。単純なkey-valueストレージ |
| 2 | チェックサムの格納を追加。テーブル構造を key->(checksum,value) に変更 |
| 3 | インメモリDBを使用した書き込みキャッシュの導入 |
| 4 | チェックサムをインラインで格納（20バイト）に変更 |
| 5 | 主キーに個別のカラムを使用 |
| 6 | 一部機能で圧縮を使用。異なるblobフォーマットのため新テーブルに移行 |
| 7 | チェックサムサイズを20バイトから16バイトに変更（現行バージョン） |

## 備考

### SQLite設定

- **ジャーナルモード**: WAL（Write-Ahead Logging）
  - ディスク書き込みを削減し、書き込みパフォーマンスを向上
  - チェックポイント時に書き込みを結合

- **同期モード**: normal
  - デフォルトの「full」から変更し、バッファフラッシュのシステムコールを削減
  - WALモードと組み合わせることで、耐久性への影響を最小限に抑えながらパフォーマンスを向上

### スレッドセーフティ

- マルチスレッドモード（SQLITE_OPEN_NOMUTEX）を使用
- 各接続は一度に1つのスレッドからのみ使用可能
- 接続プーリングにより再接続のオーバーヘッドを削減

### データ整合性

- 各データにはチェックサム（16バイト）が格納される
- 読み取り時にチェックサムを検証し、データの破損を検出可能
- トランザクション内でBLOB読み取りを実行し、データの整合性を保証
