概要
SQLite は多くの組み込みプロジェクトやサーバーソフトウェアで利用される、非常に優れた ローカルデータベースエンジン。 しかし、 デフォルト設定 には大きな問題点が存在し、データ整合性やパフォーマンス、型安全性に悪影響を及ぼす。 主な問題点は、 外部キー制約の無効化、 型の緩さ、 同時書き込み時のエラー、 パフォーマンス設定の不備。 それぞれの問題点と、その 対策方法 を具体的に解説。 今後の改善策として「 エディション制」の導入も提案。
SQLiteの優位性と特徴
- SQLite は、 自己完結型 のライブラリとして動作するRDBMS
- 組み込み用途 や一部サーバー用途(例:lobste.rs)で業界標準
- プロセス分離不要、ソフトウェア単体でデータベース機能を実現
- シリアライザーやパーサー不要、ファイルフォーマットとRDBMSの利点を両立
- 手軽さと柔軟性 が魅力
悪いデフォルト設定 #1:外部キー制約が無効
- 外部キー制約 はデータベースの 整合性維持 に不可欠
- 例:posts.user_idがusers.idを参照
- SQLiteはデフォルトで外部キー制約を無視
- ROWID再利用 により、誤った参照が発生しやすい
- 例:削除→再挿入でIDが再利用され、データが誤って紐付く
- 解決策 :
PRAGMA foreign_keys = ON;で明示的に有効化 - 他のRDBMS では標準で有効なため、SQLiteの仕様は特異
悪いデフォルト設定 #2:カラム型の緩さ
- SQLiteの型システム は「型アフィニティ」に基づく
- INTEGERカラム でも 文字列やBLOB が格納可能
- 例:duration_secに「Way too long, I mean come on」も格納可
- 型エラーが発生しない ため、バグの温床
- strictテーブル を使えば型エラーを強制できる
- 例:
CREATE TABLE ... strict;
- 例:
- strict指定はテーブルごと で、全体適用は不可
- 柔軟な型名利用 や 独自型エイリアス の文化も存在
- SQL標準の
CREATE DOMAIN(型エイリアス+制約)未対応
- SQL標準の
悪いデフォルト設定 #3:同時書き込み時のSQLITE_BUSYエラー
- SQLiteは同時リーダー可、同時ライター不可
- 書き込み競合時、即座に
SQLITE_BUSYエラー発生 - 期待される挙動 :ロック解除まで一定時間待機
- 解決策 :
PRAGMA busy_timeout = 5000;でタイムアウト設定 - 現状のデフォルト では、管理作業やCLI操作時にクラッシュの危険
悪いデフォルト設定 #4:パフォーマンス
- SQLiteのパフォーマンス は設定次第で大きく向上
- Write-Ahead Log(WAL) がデフォルトで無効
- 有効化:
PRAGMA journal_mode = WAL;
- 有効化:
- WAL有効化 で書き込み速度が大幅向上
- 同期設定 も
PRAGMA synchronous = NORMAL;で最適化可能 - 適切なチューニング でPostgreSQLやMySQL並みの性能も実現可能
デフォルト問題の根本要因と今後の提案
- 後方互換性 維持のため、現状のデフォルトが継続
- 既存ソフトの壊滅的影響を回避
- エディション制導入 の提案
- 新規プロジェクト向けに「推奨設定エディション」を作成
- 既存プロジェクトは従来設定のまま利用可
- SQL標準準拠の型エイリアス(CREATE DOMAIN) や カスタム制約 の実装も期待
まとめ
- SQLite は非常に優れた ローカルデータベース だが、 デフォルト設定 には注意が必要
- 外部キー制約・型安全・同時書き込み・パフォーマンス の各項目で 明示的な設定 が推奨
- 今後の発展 には、 エディション制 や SQL標準準拠 への対応が鍵