📝

UPDATE設計を破綻させないDB状態遷移図の作り方

に公開

はじめに
この記事では、設計段階でDBの状態遷移図を先に作るべき理由と、UPDATE が多い業務システムでどのように運用可能なデータモデルへ落とし込むかを整理します。
特に、イミュータブルデータモデルの利点を認めつつ、データ量や運用負荷の現実から UPDATE を前提に設計する場面を対象にします。

なぜ状態遷移図が最初に必要なのか
テーブル設計をカラム定義から始めると、後で「このデータはいつ、誰が、どの条件で更新してよいのか」が不明確になりやすいです。
この曖昧さは、実装段階で次の問題として表面化します。

想定外の UPDATE が混ざる
画面やバッチごとに更新ルールが分岐する
不整合の調査で原因追跡が難しくなる
状態遷移図を先に作ると、更新可能な経路と禁止すべき経路を設計時点で合意できます。
結果として、UPDATE 文の責務が明確になり、実装の迷いと不具合が減ります。

UPDATE が一番面倒になる理由
INSERT は新規追加、DELETE は削除として比較的責務が単純です。
一方で UPDATE は、既存状態との関係を常に意識する必要があります。

遷移前の状態チェックが必要
同時更新の競合を考慮する必要がある
監査や再現のために変更履歴を残す必要がある
業務ルール変更の影響を受けやすい
つまり、UPDATE はSQL構文の問題ではなく、状態管理そのものの問題です。

イミュータブルモデルは有効だが万能ではない
イミュータブルデータモデルは、更新を追加操作へ置き換えるため、監査性と再現性の面で強力です。
ただし実務では次の制約にぶつかります。

データ量の増加による保管コスト
参照クエリの複雑化
JOINが多くなりパフォーマンスが悪化しやすい
最新状態の算出コスト
保守担当者の学習コスト
そのため、全領域を完全イミュータブルにするより、履歴を残すべき領域と UPDATE で管理する領域を分ける設計が現実的です。

ユーザー仮登録と本登録の例で見る必要性
たとえばユーザー管理で、仮登録 -> 本登録 -> 退会 のような状態を UPDATE で管理する場合、状態遷移図がないとデータの変化を追いにくくなります。
仮登録の時点では、メールアドレスは存在しても、社内ユーザーIDや所属情報はまだ払い出されていないことがあります。
このように「状態ごとに存在するデータが違う」前提を図で明示しておかないと、実装側で不整合が起きやすくなります。

どの操作で 仮登録 から 本登録 へ変わるのか
メール未確認のまま本登録へ進めるのか
本登録時に社内ユーザーIDをいつ払い出すのか
本登録後にどの機能が利用可能になるのか
退会時に関連テーブルをどう更新するのか
ここが曖昧だと、別機能の設計時に「このユーザーテーブルは今どの状態を前提にすべきか」が分からなくなります。
結果として、認可、通知、課金、監査ログなど周辺機能で前提不一致が起きやすくなります。

イミュータブルで全面管理しないのであれば、少なくとも状態遷移図で どの状態からどの状態へ、何を条件に変わるか を固定しておくことが重要です。

Discussion