SQL

SQLファイルとは

表を INSERT 文に直したもので、そのままデータベースに流し込めます。

SQL とは何か

SQL はプレーンテキスト形式です。どのエディターでも開けます。 プログラム間のデータ受け渡しと長期保存のために使われます。

拡張子は .sql、正式名称は SQL Insert Statements です。ただしどちらも、そのファイルが中に何を持てるかほどには多くを語りません。このページの残りは、その中身についての話です。

SQL はどこから来たのか

1986 年までさかのぼります。 仕様は ISO/IEC 9075 です。

これだけ長く読まれ続けてきた形式なら、10 年後に取り出したいものを預けても大丈夫です。

仕様は公開されています

仕様書がそのまま公開されているので、中身を推し量るのではなく文書を読んで実装できます。この形式が数多くのプログラムに載っているのはそのためであり、20 年前に書かれたファイルが今も開けるのもそのためです。ただし「仕様が公開されている」ことと「使用料が要らない」ことは別の話です。中でコーデックを包んでいる形式では、特許のライセンスは仕様書が答えていない別の問題として残ります。

コメントを書き残せます

SQL ファイルにはコメントを書く方法があります。人が面倒を見るファイルと、プログラムが書き出すファイルを分けるのは、まさにこの一点です。コメントを持てない形式へ変換すると真っ先に消え、しかも誰も警告してくれません。

SQL を開けるのは何か

PostgreSQL、MySQL、DBeaverが読めますし、同じ種類のプログラムならたいてい読めます。

ファイルが開かないとき、形式が悪いことはめったにありません。たいていはプログラムのほうが形式より古いのです。もっと古い形式に変換してしまうのが確実な逃げ道で、このサイトの残りの部分はそのためにあります。

ブラウザーで開く

これを読めるブラウザーはありません。

これを変換するいちばんよくある理由がこれです。形式が悪いのではありません。ファイルを見せたい場所が、それを読めないというだけのことです。

作業のための形式です

SQL は、開いて手を入れるために作られています。作業が続いているあいだはこの形式でファイルを持ち、完成したものが必要になるたびに、ここから書き出してください。

言語であり、それを含んでいるだけのファイル

SQL は 1986 年から標準化されているクエリー言語です。.sql ファイルは、その文を含んだテキストファイルにすぎません。ヘッダーもなく、構造もなく、拡張子だけを見て特定のファイルが何をするかを知る方法もありません。テーブルを作るかもしれず、百万行を挿入するかもしれず、スキーマを変更するかもしれず、あるいは誰かが残しておきたかった三つのクエリーが入っているだけかもしれません。

実際にやり取りされるファイルは、たいてい二種類に分かれます。ダンプは、データベースやテーブルを、別の場所で再現するための文として書き出したものです。マイグレーションはスキーマを制御された形で変更するスクリプトです。どちらもテキストで、どちらもどんなエディターでも開けますが、この二つを取り違えると、列を追加するはずのスクリプトがテーブルを削除してしまう、といった事態になります。

ダンプが実際に含んでいるもの

たいてい三つの要素が順番に並びます。テーブルが存在すれば削除する文で、これがあるため、稼働中のデータベースに対してダンプを実行することは取り消せる行為ではありません。列とその型を定義する CREATE TABLE 文。そして行のデータが INSERT 文として続きます。一行に一つのこともあれば、数百行を一つの文にまとめていることもあります。後者は読み込みが劇的に速い代わりに、読みにくくなります。

その周りに、本物のダンプはさらに管理用の記述を加えます。文字コードの宣言、データ読み込み中はインデックスの再構築を止める設定、途中で失敗しても何も残らないようにするトランザクションのラッパーなどです。この管理部分はデータベースごとに異なり、あるデータベースのダンプが別のデータベースに読み込めない主な理由です。

方言こそが問題

標準は核となる部分を定めていますが、どのデータベースもそれを拡張しています。識別子の引用符も違います。MySQL はバッククォート、PostgreSQL は二重引用符、SQL Server は角括弧です。自動採番のキーは三通りの書き方があります。日付関数、文字列関数、真偽値の扱い、型の名前そのものもすべて異なります。

そのため MySQL のダンプは PostgreSQL には読み込めず、出てくるエラーはたいてい理由の説明ではなく、四行目あたりの構文エラーです。方言の間の変換は本物の作業で、しかもほとんど機械的です。スキーマではなくデータを移したいだけなら、SQL を翻訳するより CSV を経由するほうが、たいてい速くて確実です。

グラフィカルなツールなしで読み込む

コマンドラインでは、どのデータベースも独自のクライアントを持っていて、呼び出しは短く済みます。PostgreSQL なら psql、MySQL や MariaDB なら mysql クライアント、SQLite なら sqlite3 が、それぞれファイルを入力として受け取ります。大きなダンプにはこれが圧倒的に速い方法です。まずファイル全体をメモリーに読み込むグラフィカルなツールは、数百メガバイトを超えると苦戦します。

