Microsoft.Data.Sqlite
type: Concept
definition: MicrosoftがメンテナンスするSQLite向けの軽量ADO.NETプロバイダーで、ネイティブのSQLite本体もNuGetパッケージに同梱される。
recommended for: 新規開発でのSQLiteライブラリ採用
mitigates: SQLITE_BUSY(database is locked)
not recommended for: SQLiteデータベース全体の暗号化要件

WALモード(Write-Ahead Logging)
type: Concept
definition: 変更をデータベース本体ではなく隣接する-walファイルへ追記していき、読み取りと書き込みを同時に進められるようにするSQLiteのジャーナリングモード。
alternative label: journal_mode=WAL
mitigates: SQLITE_BUSY(database is locked)
incompatible with: 稼働中DBファイルの単純ファイルコピー

System.Data.SQLite
type: Concept
definition: SQLite開発チーム系列の老舗ADO.NETプロバイダーで、接続文字列や型の扱いがMicrosoft.Data.Sqliteとは互換性のない別物。

Microsoft.EntityFrameworkCore.Sqlite
type: Concept
definition: 内部でMicrosoft.Data.Sqliteを使う、EF Core向けのSQLiteデータプロバイダー。
alternative label: EF Core SQLiteプロバイダー
broader: Microsoft.Data.Sqlite
uses: Microsoft.Data.Sqlite

新規開発でのSQLiteライブラリ採用
type: Concept
definition: これから作るアプリでC#からSQLiteを扱うためのADO.NETプロバイダーを新規に選定・採用すること。

SQLITE_BUSY(database is locked)
type: Concept
definition: 他の接続が書き込みロックを持っているときにSQLiteが返すエラーで、Microsoft.Data.Sqliteはコマンドタイムアウトまで自動リトライする。
alternative label: database is locked

書き込み経路の一本化(Channelsによる書き込みキュー)
type: Concept
definition: 複数スレッドが直接DBに書かず、System.Threading.Channelsのキューに投げて専任の書き込みループだけがコミットする設計。
alternative label: System.Threading.Channels書き込みキュー
mitigates: SQLITE_BUSY(database is locked)
uses: 明示的トランザクションによるINSERTのバッチ化

明示的トランザクションによるINSERTのバッチ化
type: Concept
definition: 複数件のINSERTをBeginTransactionで囲みまとめてCommitすることで、コミットごとのfsyncコストを削減する手法。
mitigates: コミットごとの同期書き込み(fsync)コスト

コミットごとの同期書き込み(fsync)コスト
type: Concept
definition: SQLiteがコミットのたびに行うストレージへの同期書き込みにかかるコストで、1件ずつ暗黙コミットするとSSDでも毎秒数百〜数千件で頭打ちになる。

稼働中DBファイルの単純ファイルコピー
type: Concept
definition: SQLiteのDBファイルが稼働中のまま、OSのファイルコピー機能でそのまま複製するバックアップ方法。
may cause: SQLiteデータベースの破損
not recommended for: 稼働中SQLiteデータベースの一貫したバックアップ要件

SQLCipher
type: Concept
definition: SQLiteデータベースファイル全体を透過的に暗号化する、標準のSQLiteネイティブライブラリを置き換える形の拡張。
alternative label: SQLitePCLRaw.bundle_e_sqlcipher
recommended for: SQLiteデータベース全体の暗号化要件

DPAPI
type: Concept
definition: 実行中のマシン上でアプリの秘密情報を保護するWindowsのデータ保護API。
alternative label: データ保護API
recommended for: アプリの秘密情報

Microsoft.Data.Sqliteの接続プーリング
type: Concept
definition: バージョン6.0以降Microsoft.Data.Sqliteで既定有効になっている、接続のOpen/Closeを高速化する仕組み。
broader: Microsoft.Data.Sqlite
may cause: プーリングによるDBファイルハンドルの保持

プーリングによるDBファイルハンドルの保持
type: Concept
definition: 接続をClose/Disposeしてもネイティブの接続がプールに残り、DBファイルのハンドルを掴み続けたままになる状態。
broader: Microsoft.Data.Sqliteの接続プーリング

