ステータス管理テーブル
1. 目的
2. 課題
- 複数のサブシステムで構成されたシステムがあり、それらは各々テーブルを管理している
- アプリケーションはサブシステムの状態によって処理の内容を変える必要がある為、各サブシステムが管理するテーブルにクエリを発行する必要がある
- この状態チェックのクエリは各サブシステムに仕様変更が発生するたびに改修が必要になってしまう
3. 解決策
- サブシステムから現在の状態を報告してもらうテーブル(=ステータス管理テーブル)を作成する
- ↓のようなイメージ
-- 進捗ステータス管理テーブル
CREATE TABLE progress_status (
id int AUTO_INCREMENT PRIMARY KEY, -- 主キー
matter_id int, -- 案件ID(FK)
is_checked_content int, -- 広告内容チェックが完了しているか(0/1)
is_checked_banner int, -- バナーデザインチェックが完了しているか(0/1)
is_checked_legal int, -- 法務チェックが完了しているか(0/1)
is_checked_advertiser int, -- 広告主チェックが完了しているか(0/1)
is_checked_payment int -- 入金チェックが完了しているか(0/1)
);
- サブシステム側のワークフローが完了したらステータス管理テーブルの状態を更新する(そのような処理をサブシステム側に実装する)
- アプリケーションはステータス管理テーブルの状態を参照して処理を行う
4. メリット
- アプリケーションは1つのテーブルを見れば全体の進行状況を知ることができる
- 各テーブルを参照するクエリとその結果を判定する処理が不要になる
- サブシステムの改修や仕様変更の影響を受けなくなる
5. デメリット
- サブシステムの状態はクエリにより導出可能である為、正規化を崩すことになる
- 正規化を崩すことで実質的にデータを二重に持つことになるため、更新漏れとデータ不整合のリスクを抱えることになる
6. 注意事項
- ステータス管理テーブルを使うと必然的に正規化が崩れるので無闇に乱用してはならない
参考資料
Appendix-1: 例
- 例として広告配信システムを考える
- この広告配信システムでは各部門の作業が完了しないと広告を配信することができない
- 各部門で行われる作業は以下のようなものがある
- 広告入稿内容チェック
- 広告バナーチェック
- 法務チェック
- 広告主最終チェック
- 入金チェック
- 配信開始
- 各タスクは部門間をまたいで行われるものもあり、それぞれの状態はサブシステムに登録される
- 最終的に配信を開始する際は、サブシステムに登録されたデータを参照して全ての工程が完了していることを確認する必要がある
- 現状は配信開始を担当するアプリケーションから各サブシステムのデータを参照しているが、参照先のサブシステムの仕様変更や改修の影響を受けやすく、不具合が発生しやすいという問題がある