データベースとマイグレーション
PostgreSQL の運用先を選び、実行中のアプリを壊さず Drizzle の変更をリリースします。
スターターのコミット
7580470で検証済みです。
このページを終えると、各環境で使う DB、スキーマ変更をレビュー可能な SQL にする方法、アプリのリリースとは分けて適用する方法が分かります。
スターターは複数の DB アダプターを用意せず、PostgreSQL と Drizzle を採用しています。ローカルでは pnpm setup で Docker 上の PostgreSQL を使えます。本番では、互換性のあるマネージド PostgreSQL または自社運用の PostgreSQL を選び、DATABASE_URL を設定します。src/db/schema.ts がスキーマの正本で、src/db/migrations/ にコミットされた SQL がデプロイ履歴です。db() を呼べるのは src/models/** だけです。
ローカル手順
pnpm setup は開発用とテスト用の DB を分けて作ります。テスト DB の名前には test が必要で、安全機構はそれ以外の DB の全行削除を拒否します。
スキーマ変更後:
pnpm db:generate
pnpm db:migrate
pnpm test:db:setup
pnpm test:db生成された SQL と meta/_journal.json をコードと一緒にコミットし、デプロイ済みのマイグレーションは編集しません。
本番手順
アプリのデプロイ時にマイグレーションは自動実行されません。DB とアプリを別々に監視し、再試行し、リリースできるようにする既定の安全策です。
pnpm db:check:prod
pnpm db:migrate:prod本番用の実行処理は、非対話で PostgreSQL のアドバイザリーロックを取得し、チェックサムを検証します。先にバックアップを取り、スキーマとアプリを別々にリリースしても新旧コードの両方が動く、追加してから削除する段階的な変更にします。
データ規約
- 数値
idは内部用、公開 API はuuidを使います。 - 金額は最小通貨単位の整数と通貨コードで保存します。
- テナントに属する行は
org_uuidを持ち、すべてのモデルクエリで組織を限定します。 - 冪等性キーと取引番号は、DB の一意制約で守ります。
- 広範な外部キー結合を意図的に避け、削除順序と参照確認はサービスとデータライフサイクル方針が担います。
- 予約では PostgreSQL の排他制約も使い、仮押さえ・確定済みの時間枠が重複するのを防ぎます。
本番前に決めること
- マイグレーションを CI のリリースジョブと運用担当者のどちらが実行するか決めます。各 Web インスタンスからは実行しません。
- データの価値に見合うバックアップ・復元方針を決めます。マイグレーションロックはバックアップの代わりではありません。
- 外部キーを少なく保つか、削除・保持の規則を定義したうえで厳しい制約を加えるか決めます。どちらもテナント間の安全性を保つ必要があります。
- 無停止を目指す場合は、追加してから削除する段階的な変更を優先します。破壊的な一段階の名前変更は簡単ですが、スキーマとコードのリリースを結合し、ロールバックを危険にします。
pnpm db:check:prod が予想どおりの未適用一覧を示し、バックアップが最新で、ステージング環境の複製で検証済みであり、展開中に旧・新両方のアプリ版が動くなら、本番マイグレーションの準備は完了です。
本番データの契約を変える前に、スターターの docs/database.md と DEPLOYMENT.md を読んでください。コードの置き場所はアーキテクチャとエラー契約、認証用 ID と公開 ID の区別は顧客認証で確認できます。