Railsのプロジェクトを触っていると、db/structure.sql という巨大なファイルに出会います。
「これ何?勝手に書き換わるけど触っていいの?」と戸惑いがちなこのファイルを、初心者向けにまとめます。
結論:DBの「完成形の設計図」
structure.sql は、ひとことで言うと
今のデータベースの構造を、ゼロから丸ごと再現するためのSQL命令をまとめた「完成形の設計図(スナップショット)」
です。しかもRailsが自動で生成・更新するファイルで、人が手で書くものではありません。
中身はこんなイメージです。
CREATE TABLE `deals` ( -- 「案件」テーブルを作る命令
`id` bigint unsigned NOT NULL,
`name` varchar(255),
...
);
CREATE TABLE `contacts` ( ... ); -- 「コンタクト」テーブルを作る命令
...(全テーブル分つづく)...
-- 末尾に「どの設計変更まで適用済みか」の台帳
INSERT INTO `schema_migrations` VALUES
('20260806000000'),
('20260805000000'),
...
前半に全テーブルの CREATE TABLE、末尾に「どこまで変更を適用済みか」の台帳(schema_migrations)が入っています。
前提知識:マイグレーションとの関係
structure.sql を理解するには、マイグレーションとセットで考えるのが近道です。
-
マイグレーション = DB構造の変更履歴(=設計変更の指示書の束)
- 例:「dealsテーブルにstatus列を追加する」といったファイルが1変更につき1つ
- ファイル名は
20260803000000のような 日付+番号
- structure.sql = その履歴を全部適用し終えた最終結果のスナップショット
図にするとこうです。
① 開発者がマイグレーションファイルを書く(変更の指示書)
例:「dealsにstatus列を追加」
② db:migrate を実行 → 実際にDBが変更される
③ ★このときRailsが自動でstructure.sqlを"今のDBの姿"に更新する★
つまり structure.sql は、db:migrate の副産物として自動更新されるもの。原則、手で編集しません。
何のためにあるの?
一番の存在理由は、新しくDBを一から作るときに速いからです。
新メンバーが環境構築するとき、あるいはテスト用DBを毎回作り直すとき、DBを「まっさら → 最新の形」にする必要があります。その方法は2つあります。
| 方法 | やること | 速度 |
|---|---|---|
| マイグレーションを全部実行 | 何百個の指示書を1個ずつ順番に実行 | 遅い |
structure.sql を読み込む |
完成形を一発で再現 | 速い |
なぜマイグレーション全実行は遅いのか
理由①:歴史をもう一度なぞるので無駄が多い
マイグレーションは変更履歴なので、全実行すると過去の回り道まで再現します。
① dealsテーブルを作る
② dealsにstatus列を追加
③ ②のstatus列を削除する ← 気が変わった
④ dealsにstate列を追加
最終的に欲しいのは「statusは無く、stateがある」状態だけ。でも全実行は②で作って③で消す無意味な往復まで律儀に再現します。structure.sql は最終結果だけなので回り道しません。
理由②:1個ずつ直列でしか実行できない(オーバーヘッド)
マイグレーションは順序依存なので並列化できず、1個ごとに「Rails起動→コード読込→SQL変換→実行→台帳記録」の準備・後片付けが発生します。これが数百回積み重なる。
structure.sql は1本の巨大なSQLを流し込むだけなので、この繰り返しコストがほぼゼロです。
理由③:中間状態の作り替えが積もる
同じ「state列を追加」でも、マイグレーションはテーブル作成→列追加→列削除→別の列追加…と中間状態を何度も作り替えます。インデックスの貼り直しなどが絡むとさらに遅くなります。
たとえ話
- マイグレーション全実行 = 料理番組を1話目から全部見て、途中の失敗作まで作り直して追体験する
- structure.sql = 完成した料理の写真とレシピを見て、それだけ作る
欲しいのは完成品だけなので、後者が圧倒的に速い、というわけです。
だから2つを使い分ける
structure.sql とマイグレーションは、どちらか一方が偉いのではなく、場面で使い分けます。
| 場面 | 使うもの | 理由 |
|---|---|---|
| 新環境構築・テストDB作成 | structure.sql(完成形) | 履歴をなぞる必要はなく、速く最新状態を再現したい |
| 稼働中の本番DBを変更 | マイグレーション(差分だけ) | 既存データを保ったまま「今回の変更分」だけ安全に当てたい |
新メンバーの環境構築は「まっさら → 最新形にしたいだけ」なので、structure.sql が最適です。
補足:schema.rb と structure.sql
Railsの設計図には2形式があり、プロジェクトごとにどちらか一方を選びます。
| ファイル | 中身 | 特徴 |
|---|---|---|
db/schema.rb |
Rubyで書かれた設計図 | シンプル。Railsのデフォルト |
db/structure.sql |
生のSQLで書かれた設計図 | トリガーやDB独自機能まで忠実に表現できる |
MySQLのトリガーや細かい制約など、Rubyの schema.rb では表現しきれない機能を使っているプロジェクトでは structure.sql を選びます。
まとめ
| 質問 | 答え |
|---|---|
| structure.sqlって何? | 今のDB全体の構造を再現するSQLをまとめた「完成形の設計図」 |
| Railsが作るの? |
はい。db:migrate 実行時に自動生成・更新される |
| 手で書く? | 原則ノー。自動更新される |
| 何の役に立つ? | 新環境・テストDBを一瞬で最新構造にするため |
Top comments (0)