SQLiteはアプリやブラウザ、デバイスで使われる単一ファイルの組み込みデータベースです。シンプルさ、信頼性、速度、可搬性が強みであり、同時書き込みが多いケースにだけ限界があります。

SQLiteは小さなデータベースエンジンをライブラリとして提供するもので、アプリに組み込んで使います—サービスを起動して使うものではありません。ネットワーク越しに別のデータベースマシンとやり取りする代わりに、アプリは単一のデータベースファイル(多くの場合 app.db のようなファイル)をディスク上で読み書きします。
「ただのファイル」という考え方が魅力の大部分です。そのデータベースファイルにはテーブル、インデックス、データが入っており、SQLiteはクエリ、制約、そしてACIDトランザクションといった難しい部分を裏で処理します。
クライアントサーバ型データベース(PostgreSQLやMySQLなど)では通常:
SQLiteでは、データベースはアプリケーションプロセスの中で動きます。別のサーバをインストールしたり起動したり、健康状態を保ったりする必要はありません。アプリがSQLiteのAPIを呼び出し、SQLiteがローカルファイルを直接読み書きします。
人々はしばしばSQLiteを「サーバーレス」と表現しますが、それはクラウドの用語とは違い、別個のデータベースサーバプロセスを管理しないという意味です。
SQLiteは配布が容易で信頼性が高いため、多くの日常的なソフトウェアに静かに組み込まれています:
多くのプロダクトは単純さを理由にSQLiteをデフォルトで選びます:高速で安定、しかもゼロコンフィグです。
SQLiteはシングルユーザー向けアプリ、組み込み機器、プロトタイプの本番化、そして書き込みの同時実行が中程度のサービスにとって優れた選択肢です。しかし、複数のマシンが同じデータベースに同時に書き込むようなスケーリング要件には向きません。
重要な点:SQLiteは機能が「小さい」のではなく、運用負荷が「小さい」ことが強みです。だからこそ多くの現場で選ばれ続けています。
SQLiteにはマーケティング的に聞こえる二つの言葉が付きまといますが、ここでは実用的な意味があります:組み込みとサーバーレス。
SQLiteはPostgreSQLやMySQLのようにバックグラウンドで“動かす”ものではありません。ソフトウェアライブラリであり、アプリがリンクして直接利用します。
アプリがデータを読み書きするときは同じプロセス内でSQLite関数を呼び出します。別個のデータベースデーモンを起動/監視/パッチ適用/再起動する必要はありません。アプリとデータベースエンジンが共に存在します。
SQLiteの「サーバーレス」はクラウドベンダーが売る“サーバーレスデータベース”とは違います。
クライアントサーバ型ではコードがTCP経由でSQLを送りますが、SQLiteでは言語バインディング越しにライブラリ呼び出しでSQLを実行し、SQLiteがデータベースファイルを読み書きします。
結果として:ネットワークホップがない、接続プールの調整が不要、そして「DBホストに到達できない」といった失敗モードが減ります。
多くのプロダクトにとって「組み込み+サーバーレス」は可動部が少ないことを意味します:
この単純さが、重厚な選択肢にも関わらずSQLiteが広く使われる大きな理由です。
SQLiteの最も過小評価された利点は最もシンプルです:データベースがアプリと一緒に動くファイルであること。別途サーバーをプロビジョニングしたりポートを開けたり、ユーザーアカウントを作成したりする必要はありません。「データベースは動いているか?」というチェックリストも不要です。
クライアントサーバ型だとアプリを出すときにインフラを出す必要があることが多い:DBインスタンス、マイグレーション、監視、認証情報、スケーリング計画など。しかしSQLiteなら初期の.dbファイルを同梱するか初回起動で作成し、アプリが直接それを読み書きします。
スキーマ変更も簡単です。新しいテーブルやインデックスが必要なら、アプリの更新にマイグレーションを組み込めば、従来の複数段階のロールアウトが単一のリリースにまとまります。
この「ファイルを送る」モデルは環境が制約され分散している場合に有利です:
データベースファイルをコピーするのは一見簡単ですが、アプリが書き込み中のライブファイルを安易にコピーすると危険です。SQLiteのバックアップメカニズムを使うか、一貫したスナップショットを取るようにして、堅牢なストレージに保管してください。
サーバーをチューニングして監視する必要がないため、チームはDB運用の負担をかなり削減できます:サービスパッチ適用、接続プール管理、認証情報のローテーション、レプリカの監視などです。とはいえスキーマ設計やマイグレーションは必要で、データベース固有の作業が完全に不要になるわけではありません。
SQLiteが信頼される理由は利便性だけではありません。多くの人がSQLiteを信用するのは、派手な機能よりデータの正しさを優先して設計されているからです。多くのアプリにとってもっとも重要なのはシンプルです:データを失ったり破損させないこと。
SQLiteはACIDトランザクションをサポートします。簡単に言えば「問題が起きてもデータが一貫した状態に保たれる」ということです。
SQLiteはクラッシュ耐性を達成するためにジャーナル(安全網)を使います。主に聞くモードは:
内部実装を知らなくても恩恵は受けられます:要点はSQLiteが予測可能に復旧するよう設計されていることです。
多くのアプリケーションはクラスタリングや珍しいデータ型を必要としません。求められるのは正確な記録、安全な更新、そしてクラッシュしても静かにデータが壊れないという安心です。SQLiteが「地味で正しい」ことを重視している点は、その採用理由の大きな部分を占めます。
SQLiteはアプリと同じプロセス内で動くため、しばしば「即時」に感じられます。別のデータベースサーバに接続するためのTCPハンドシェイクやネットワーク遅延がなく、クエリはローカルファイルを読む関数呼び出しです(OSのページキャッシュが効くことも多い)。そのため「SQLを実行して結果が返る」までの時間が非常に短くなります。
多くのプロダクトでは、ワークロードが読み中心で書き込みは緩やかです:アプリ状態の読み込み、検索、フィルタリング、ソート、小〜中規模テーブルの結合など。SQLiteはこれらに優れています。効率的なインデックス検索、レンジスキャン、データがローカルストレージに収まる範囲での高速な集約処理が可能です。
中程度の書き込みワークロードにも向いています:ユーザー設定、バックグラウンド同期キュー、キャッシュされたAPIレスポンス、イベントログ、あるいは後でマージするローカルファーストのデータストアなど。
SQLiteのトレードオフは書き込み時の同時実行性です。複数のリーダーはサポートしますが、書き込みは整合性を保つために調整が必要です。多数のスレッドやプロセスが同時に更新しようとするとロック競合が起き、リトライや「database is busy」エラーが発生する可能性があります。アクセスパターンを工夫したり動作を調整する必要があります。
クエリが悪ければSQLiteが自動で速くしてくれるわけではありません。インデックスの活用、選択的なWHERE句、不要な全表スキャンの回避、トランザクションのスコープ管理などは重要です。SQLiteは「本物の」データベースとして扱ってください。
SQLiteの最も特徴的でシンプルな特性は、データベースが単一ファイル(とオプションのサイドカーファイル、例えばWAL)であることです。そのファイルにスキーマ、データ、インデックスがすべて含まれています。
「ただのファイル」なのでポータビリティはデフォルト機能になります。ファイルをコピーしたり、バグレポートに添付したり、適切な範囲でチーム内で共有したり、サーバを立てずに別マシンへ移すことが簡単です。
SQLiteは事実上すべての主要プラットフォームで動きます:Windows、macOS、Linux、iOS、Android、そして多くの組み込み環境。そして後方互換性に保守的なことで有名なので、古いバージョンで作成されたDBファイルでも新しいバージョンで開けることが多いです。
単一ファイルモデルはテストでも強力です。既知のデータセットでユニットテストを実行したければ、小さなSQLiteファイルをチェックインしたりテスト中に生成したりすれば、すべての開発者とCIが同じベースラインから始められます。顧客の問題を再現するにはDBファイルを送ってもらえば、ローカルで問題を再生できます(プライバシー配慮は必要です)。
ポータビリティはメリットであると同時にリスクでもあります:ファイルが削除されたり破損したらデータは失われます。DBファイルは重要なアプリ資産として扱ってください:
SQLiteは多くのプラットフォームに組み込まれ、一般的なランタイムにバンドルされ、環境間での「退屈な」互換性があるため、採用が容易です。
ほとんどのスタックはSQLiteへの定番ルートを持っています:
sqlite3)、Go(mattn/go-sqlite3)、Java(JDBCドライバ)、.NET()、PHP(PDO SQLite)、Node.js(、)この広がりは、慣れたパターン(マイグレーション、クエリビルダ、コネクション管理)が使えることを意味し、カスタムの配管工事をほとんど必要としません。
SQLiteのツールは非常に取り組みやすいです。sqlite3 CLIでテーブルの確認、クエリ実行、データダンプ、CSVインポートが簡単にできます。視覚的に確認したい場合はSQLiteStudioやDB Browser for SQLiteといったGUIツールが非専門家でもデータ検証を助けます。
デリバリ面では主流のマイグレーションツールがSQLiteをサポートすることが多いです:Railsのマイグレーション、Djangoのマイグレーション、Flyway/Liquibase、Alembic、Prisma Migrateなどでスキーマ変更を再現可能にできます。
SQLiteが広く使われているため、問題はよく理解されています:ライブラリは実戦で鍛えられ、エッジケースは文書化され、事例も豊富です。人気があることでサポートが増え、採用障壁がさらに下がります。
ライブラリを選ぶ際は、積極的にメンテナンスされているドライバやORMアダプタを選び、同時実行の挙動やバインディングサポート、マイグレーションの扱いを確認しましょう。良くサポートされた統合は、スムーズな導入と週末に行うトラブルシューティングの差になります。
SQLiteはフルサーバを置くことがコストと複雑さ、故障モードを増やすような場面でよく選ばれます。
多くのモバイルアプリはユーザーセッション、キャッシュされたコンテンツ、メモ、後でアップロードするキューなどの信頼できるローカルストアを必要とします。SQLiteは単一ファイルでACIDトランザクションを持つため、クラッシュや低バッテリー、断続的接続に耐えうる保存が可能です。
オフラインファーストやローカルファーストなアプリでは特に優れています:まずローカルにすべて書き込み、ネットがあるときにバックグラウンドで同期する。これによりオフラインだけでなく、UIが速く、読み書きがデバイス上で完結する分だけ挙動が予測しやすくなります。
デスクトップソフトはユーザーに設定をさせずにDBを持ちたいことが多いです。単一のSQLiteファイルを配布するか初回起動で作成することでインストールは簡単になり、バックアップも「ファイルをコピーする」だけで分かりやすくなります。
会計ツール、メディア管理ツール、小規模なCRMのようなアプリは、データをアプリに近く置くことで性能が上がり、「データベースサーバが動いているか?」という問題を回避できます。
開発者ツールや履歴、インデックス、メタデータのために構造化ストレージが必要な場面でSQLiteが使われます。安定していること、移植性があること、別プロセスを必要としないことが好まれる理由です。
ルーター、キオスク、POS端末、IoTゲートウェイは設定やログ、小さなデータセットをローカルに保存することが多く、SQLiteの小さなフットプリントとファイルベースの可搬性は実際的なメリットになります。
開発者は素早いプロトタイプ作成、ローカル開発用DB、テスト用フィクスチャとしてSQLiteを使います。ゼロセットアップでリセットが容易、決定論的であることは反復速度を上げ、CIの信頼性を高めます。
これはKoder.aiのような環境でも典型的です:チームはローカル反復を速めるためにSQLiteで始め、必要になったら生成されたソースをエクスポートしてPostgreSQLへ移行します。「シンプルから始めて必要なら移行する」ワークフローは早期の納品を妨げません。
SQLiteはローカルストレージの優れたデフォルトですが万能ではありません。重要なのはワークロードと運用要件で判断することです。
SQLiteは複数のリーダーを扱えますが、書き込みは制約されます。多くのユーザーやプロセスが同時にデータを更新するような状況では、クライアントサーバ型データベース(PostgreSQLやMySQLなど)が適していることが多いです。
よくある兆候は「ノートPCでは全て問題ないが、実際の利用ではタイムアウトやロック競合、書き込み待ちが発生する」ケースです。
SQLiteは速くなり得ますが、想定するワークロードの形が違います:多くの読み取りと中程度の書き込みです。高頻度のインサート/アップデート(メトリクス収集、イベントストリーム、ジョブキュー、高ボリュームのログ)で多数の並列ライターを期待するなら、サーバDBの方が予測可能にスケールします。
これは単に「速さ」の問題だけではありません。遅延の一貫性の問題でもあります:書き込みのバーストが他のライターや時にはリーダーをブロックし、説明のつかないテールレイテンシを生むことがあります。
中央で共有されるネットワーク越しのDB、ロールベースの権限管理、監査ログ、中央バックアップ、ポイントインタイム復旧といったガバナンスが必要ならSQLiteは適しません。ネットワーク共有にDBファイルを置くことも可能ですが、信頼性やロッキングの問題を招きやすいです。
サーバ型DBが優れる場面:
2つの質問を自分に投げかけてください:
もし答えが「多くのライター」と「中央管理が必要」であれば、クライアントサーバDBを選ぶ方が安全で簡単な場合が多いです。
SQLiteとPostgreSQLやMySQLのようなDBは両方ともテーブルを持ちSQLを実行できますが、設計思想が異なります。
**SQLiteはアプリケーションプロセス内で動き、ローカルファイルを直接読み書きします。**一方で、**クライアントサーバDBは別サービスとして動きます。**アプリはネットワーク(たとえローカルホストでも)経由で接続してクエリを送り、サーバがストレージ、同時実行、ユーザー管理、バックグラウンド作業を担当します。
この違いが実務上のトレードオフを大半説明します。
SQLiteならデプロイはバイナリとファイルを配るだけで済むことが多い。ポートも認証情報も不要、サーバのアップグレードも不要—デスクトップやモバイル、エッジ、ローカルファースト製品には大きな利点です。
クライアントサーバDBは多数のアプリやユーザーが同じDBを叩く場合に中央管理が強みになります:細かなアクセス制御、オンラインバックアップ、リードレプリカ、成熟した可観測性などです。
SQLiteは次のようにスケールします:
一方、クライアントサーバDBは共有ワークロードに対して大きなマシン、レプリケーション、パーティショニング、プーリングでスケールしやすいです。
SQLiteを選ぶべきか:ローカルデータ、最小限の運用、単一アプリが主に書き込むような要件であればSQLite。
クライアントサーバDBを選ぶべきか:多数の同時書き込み、複数サービスからのネットワークアクセス、中央管理や高可用性が必要ならサーバDB。
迷うなら、まずSQLiteで早く届け、PostgreSQLなどへ移行できる明確なパス(スキーマ、マイグレーション、エクスポート/インポート)を用意しておくと良いです(参考:/blog/migrating-from-sqlite)。
SQLiteは本番運用に耐えられますが、「一時的なファイル」として扱わず本物のデータベースとして設計してください。以下の習慣がスムーズな運用と障害回避の差になります。
SQLiteは複数のリーダーと通常は1つのライターを前提とします。これが多くのアプリで問題にならないのは、設計次第です。
書き込みトランザクションは短くシンプルに:まずアプリ内で作業を終わらせてからトランザクションを開き、書き込み・コミットを素早く行ってください。ネットワーク待ちやユーザー入力、遅いループ中にロックを保持する長いトランザクションは避けましょう。バックグラウンドジョブは書き込みをキュー化してインタラクティブなリクエストをブロックしないようにします。
WALモードはSQLiteが変更をどう記録するかを変え、読み取りはライター中も継続できることが多くなります。読みが多く書き込みが時折あるようなアプリでは、WALは“データベースがロックされている”摩擦を減らしスループットを改善する実用的な選択です。
WALは万能ではありません:やはり同時ライターは1つであり、ディスク上にWALファイルが増える点は考慮が必要です。ただし多くの本番環境でのデフォルト候補になっています。
SQLiteは単一ファイルだからといってバックアップが不要になるわけではありません。負荷下でのランダムなコピーに頼らず、一貫性の取れた方法でスナップショット/バックアップを行ってください。
スキーマ変更はマイグレーションで管理し、バージョン管理・自動実行・ロールフォワード/ロールバックのテストを実施しましょう。
本番で起きる多くの「驚き」はデータサイズや同時実行が増えたときに現れます。ステージングと自動テストで同じスキーマ、インデックス、重要設定(ジャーナルモードなど)を使い、現実的なボリュームとアクセスパターンで負荷試験を行ってから本番へ投入してください。
SQLiteが広く使われるのは、データ保存をライブラリを使う感覚に近づけるからです。プロビジョニング不要のSQLエンジン、ACIDトランザクション、成熟したツール群が得られ、データベースサーバの立ち上げやユーザー管理、ネットワーク接続の監視といった運用作業が不要になります。
ベストな場面でのSQLiteは「ただ動く」選択肢です:
SQLiteは高い書き込み同時実行やネットワーク越しの集中共有データベース向けではありません。複数のリーダーは問題ありませんが、多数の並列書き込みや多拠点での単一ファイルの共有はクライアントサーバ型DBの方が安全です。
まずワークロードを記述してください—それから最もシンプルな道具を選びます。アプリが主にローカル、シングルユーザー、または「ローカルファースト」であるならSQLiteは強力なデフォルトです。多人数の同時書き込みが必要ならPostgreSQLなどのサーバDBを検討してください。
最初の4つに「はい」、最後に「いいえ」で答えられるなら、SQLiteは非常に適した選択です。
SQLiteは組み込みデータベースエンジンです:アプリケーションプロセス内で動作するライブラリとして使います。アプリは1つのデータベースファイル(例:app.db)を直接読み書きし、別途インストールするDBサービスは不要です。
SQLiteにおける「サーバーレス」は別プロセスのデータベースサーバが存在しないことを意味します。クラウドの“サーバーレス”と違い「サーバーがない」ので、アプリがプロセス内でSQLiteのAPIを呼び出し、ローカルファイルへの読み書きを行います。
通常、何かをプロビジョニングする必要はありません:初回起動で.dbファイルを同梱するか作成し、アプリの更新時にマイグレーションを実行すれば動きます。これにより複数手順のインフラ展開が単一のリリースアーティファクトに変わることが多いです。
はい。SQLiteはACIDトランザクションをサポートしており、クラッシュや電源断時の部分書き込みやデータ破損を防ぎます。
SQLiteは中断から安全に復旧するためにジャーナルを使います。
多くの本番環境ではWALが“database is locked”問題の摩擦を減らすための実用的な選択です。
理由は単純です:SQLiteはプロセス内で動くため、クエリは関数呼び出しでネットワーク往復が発生しません。ローカルディスクとOSのページキャッシュの恩恵もあり、読み中心のワークロードでは非常に速く感じられます。特にデスクトップ、モバイル、ローカルファーストなアプリで顕著です。
SQLiteは複数の読み取りを許容しますが、書き込みはファイル整合性を保つために調整が必要です。多くの並列書き込みが発生する状況では、ロック競合や database is busy / database is locked エラーが出ることがあります。書き込みを直列化し、短いトランザクションにする設計が重要です。
多くのマシン/サービスが同じ共有データベースに書き込みを行う必要がある場合や、中央集権的なポリシーが必要な場合はSQLiteは適しません。
代わりにクライアントサーバ型DB(PostgreSQL/MySQLなど)を選ぶべき状況:
SQLiteのDBファイルは重要なアプリデータとして扱ってください。
ローカル・シングルユーザー・ライトが軽い状況でまずSQLiteを使い、明らかに書き込み並列性で限界に達したらサーバDBへ移行するのが実務的です。
現実的なヒント:
写経的には、書き込み並列性が問題になったらPostgreSQL等に移行します(参考:/blog/migrating-from-sqlite)。
Microsoft.Data.Sqlitebetter-sqlite3sqlite3