実行する前にすべきことが二つあります。ファイルの先頭を読んで、何かを削除する文がないか確認すること。そしてダンプ自体がデータベースを作らない場合は、先に対象のデータベースを作っておくことです。あるデータベース名向けに書かれたダンプが、勝手に別の名前を作ってくれることはありません。

なぜ大きな取り込みが途中で止まるのか

たいてい四つのうちのどれかです。数千行をまとめた大きな INSERT がぶつかる、サーバー側のパケットや文のサイズ上限。グラフィカルなクライアントにはあってもコマンドラインにはないタイムアウト。エラーではなく文字化けとして現れる文字コードの不一致で、早めに気付く価値があります。あるいは、参照先のテーブルより先に届いた行を拒否する外部キー制約です。

最後のものが一番よくあり、一番気付きにくい原因です。ダンプは通常、読み込みの間だけ制約チェックを無効にすることでこれに対処していますが、手作業で編集されたダンプ — 大きなファイルから一部のテーブルだけを抜き出したもの — はその保護を失っています。依存関係の順序で読み込むか、そのラッパーを復元するのが対処法です。

手元のものにダンプが不向きなとき

ダンプはデータベースを再現するためのものです。欲しいのがデータそのもの — 分析する、スプレッドシートに読み込む、データベースを動かしていない人に渡す — であれば、CSV のほうが良い入れ物で、その違いが目に見えるほど大きなデータなら Parquet のほうがさらに良い選択です。

逆方向も知っておく価値があります。スプレッドシートを INSERT 文に変換するのは、直接接続する手段がないデータベースにテーブルを入れる標準的な方法です。管理型ホスティングでよくある状況で、開いたポートはなくても、貼り付けたファイルを喜んで実行してくれるクエリーコンソールがある、という場合です。

安全に読み書きする

テキストなのでどんなエディターでも開けます。実行する予定があるなら、SQL の構文を理解するエディターを使う価値があります。文に色を付けてくれ、データベースが見つける前に、閉じていない引用符を目に見える形で示してくれます。

ダンプは非常に大きくなることがあり、数ギガバイトのファイルを確認する賢い方法は、全体を開くのではなく最初と最後の数十行だけを見ることです。最初の行は方言と文字コード、何かが削除されるかどうかを教えてくれ、最後の行はダンプが最後まで終わったかどうかを教えてくれます。誰かから送られてきたファイルについて知るべき、最も役立つ情報です。

基本情報

SQLフォーマットの識別子と出自。
拡張子.sql
メディアタイプapplication/sql
初版1986
仕様ISO/IEC 9075

SQL ファイルについてのよくある質問

SQL ファイルを開くには

プレーンテキストなので、どんなテキストエディターでも開けます。実行する予定があるなら、SQL の構文を理解するエディターやデータベースツールのほうが良く、文をハイライトし、データベースが見つける前に閉じていない引用符を示してくれます。

SQL ファイルをデータベースに取り込むには

そのデータベース自身のコマンドラインクライアントに、ファイルを入力として渡してください。PostgreSQL なら psql、MySQL や MariaDB なら mysql クライアント、SQLite なら sqlite3 です。大きなファイルではグラフィカルなツールよりずっと速く確実です。ダンプがデータベースを作らない場合は、先に対象のデータベースを作っておいてください。

MySQL のダンプは PostgreSQL に読み込めますか

ほぼ読み込めません。識別子の引用符、自動採番の構文、型名、関数名がすべて異なるため、たいてい数行以内で読み込みが失敗します。スキーマではなくデータを移したいだけなら、CSV に書き出してそれを取り込むほうが、方言を翻訳するより速いのが普通です。

なぜ取り込みが途中で止まるのですか

よくある原因は、大きな一括 INSERT がぶつかるサーバー側の文サイズ上限、グラフィカルなクライアントのタイムアウト、参照先のテーブルより先に届いた行を拒否する外部キー制約です。ダンプは通常、読み込みの間だけ制約チェックを無効にしていますが、手作業で編集した抜粋はその保護を失っています。

SQL ファイルはデータベースそのものですか

違います。データベースを構築するための命令の集まりです。データベースは、そのファイルが実行された後に存在するものです。ファイル自体はテキストで、どんなエディターでも読め、何かが実行するまでは何もしません。

データを移すには SQL と CSV のどちらを使うべきですか

行き先がスプレッドシートや分析ツール、別のデータベースエンジンなら CSV です。同じデータベースを別の場所で再現したく、スキーマや型、キー、インデックスも一緒に持っていきたいなら SQL のダンプです。