SQLiteファイルの解説:構造、ユースケース、および主な制限

SQLiteファイルは、テーブル、インデックス、スキーマをすべてまとめた、リレーショナルデータベース全体を保持する単一のディスクファイルです。SQLite自体のドキュメントでは、これを「メインデータベースファイル」と呼び、「SQLiteデータベースの完全な状態は通常、これに含まれている」と記されています。この一文において、「通常」という言葉は非常に重要な意味を持っています。
もしこれまでに.db、.sqlite、または.sqlite3ファイルを渡されて、すべてのデータを受け取れたのだろうかと疑問に思ったことがあるなら、これこそが正しく理解すべきフォーマットです。
SQLiteファイルとは実際に何なのか
SQLiteは、自らを「自己完結型、サーバーレス、ゼロ構成、トランザクション対応のSQLデータベースエンジンを実装するインプロセスライブラリ」と説明しています。同じページには、SQLiteには「独立したサーバープロセスが存在しない」とも記載されています。アプリケーションがこのライブラリをリンクし、ファイルを読み込みます。
これにより、2つの結果が生じます。第一に、データベースが1つの成果物として移動するため、非常に多くのアプリケーションがこの方法でデータを配信しています。第二に、ファイルはそれを書き込んだソフトウェアよりも長持ちするため、フォーマットが極めて安定していなければなりません。SQLiteは、その主要な特徴の1つとして「安定し、永続的なファイルフォーマット」を挙げています。また、コードはパブリックドメインにあり、「商業用、個人用を問わず、あらゆる目的で自由に使用できる」とも述べています。
その規模は過小評価されがちです。SQLite自体の紹介ページには、「数え切れないほど多くのアプリケーションで使用されている、世界で最も広く導入されているデータベースである」と書かれています。
ファイルの中身
100バイトのヘッダー
最初の数バイトがフォーマットを識別します。オフセット0の位置に、ファイルは16バイトのヘッダー文字列: SQLite format 3\000を保持しています。このシグネチャにより、ツールは拡張子に関係なくファイルを認識します。
次のフィールドは、見た目以上に重要です。オフセット16には、「データベースのページサイズ(バイト単位)」を保持する2バイトの整数があります。ドキュメントによると、これは「512から32768までの2の累乗(両端を含む)、またはページサイズ65536を表す値1でなければならない」とされています。ヘッダー内のすべてのマルチバイトフィールドは、最上位バイトが最初に格納されます。
オフセット18と19には、さらに2バイトが続きます。これはファイルフォーマットの書き込みバージョンと読み込みバージョンです。ドキュメントには、この値が「レガシーの場合は1、WALの場合は2」であると記されています。
行ではなくページ
ヘッダーの下にあるファイルは、固定サイズのページの積み重ねです。仕様書には明確にこう記されています。「メインデータベースファイルは1つ以上のページで構成される。ページのサイズは512から65536までの2の累乗(両端を含む)である。同一データベース内のすべてのページは同じサイズである。」
ページは1から番号が振られ、最大ページ数は4,294,967,294です。テーブルとインデックスは、これらのページ内でBツリー構造として存在しているため、テキストエディタで開いてもほとんど何も表示されません。
誰も言及しないサイドカーファイル
ここが落とし穴になる部分です。ドキュメントには、完全な状態は「通常」1つのファイルにあると書かれています。そして、その例外が挙げられています。トランザクション中、SQLiteは「『ロールバックジャーナル』と呼ばれる2番目のファイルに追加情報を保存」します。WALモードでは、その2番目のファイルはライトアヘッドログ(write-ahead log)になります。
そのため、アプリケーションが書き込みを行っている最中に取得したコピーには、サイドカーにまだ残っているコミット済みのデータが欠落している可能性があります。同僚から.dbファイルだけが送られてきて、数値が少し古いように見える場合は、まずこれを確認してください。
SQLiteファイルを開く方法
3つの方法があり、どれが適切かは次に何をしたいかによって異なります。
ビューアで読み込む。 デスクトップやブラウザベースのSQLiteビューアは、ファイルを開き、テーブルを一覧表示し、行をクリックして確認できるようにします。これは「そもそも何が入っているのか」を知るための最も早い方法であり、通常は最初の確認として十分です。
コマンドラインやライブラリでクエリを実行する。 sqlite3シェルや、Python、Node、その他ほとんどの言語の標準ライブラリバインディングは、このフォーマットを直接読み込みます。スキーマをすでに把握しており、特定の数値を取得したい場合は、この方法を選択します。
テーブルをエクスポートして別の場所で分析する。 テーブルをCSVにダンプし、チームがすでに使用している任意のツールに取り込みます。ただし、このフォーマットが保護していた唯一のものである、テーブル間の関係性は失われます。可能な限り、生のテーブルではなく、結合した結果をエクスポートするようにしてください。
ツールが「ファイルはデータベースではありません」と表示する理由
仕様書がこの理由を説明しています。すべての有効なファイルは、16バイトのヘッダー文字列、SQLite format 3\000で始まります。ファイルを開いた読み込みプログラムが、オフセット0の位置にそのシグネチャを見つけられない場合、渡されたファイルはSQLiteデータベースではありません。
ほとんどの場合、3つの一般的な原因が考えられます。ファイルの転送が不完全で、ヘッダーはあるものの残りの部分が途切れている場合。ファイルが暗号化されているか、アプリケーションによってラップされているため、最初の数バイトが別のデータになっている場合。あるいは、拡張子が紛らわしく、親切心から誰かが名前を変更したプレーンなエクスポートファイルを実際に受け取った場合です。
SQLiteファイルはどこまで大きくなるか
通常その質問から想像されるよりも大きくなります。SQLiteの制限に関するページによると、データベースファイルの最大サイズは4,294,967,294ページです。最大ページサイズである65,536バイトの場合、データベースの最大サイズは約281テラバイトになります。
このページはその数値について非常に率率直です。上限について、「開発者がこの制限に達することができるハードウェアにアクセスできないため、テストされていない」と記されています。
行数も同じ壁によって制限されます。理論上の最大値は、1つのテーブルにつき2^64行です。ドキュメントでは、この制限について「最大データベースサイズである281テラバイトに先に達してしまうため、到達不可能である」と指摘しています。
実務において役立つ教訓は、制限とは逆のものです。誰かから.dbファイルを渡され、サイズが大きいと警告されたとしても、このフォーマットが原因で作業が滞ることはまずありません。ファイル作成時に選択されたページサイズや、インデックスが含まれているかどうかの方が、ドキュメントに記載されている上限よりもはるかに操作性に影響を与えます。
SQLiteファイルに遭遇する場所
- アプリケーションのエクスポート。 デスクトップやモバイルのアプリは、履歴、設定、メッセージログをコピー可能なSQLiteファイルに保存することがよくあります。
- 分析データの受け渡し。 エンジニアは、データベースへのアクセス権を付与する代わりに、スナップショットを1つのファイルとして送信します。
- デバイスとテレメトリ。 組込システムは、通信するサーバーがないため、ローカルに書き込みを行います。
- アーカイブ。 フォーマットの長期的な安定性により、何年も読み取り可能な状態を維持する必要があるデータセットの一般的な選択肢となっています。
- ブラウザやツールの内部。 多くのローカルツールはこの方法で状態を保持するため、サポートチケットにこの拡張子が登場することがよくあります。
WALファイルとジャーナルファイルの役割
.dbファイルをコピーした際、その隣に-walや-journalファイルがあるのを見つけたことがあるかもしれません。これらは仕様書に記載されているサイドカーファイルであり、これらを削除することがデータ紛失の原因になります。
ロールバックジャーナルは、古い仕組みです。ページを変更する前に、SQLiteはそのページのオリジナルバージョンをジャーナルに書き込みます。書き込みが中断された場合、オリジナルを元に戻すことができるため、クラッシュしてもトランザクションが維持されます。
ライトアヘッドログ(WAL)は、この配置を反転させます。変更は最初にログに書き込まれ、メインファイルは後から更新されます。ヘッダーは、データベースがどちらのモードであるかを示します。オフセット18にあるファイルフォーマットの書き込みバージョンは、「レガシーの場合は1、WALの場合は2」です。
実用的なルールは、完全な状態に関する一文から直接導き出されます。データベースがWALモードであり、誰かからメインファイルだけを渡されたと仮定します。その場合、最も新しくコミットされた変更は、受け取っていないログの中にまだ残っている可能性があります。
したがって、データベースファイルを渡されたときは、2つの質問をしてください。コピーを取得した際、アプリケーションは正常に終了していたか、そして他に一緒に提供されたファイルはなかったか。どちらの答えも通常は「はい」ですが、そうではない稀なケースにおいて、本番環境と数値が密かに食い違うことになります。
SQLiteファイル vs CSV vs Parquet
| SQLite file | CSV | Parquet | |
|---|---|---|---|
| 形状 | 複数のテーブル、1つのファイル | 1つのテーブル、1つのファイル | 1つのテーブル、1つのファイルまたはフォルダ |
| 型 | データとともに保存 | 読み込みプログラムによって推論 | データとともに保存 |
| 関係性 | キーとインデックスを介して保持 | 失われる | 失われる |
| 人間が読めるか | いいえ | はい | いいえ |
| クエリ実行を前提とした書き込み | はい、SQLを使用 | いいえ | はい、分析エンジンによる |
| よくある失敗 | ジャーナルまたはWALサイドカーの欠落 | 型や区切り文字の推測ミス | ツールチェーンのサポート状況 |
これらのフォーマットを定期的に使用される場合は、ParquetファイルおよびTSVファイルに関する解説記事でも、これら2つについて同様の内容をカバーしています。
チームがこのフォーマットを選ぶ理由
実行環境が不要。 SQLiteには「独立したサーバープロセスが存在しない」ため、データの受け渡しはプロビジョニングの申請ではなく、単なるファイルのコピーで済みます。
型がそのまま維持される。 日付カラムは日付として届きます。CSVリーダーが識別子を指数表記に変換してしまうのを見たことがある人なら、これがいかに価値のあることか理解できるでしょう。
関係性も維持される。 関連する複数のテーブルが1つの成果物としてまとまっているため、データを意味のあるものにしていた結合がそのまま利用可能です。
堅牢性が設計に組み込まれている。 SQLiteは、そのコア機能の1つとして「停電後でも」維持されるトランザクションを挙げており、これが非常に多くの組み込みソフトウェアで採用されている理由です。
知っておくべき制限
1ファイルにつき、同時に書き込めるのは1プロセスのみ。 エンジンはサーバーとして提供されるのではなく組み込まれているため、並行処理モデルはクライアントサーバー型のデータベースとは異なります。これは設計上の選択であり、欠陥ではありませんが、このファイルがどのような用途に適しているかを決定づけています。
ページサイズは作成時に固定される。 データベース内のすべてのページは同じサイズであり、そのサイズはヘッダーに記録されます。これは作成時に一度だけ選択します。
再び、サイドカーのルールについて。 メインファイルだけを取得するコピー、バックアップ、またはアップロードのルーチンは、ジャーナルやライトアヘッドログにあったデータをすべて見落とす可能性があります。
不透明さ。 SQLiteファイルは、CSVのように簡単に中身を流し読みすることはできません。読み取るにはツールが必要であり、これこそが多くの分析作業を停滞させる摩擦となります。
SQLiteファイルから答えを得る方法
従来の方法は、クライアントをインストールし、ファイルを開き、スキーマを理解してからSQLを書き始めることです。テーブルをすでに知っている場合はこれで問題ありません。しかし、今朝ファイルを渡されて、今日の午後に会議があるという場合には、この方法では間に合いません。
より近道なのは、直接質問することです。Powerdrill Bloomを使用すると、自然言語でデータを操作でき、ソースが添付された回答が返ってきます。ホームページでは、「すべての数値が、その背景にあるページ、行、図とともに返される」と約束されています。そこから、同じワークスペースでチャート、シート、または簡単なスライド資料を作成できます。
これが通常のワークフローである場合、知っておくべき2つの関連ページがあります。Chat with Databaseは構造化データへの対話的なアプローチをカバーしており、Text to SQLはクエリ自体を取得したい場合をカバーしています。もしデータの受け渡しがフラットなエクスポートファイルとして届いた場合は、CSV AI assistantのページがその方法をカバーしています。
ヘッダーが教えてくれるもう一つのこと
ページサイズは固定のオフセットに存在するため、ファイルを適切に開く前に、ファイルに関する有用な情報を得ることができます。4,096バイトのページで作成されたデータベースは、65,536バイトのページで作成されたデータベースとは異なる動作をします。その選択は、ファイルが作成されたときに一度だけ行われました。
これは、後から気軽に変更できるような数値ではありません。設定というよりも、スキーマの決定と同じカテゴリに分類されるものです。
結論
SQLiteファイルは、1つの成果物の中にデータベース全体が収まっています。16バイトのシグネチャ、オフセット16に記録されたページサイズ、そしてテーブルとインデックスを保持する固定サイズのページの積み重ねで構成されています。持ち運びが容易で、型が維持され、何年経っても読み取り可能な状態を保ちます。
仕様書が慎重に説明している1つの注意点を忘れないでください。完全な状態は通常、そのファイルの中にあります。トランザクション中、その一部は隣にあるロールバックジャーナルまたはライトアヘッドログに存在します。コピーを信頼する前に、サイドカーファイルの有無を確認してください。
ファイルが手元にあり、スキーマではなく答えが必要な場合は、Powerdrill Bloomをお試しいただき、データに対して直接質問を投げかけてみてください。
よくある質問
.db、.sqlite、.sqlite3の違いは何ですか?
構造的な違いはありません。3つともすべて同じフォーマットに対する慣用的な拡張子であり、実際の識別子はファイルの先頭にある16バイトのヘッダー文字列SQLite format 3\000です。
SQLiteファイルが使用しているページサイズを知るにはどうすればよいですか?
ヘッダーに記録されています。オフセット16にある2バイトの整数が、バイト単位のページサイズを保持しています。これは512から32768までの2の累乗、または65536を表す値1でなければなりません。
SQLiteファイルは完全なデータベースですか?
通常はそうですが、常にそうとは限りません。ドキュメントによると、トランザクション中、SQLiteは追加情報をロールバックジャーナルに保持します。WALモードでは、その情報は代わりにライトアヘッドログに送られます。
SQLiteファイルをExcelで開くことはできますか?
直接開くことはできません。ファイルにはテキストの行ではなく、Bツリーページが格納されているためです。一般的な方法は、まずテーブルをCSVにエクスポートするか、データベースフォーマットを読み込んで結果を返すツールを使用することです。
SQLiteは商用利用無料ですか?
はい。SQLiteは、そのコードがパブリックドメインにあり、「商業用、個人用を問わず、あらゆる目的で自由に使用できる」と述べています。