テーブル設計: statusカラムから生じる技術的負債とその解決策②
概要
の解説記事です。
実際にありそうなユースケースで説明しています
対象読者
- テーブル設計を学んでいる方
- 技術的負債を解消したい方
いいね!してね
この記事の事例は必要に応じて今後追記していく予定です!
「新しい事例が知りたい」「他の事例も知りたい」と思った人は、ぜひこの記事にいいね👍してください。筆者のモチベーションにつながります!
それでは以下が本編です。
ユースケース
下記のような会員(member)のテーブルを例にしたい。
会員のライフサイクルは下記のような流れで変わると想定できる。
1 会員未認証(pending_activation)
2 会員認証完了(verified)
3 会員情報入力完了(active)
4 会員退会(resigned)
また、上記の他に、システム・管理者権限で操作できるものとして下記の状態がある。
5 会員失効(disabled)
6 会員強制退会(banned)
7 会員復元(restored)
その他ライフサイクルが変わるごとにレコードを作成するアクティビティテーブル(status_activities)がある。
上記のライフサイクルについて説明していく。
説明すること
- Writeフロー
- Readフロー
Writeフロー
会員未認証(pending_activation)
firebaseのメールアドレスログインのフローを想定してほしい。
ユーザーが、会員登録フォームにメールアドレス・パスワードを入力して送信する。
入力したメールアドレス宛に認証用のメールが送信される(未認証)
Writeフローの例1
会員認証完了(verified)
ユーザーは、認証用のメール内のリンクをクリックして認証を完了させた。
※認証完了時にコールバックでWEBサイトの特定のURLをGETする
Writeフローの例2
会員情報入力完了(active)
アドレス認証完了したのち、会員情報入力画面を表示させる。
ユーザーは、必須入力項目のみ登録する。
※入力項目はhas_oneでmember_accountテーブルを用意する。今回は割愛
Writeフローの例3
その他
割愛。必要であれば追記します
Readフロー
ログインユーザーの判定
member_status_activitiesテーブルを見ると、上記のWriteフローの履歴が全て存在する。
member_status_activities
id | member_id | status | created_at |
---|---|---|---|
xxxxx-xxxxx-00001 | aaaaa-aaaaa-aaaaa | PENDING_VERIFICATION | 2024-05-16 22:00:00 |
xxxxx-xxxxx-00002 | aaaaa-aaaaa-aaaaa | VERIFIED | 2024-05-16 22:05:00 |
xxxxx-xxxxx-00003 | aaaaa-aaaaa-aaaaa | ACTIVE | 2024-05-17 10:00:00 |
ログインメンバーかどうか判定したいなど、最後のステータスを取得したいケースが想定される。
その場合は、member_idごとに最後のステータスのみ表示した viewテーブル(member_status_activity_latest)かそれに相当するレポジトリ層を用意する。
member_status_activity_latest
id | member_id | status | created_at |
---|---|---|---|
xxxxx-xxxxx-00003 | aaaaa-aaaaa-aaaaa | ACTIVE | 2024-05-18 03:00:00 |
このテーブルからmember_id
とAVTIVE
という条件でレコードを取得できたとき、ログインユーザーであると判定できる。
Readフローの例1
まとめ
ステータスの追加、削除、順序入替えをしたくなったときに対応しやすいテーブル設計になった!
主キーで関連しているためデータ量が増えてもクエリコストが小さいと思う!
この記事が参考になった方は、ぜひこの記事にいいね👍してください。筆者のモチベーションにつながります!また、質問や疑問点があればコメントください
Discussion