SqliteConnection.ClearPool
type: Concept
definition: 指定した接続文字列に対応する接続プールを破棄し、DBファイルのハンドルを解放するMicrosoft.Data.SqliteのAPI。
alternative label: ClearAllPools
broader: Microsoft.Data.Sqliteの接続プーリング
prevents: プーリングによるDBファイルハンドルの保持

SQLiteデータベースの破損
type: Concept
definition: ディスク障害や不適切なファイル操作によってSQLiteのファイル構造が壊れ、正しく読み書きできなくなる状態。
verified by: PRAGMA quick_check

VACUUM INTO
type: Concept
definition: 元のファイルを変更せず、断片化を解消した一貫性のある最小サイズのコピーを別ファイルへ作成できるSQLiteのSQL文。
recommended for: 稼働中SQLiteデータベースの一貫したバックアップ要件

稼働中SQLiteデータベースの一貫したバックアップ要件
type: Concept
definition: 稼働中のSQLiteデータベースを、トランザクション途中の状態を混ぜずに一貫性のある形で複製したいという要件。

SqliteConnection.BackupDatabase
type: Concept
definition: SQLiteのBackup APIをラップした、稼働中でも接続オブジェクト間で一貫したスナップショットを作成できるMicrosoft.Data.SqliteのAPI。
alternative label: Backup API
broader: Microsoft.Data.Sqlite
recommended for: 稼働中SQLiteデータベースの一貫したバックアップ要件
may cause: BackupDatabase完了までの書き込みブロック

BackupDatabase完了までの書き込みブロック
type: Concept
definition: Microsoft.Data.SqliteのBackupDatabaseが可能な限り速くコピーする代わりに、完了するまで他の接続からの書き込みをブロックする現在の実装挙動。
broader: SqliteConnection.BackupDatabase

PRAGMA quick_check
type: Concept
definition: 完全なintegrity_checkより軽量に、SQLiteデータベースの整合性を検証できるPRAGMA文。

SQLiteデータベース全体の暗号化要件
type: Concept
definition: SQLiteのデータベースファイル全体を暗号化して保存したいという要件。

アプリの秘密情報
type: Concept
definition: 業務アプリが扱う接続文字列・APIキーなどの秘密情報。ログオン済みマシンではドライブ暗号化では守れない。
alternative label: 接続文字列
alternative label: APIキー

SQLiteの型マッピング(INTEGER/REAL/TEXT/BLOB)
type: Concept
definition: SQLiteが実際に保存できるINTEGER/REAL/TEXT/BLOBの4つの型に、.NETの型を割り当てるMicrosoft.Data.Sqliteの対応規則。

decimal列のTEXT保存による比較・集計の不整合
type: Concept
definition: decimalがTEXTとして保存されるため、SQLiteの型序列上TEXTが常に数値より大きく扱われ、WHERE比較やSUM等の集計が意図どおりに動かなくなる問題。
broader: SQLiteの型マッピング(INTEGER/REAL/TEXT/BLOB)

金額を最小通貨単位の整数で持つ設計
type: Concept
definition: 金額をdecimalではなく、円などの最小通貨単位に換算したINTEGER(long)で保存する設計方針。
prevents: decimal列のTEXT保存による比較・集計の不整合

subject: Microsoft.Data.Sqlite
predicate: incompatibleWith
object: System.Data.SQLite
description: 接続文字列のキーワードも型の既定の扱い(例: Guidの保存形式)も異なる別物で、互換性がない。
evidence: connection-strings
verified at: 2026-08-01
certainty: context-dependent

subject: Microsoft.EntityFrameworkCore.Sqlite
predicate: uses
object: Microsoft.Data.Sqlite
description: EF CoreのSQLiteプロバイダーは、内部でMicrosoft.Data.Sqliteを使う。
evidence: limitations
verified at: 2026-08-01
certainty: established

subject: Microsoft.Data.Sqlite
predicate: recommendedFor
object: 新規開発でのSQLiteライブラリ採用
description: 新規開発で使うライブラリは、EF Coreチームがメンテナンスする軽量なMicrosoft.Data.Sqliteが基本とされる。
evidence: sqlite
verified at: 2026-08-01
certainty: established

