概要
Rails では マイグレーション (migration) と スキーマ (schema) が連携して、データベース構造をコードで安全にバージョン管理できます。マイグレーションは「変更履歴」、スキーマは「現在の完成図」を表し、いずれも ActiveRecord によるオブジェクト指向データ操作の基盤です。本節では両者の役割と実践的な運用方法を詳述します。
1. マイグレーションとは
| 観点 | 内容 |
|---|---|
| 目的 | データベースの「構造変更」を Ruby で宣言的に記述し、差分を自動適用する |
| 本体 | db/migrate/YYYYMMDDHHMMSS_add_email_to_users.rb のようなタイムスタンプ付き Ruby クラス |
| 実行単位 | バージョン番号(タイムスタンプ)が付けられ、順序どおりに適用/取り消し可能 |
| 永続管理 | Git などの VCS にコミットして、チーム/CI で同じ履歴を再現 |
1.1 生成
生成直後の雛形:
-
changeは 可逆的。自動でup/downが推測されます。 -
破壊的操作(
execute "DROP TABLE ..."など)はup/downを 個別に 定義。
1.2 適用・管理コマンド
| コマンド | 説明 |
|---|---|
bin/rails db:migrate |
まだ適用されていないマイグレーションを順に実行 |
bin/rails db:rollback STEP=1 |
直近 n 件を取り消し (STEP 省略で 1) |
bin/rails db:migrate:status |
適用済み/未適用を一覧表示 |
bin/rails db:version |
現在のスキーマバージョンを表示 |
ActiveRecord は schema_migrations テーブルで 適用済みバージョン を追跡します。
2. スキーマ定義ファイル
2.1 db/schema.rb
db/schema.rb-
マイグレーションを 全部適用した結果 を Ruby DSL で表現。
-
デフォルトで
bin/rails db:migrate後に自動更新。 -
非常に高速にロードでき、テスト用データベース作成 (
bin/rails db:test:prepare) でも使用。
2.2 db/structure.sql
db/structure.sql-
schema.rbが表現できない DB 固有機能(CHECK 制約、トリガーなど) を完全保持。 -
config.active_record.schema_format = :sqlで出力形式を切替。
選択指針
ポータビリティ重視 →
schema.rbDB 固有機能を多用 →
structure.sql
3. マイグレーションのライフサイクル
-
作成:
rails generate migration -
コードレビュー:命名規則・インデックス・NOT NULL 制約確認
-
適用:CI/CD で
rails db:migrateを自動実行 -
検証:アプリ起動時に PendingMigrationError がないことを確認
-
運用:本番でロールバックが難しい破壊的変更は 2 段階 で実施
-
① 新カラム追加 → 両対応コード
-
② 旧カラム削除
-
4. データマイグレーションの扱い
-
構造変更とデータ更新を分離するとレビュー・ロールバックが容易。
-
構造:
20250621120000_add_status_to_orders.rb -
データ:
20250621121000_migrate_order_status.rb(update_all等)
-
-
大量データは バッチ(Rake タスク/ActiveJob)や オンラインマイグレーションツール(gh-ost, pt-online-schema-change 等)を選択。
5. ベストプラクティス
-
わかりやすい名前
-
AddDeletedAtToUsersなど変更内容+対象テーブルを明示
-
-
インデックスは同時追加
-
後から追加するとロールバック時に整合性問題が起きやすい
-
-
NOT NULL 制約は 2 段階
-
カラム追加 (
null: true) → 既存行更新 → 2) 制約付与 (change_column_null)
-
-
長時間ロック回避
-
add_column_with_defaultを避け、default:をマイグレーション後にchange_column_defaultで設定
-
-
db/seed.rb と混同しない
-
seeds は 初期データ投入用。構造変更はマイグレーションで行う
-
-
idempotent なコードを書く
-
index_exists?,column_exists?で多重適用エラーを防止
-
-
本番直前のロールバック不可対策
-
safety_assured {}(gem strong_migrations)や メンテナンスウィンドウを設定
-
6. よく使う DSL サンプル
7. 参考コマンド一覧
まとめ
-
マイグレーションは時系列で蓄積される「差分スクリプト」、スキーマファイルはその結果を示す「最新設計図」。
-
ActiveRecord が
schema_migrationsテーブルと DSL を用いて、DB の状態を Ruby コードで安全に同期する。 -
破壊的変更・大量データ移行はフェーズ分割し、ロック時間とロールバックリスクを最小化する。
-
schema.rbとstructure.sqlの選択は用途で切り替え、CI/CD で自動検証を徹底する。
以上が Rails モデルレイヤにおける マイグレーションとスキーマ の詳細です。
ChatGPT4o 生成日:2025/06/21