SQLiteとは何か — サーバー不要のデータベースの仕組みと使いどころ
この章の目次開く
SQLiteは、アプリケーションに組み込んで使うリレーショナルデータベースです。 MySQLやPostgreSQLのようにデータベースサーバーを起動する必要がなく、1つのファイルがそのままデータベースになります。
「簡易版のデータベース」と紹介されることが多いのですが、実際には世界でもっとも多くデプロイされているデータベースです。スマートフォンのアプリ、Webブラウザ、OS、家電、車載機器のほとんどがSQLiteを内蔵しています。
学習者サーバーがいらないって、どういうことですか? データベースって、起動してポート番号を指定して接続するものだと思っていました。
先生それはMySQLやPostgreSQLのような「クライアント/サーバー型」の話だね。SQLiteはライブラリとしてアプリの中に入っていて、ファイルを直接読み書きするんだ。
サーバーがない、とはどういうことか
MySQLやPostgreSQLでは、データベースサーバーというプロセスが常に動いています。アプリケーションはネットワーク経由でそのサーバーに接続し、SQLを送り、結果を受け取ります。
SQLiteにはこのサーバープロセスがありません。SQLiteはライブラリであり、アプリケーションのプロセスの中で動きます。SQLを実行すると、そのプロセス自身がデータベースファイルを直接読み書きします。
SQLiteに「接続する」とは、実際には「ファイルを開く」ことです。この違いが、SQLiteのメリットとデメリットのほぼすべての原因になっています。
| 観点 | クライアント/サーバー型 | SQLite |
|---|---|---|
| 起動 | サーバープロセスの起動が必要 | 不要(ライブラリを読み込むだけ) |
| 接続 | ホスト・ポート・認証情報 | ファイルパス |
| ネットワーク越しの利用 | できる | できない |
| ユーザーごとの権限管理 | ある | ない(OSのファイル権限で代替) |
| 運用作業 | バックアップ・監視・アップデート | ファイルをコピーするだけ |
| 同時書き込み | 複数同時に処理できる | 一度に1つ |
データベース = 1つのファイル
SQLiteのデータベースは、テーブルもインデックスもビューもトリガーも、すべて1つのファイルに入っています。
ls -lh
# -rw-r--r-- 1 user staff 32K mydb.dbこのファイルをコピーすれば、それがそのままバックアップです。別のマシンに持っていっても、OSやCPUのアーキテクチャが違っても、同じように読めます。
ファイルパスの代わりに :memory: を指定すると、ディスクを使わずメモリ上だけにデータベースを作れます。プロセスが終了すると消えるため、テストで重宝します。

SQLiteが得意なこと
サーバーがないという特性は、次のような場面で強く効きます。
| 用途 | なぜ向いているか |
|---|---|
| テスト用のDB | プロセスごとに使い捨てできる。:memory: なら後片付けも不要 |
| CLIツール・デスクトップアプリ | ユーザーにDBサーバーのインストールを要求しなくてよい |
| 読み取りが中心のWebアプリ | 読み取りはプロセス内で完結するため非常に速い |
| 設定・キャッシュの保存 | JSONファイルを自前でパースするよりSQLで扱える |
| 組み込み機器・モバイルアプリ | メモリと依存が小さい |
| local-firstなアプリ | 手元にデータの実体があり、オフラインでも動く |
Web開発の文脈では、「PostgreSQLを1台立てるほどではないが、JSONファイルで管理するのは限界」という領域がSQLiteの主戦場です。
SQLiteが苦手なこと
一方で、次のような要件には向きません。理由を理解しておくと、採用の判断が早くなります。
書き込みが同時多発するワークロード SQLiteは、同時に書き込めるプロセスが常に1つだけです。読み取りは並行できますが、書き込みは順番待ちになります。多数のユーザーが同時に投稿するようなサービスでは詰まります。
ネットワーク越しのアクセス SQLiteはファイルを直接読み書きするため、NFSやSMBのようなネットワークファイルシステム上に置くと、ロックが正しく働かずデータが壊れる危険があります。「1台のサーバーの中で完結する」構成が前提です。
ユーザーごとのアクセス制御
GRANT / REVOKE にあたる仕組みがありません。ファイルを読めるプロセスは、そのデータベースの全データを読めます。
学習者書き込みが1つずつってことは、やっぱり本番では使えないってことですか?
書き込みが「遅い」わけではありません。1回の書き込み自体はむしろ高速で、詰まるのは同時に書き込もうとしたときだけです。1秒あたり数件〜数十件の書き込みであれば問題にならないケースは多く、読み取りが9割を占めるブログ・ドキュメントサイト・社内ツールなどでは十分実用になります。
判断の軸は「アクセス数」ではなく「書き込みの同時実行数」です。ここは トランザクションとWALモード で詳しく扱います。
MySQL・PostgreSQLとの違いを整理する
SQLの文法そのものは、標準SQLをベースにしているためほとんど共通です。SELECT や JOIN の書き方は SQLとデータベースの基礎 で学んだ内容がそのまま使えます。
違いが出るのは、SQLの周辺です。
| 項目 | SQLite | MySQL / PostgreSQL |
|---|---|---|
| 型の扱い | 緩い(列に宣言と違う型も入る) | 厳密 |
| 真偽値型 | 専用の型がない(0/1で表現) | BOOLEAN がある |
| 日付時刻型 | 専用の型がない(TEXT/INTEGERで表現) | DATE / TIMESTAMP がある |
| 外部キー制約 | デフォルトで無効 | デフォルトで有効 |
| 同時書き込み | 1つ | 複数 |
| ストアドプロシージャ | ない | ある |
この2つはそれぞれ SQLiteの型は緩い と テーブル作成とrowid で扱います。
よくあるハマりどころ
「軽量だから機能が少ない」と思い込む
SQLiteは軽量ですが、機能が乏しいわけではありません。トランザクション、外部キー、ウィンドウ関数、CTE(WITH 句)、JSON関数、全文検索、部分インデックス、生成列など、モダンなSQLの機能を一通り備えています。
先生ウィンドウ関数もCTEも使えるよ。「機能が足りなくて困る」より、「型が緩くて事故る」ほうが圧倒的に多いんだ。
バージョンが古いまま使っている
SQLiteはOSやプログラミング言語のランタイムに同梱されていることが多く、手元のSQLiteが数年前のバージョンのままというケースがよくあります。STRICT テーブルや RETURNING のように後から追加された機能は、古いバージョンでは使えません。
SELECT sqlite_version();まずこれを実行して、自分が使っているバージョンを把握しておきましょう。
「開発はSQLite、本番はPostgreSQL」で揃えてしまう
手軽さから開発環境だけSQLiteにする構成は一見便利ですが、型の扱いや関数の挙動が違うため、SQLiteでは通ったSQLが本番で落ちることがあります。この構成を取る場合は、CIでは本番と同じDBMSに対してもテストを流すのが安全です。
ちゃんと使うためのポイント
- SQLiteはサーバープロセスを持たない「組み込み型」のデータベース
- データベースの実体は1つのファイルで、コピーがそのままバックアップになる
- 読み取りは並行できるが、書き込みは一度に1つだけ
- ネットワークファイルシステム上に置くとデータが壊れる危険がある
- SQLの文法は標準SQLとほぼ共通。違いは型の緩さと外部キーの既定値に集中している
SELECT sqlite_version();で手元のバージョンを最初に確認する
次の章では、SQLiteに付属する sqlite3 コマンドを使って、実際にデータベースを作り、テーブルを確認し、CSVを取り込むところまでを試します。