subject: System.Data.SQLite
predicate: notRecommendedFor
object: 新規開発でのSQLiteライブラリ採用
description: 既存アプリが安定稼働しているなら無理に移行する必要はないが、新規のコードはMicrosoft.Data.Sqliteに寄せるのが原則とされる。
evidence: connection-strings
verified at: 2026-08-01
certainty: context-dependent

subject: WALモード(Write-Ahead Logging)
predicate: mitigates
object: SQLITE_BUSY(database is locked)
description: WALモードでは読み取りと書き込みの並行性が上がり、database is lockedの大半が消える。ただし書き込み同士は依然として排他のため、SQLITE_BUSYが完全に無くなるわけではない。
evidence: wal.html
verified at: 2026-08-01
certainty: established

subject: Microsoft.Data.Sqlite
predicate: mitigates
object: SQLITE_BUSY(database is locked)
description: Microsoft.Data.Sqliteはbusy/lockedエラーに対して、コマンドタイムアウト(既定30秒)まで自動でリトライする。
evidence: database-errors
verified at: 2026-08-01
certainty: established

subject: 書き込み経路の一本化(Channelsによる書き込みキュー)
predicate: mitigates
object: SQLITE_BUSY(database is locked)
description: 書き込み経路を1本のキューに寄せると、複数スレッドによる書き込みの衝突が構造的に起きなくなる。ただし他の接続が握る長いトランザクションや読み取りから書き込みへの昇格の衝突など、他の原因によるSQLITE_BUSYは残り得る。
evidence: database-errors
verified at: 2026-08-01
certainty: established

subject: 明示的トランザクションによるINSERTのバッチ化
predicate: mitigates
object: コミットごとの同期書き込み(fsync)コスト
description: 1,000件単位の明示的トランザクションにまとめるだけで、コミットごとのfsyncコストが減り毎秒数万〜数十万件のオーダーに届く。
evidence: wal.html
verified at: 2026-08-01
certainty: established

subject: 書き込み経路の一本化(Channelsによる書き込みキュー)
predicate: uses
object: 明示的トランザクションによるINSERTのバッチ化
description: 書き込みキューはチャネルに溜まった分を最大500件までまとめて1トランザクションで書くため、経路の一本化とバッチ化を同時に実現する。
evidence: wal.html
verified at: 2026-08-01
certainty: established

subject: WALモード(Write-Ahead Logging)
predicate: incompatibleWith
object: 稼働中DBファイルの単純ファイルコピー
description: WALモードでは変更が-walファイルに追記されるため、本体(.db)だけを単純コピーすると本体未反映の直近のコミットが抜け落ちる。
evidence: wal.html
verified at: 2026-08-01
certainty: established

subject: SQLCipher
predicate: requires
object: DPAPI
description: SQLCipher系バンドルでDB全体を暗号化する場合、その暗号化キー自体の保管には何らかの保護手段が必要になる。DPAPIはWindows環境で選ばれることが多い一例であり、鍵保護の唯一の手段ではない。
evidence: system.security.cryptography.protecteddata
verified at: 2026-08-01
certainty: context-dependent

subject: Microsoft.Data.Sqlite
predicate: uses
object: Microsoft.Data.Sqliteの接続プーリング
description: Pooling=Falseを指定しない既定構成では、Microsoft.Data.Sqliteはバージョン6.0から接続プーリングが既定で有効になっている。
evidence: connection-strings
verified at: 2026-08-01
certainty: context-dependent

subject: Microsoft.Data.Sqliteの接続プーリング
predicate: mayCause
object: プーリングによるDBファイルハンドルの保持
description: 接続をClose/Disposeしてもネイティブの接続がプールに残り、DBファイルのハンドルを掴み続けることがある。
evidence: connection-strings
verified at: 2026-08-01
certainty: established

subject: SqliteConnection.ClearPool
predicate: prevents
object: プーリングによるDBファイルハンドルの保持
description: ファイル操作の直前に対応する接続プールを空にすることで、DBファイルのハンドル保持を解消できる。
evidence: connection-strings
verified at: 2026-08-01
certainty: established

subject: 稼働中DBファイルの単純ファイルコピー
predicate: mayCause
object: SQLiteデータベースの破損
description: 稼働中(トランザクション中)のDBファイルコピーは、SQLite公式が破損原因として明記している。
evidence: howtocorrupt.html
verified at: 2026-08-01
certainty: established

subject: VACUUM INTO
predicate: recommendedFor
object: 稼働中SQLiteデータベースの一貫したバックアップ要件
description: VACUUM INTOはSQL1文で、断片化を解消した一貫性のある最小サイズのコピーを稼働中でも作成できる。
evidence: lang vacuum.html
verified at: 2026-08-01
certainty: established

subject: SqliteConnection.BackupDatabase
predicate: recommendedFor
object: 稼働中SQLiteデータベースの一貫したバックアップ要件
description: BackupDatabaseは接続オブジェクト間で稼働中でも一貫したスナップショットを作成できるが、完了まで他の接続の書き込みをブロックする点に注意が必要。
evidence: backup
verified at: 2026-08-01
certainty: established

subject: 稼働中DBファイルの単純ファイルコピー
predicate: notRecommendedFor
object: 稼働中SQLiteデータベースの一貫したバックアップ要件
description: 稼働中の単純ファイルコピーは、一貫したバックアップの手段としては禁止される。
evidence: howtocorrupt.html
verified at: 2026-08-01
certainty: established

subject: SqliteConnection.BackupDatabase
predicate: mayCause
object: BackupDatabase完了までの書き込みブロック
description: 現在の実装は可能な限り速くコピーする代わりに、完了まで他の接続からの書き込みをブロックする。
evidence: backup
verified at: 2026-08-01
certainty: established

subject: SQLiteデータベースの破損
predicate: verifiedBy
object: PRAGMA quick_check
description: 起動時にPRAGMA quick_checkを実行することで、SQLiteデータベースが破損していないかを確認できる。
evidence: lang vacuum.html
verified at: 2026-08-01
certainty: established

subject: SQLCipher
predicate: recommendedFor
object: SQLiteデータベース全体の暗号化要件
description: DB全体の暗号化が要件なら、SQLCipher系のネイティブライブラリへの差し替えが必要になる。
evidence: sqlcipher
verified at: 2026-08-01
certainty: established

subject: Microsoft.Data.Sqlite
predicate: notRecommendedFor
object: SQLiteデータベース全体の暗号化要件
description: 接続文字列のPasswordを指定しても、標準のネイティブライブラリは暗号化に対応していないため何も起きない。
evidence: connection-strings
verified at: 2026-08-01
certainty: established

subject: DPAPI
predicate: recommendedFor
object: アプリの秘密情報
description: 少量の機密情報なら、DB全体の暗号化より先にWindowsのDPAPIによる保護を検討することが推奨される。
evidence: system.security.cryptography.protecteddata
verified at: 2026-08-01
certainty: established

subject: SQLiteの型マッピング(INTEGER/REAL/TEXT/BLOB)
predicate: mayCause
object: decimal列のTEXT保存による比較・集計の不整合
description: decimalはREALでは精度が欠損するためTEXTとして保存され、TEXT列に対する比較・集計が文字列規則になり意図どおりに動かないことがある。
evidence: types
verified at: 2026-08-01
certainty: context-dependent

subject: 金額を最小通貨単位の整数で持つ設計
predicate: prevents
object: decimal列のTEXT保存による比較・集計の不整合
description: 金額を最小通貨単位の整数(INTEGER)で持てば、比較も集計も正確かつ高速になり型の罠が消える。
evidence: types
verified at: 2026-08-01
certainty: established

subject: Microsoft.EntityFrameworkCore.Sqlite
predicate: uses
object: WALモード(Write-Ahead Logging)
description: journal_modeを明示的に変更しない既定構成では、EF Coreが作成するSQLiteデータベースは最初からWALモードが既定で有効になっている。
evidence: async
verified at: 2026-08-01
certainty: context-dependent

subject: Microsoft.EntityFrameworkCore.Sqlite
predicate: mayCause
object: decimal列のTEXT保存による比較・集計の不整合
description: EF Coreを使っても型の事情は消えず、decimal等の等値以外の比較や並び替えはクライアント評価になる。
evidence: limitations
verified at: 2026-08-01
certainty: context-dependent