Open7
イミュータブルデータモデルは制約条件として活用するのが良いのでは?
データと情報の違い
- データ
- 単なる事実を記録したもの
- これを永続化するのがRDB
- 情報
- データに解釈を加えたもの
- RDBから情報を生成するのに適しているものがSQL
なので、「事業にとって重要になるかもしれない事実をいかにデータとして記録しておくか」が重要である。
イミュータブルデータモデルとは
上述のように「重要となり得る事実を失わず記録する」ことが重要になる。
- そしてデータ (事実)を失う操作がUPDATE、DELETE
- なので、UPDATEやDELETEが極力起こらないようデータモデリングしていくことが重要
- そのために、リソースとイベントを抽出し、INSERT中心に設計していく
- 昔はマスタとトランザクションみたいな分類をしていたが、どれがマスタみたいなのが人によって揺れやすいので、最近はリソースとイベントのほうがうまくいきやすいと考えられている
- ある1点における活動を捉えたものがイベント (なのでwhenがある)、それ以外がリソース
- 各データの変更履歴も辿れるし、なにかあっても常に事実を理解できて最高〜
というのがイミュータブルデータモデルの根幹ではないかと。
実際にイミュータブルデータモデルやろうとしたらキツくないか?
- 例えばRailsみたいなフレームワークもUPDATEが起きること (最新の事実だけ残ってればええやん)前提で設計されている
- 「大抵のケースにおいて、最新の事実だけわかれば十分ちゃう?」という強い制約を設けることで、シンプルさを享受できる (考えることを減らせる)のがRailsの良さ
- そのトレードオフを受け入れる代わりに生産性を向上させることができる
- そもそも全データの履歴って本当に事業上、必要になることあるんだっけ?
- 普通に実装やクエリがしんどくなりそう、複雑になりそう
イミュータブルモデルは論理設計時の制約条件として有用
- イベントとリソースを抽出して、データモデリングをしていきたい
- UPDATEとDELETEがない究極の世界を考えてみる (制約を作る)と気づいていなかったイベントに気づけることが多い
- リソースのCRUD前提で考えていたもののUPDATEやDELETEが禁止ってなると、「この削除どうやって表現するんや」となるので
例: 社員と部署
- 社員と部署の関係をどうモデリングするか
- 「社員が部署に所属する」を表現したい
- 社員と部署の間に所属というテーブルを想定する
- 社員ID(FK)、部署ID(FK)、所属開始日時、所属終了日時
- 典型的なリソースエンティティ
- まずINSERTしかできない前提で論理設計を考える
- まともに所属すらできなくなる (日時情報をUPDATEできないので)
- 着任イベント、離任イベントとして表現すればよいのでは?
- 着任イベント、離任イベントの生成として整理し、それらを紐付けてやればINSERTだけで表現可能
- イミュータブルデータモデルで理想形を考えた後、物理設計フェーズで実装も考慮してみる
- 着任イベントや離任イベントのレコードどんだけできるんだよ、って辛くなる
- 着任、離任イベントをすべて覚えておいて、そこから計算で現在の部署を出すとか辛くないですか?
- 例えば事業上の要件としては、ただの社員一覧で現部署情報を出したいってだけだった場合にそんなコストを払うのはどうなのか
- 離任がついていない着任をSELECTしてきて最新のデータを取ってこないといけない、辛い
- 本当に全所属の変遷を追える必要はあるのか?追いたいのか?
- 着任、離任イベントはたしかに存在する、ただ要件的には現在の所属というテーブルがあれば十分ではないかという妥協案が生まれる
- 所属というリソースは作りましょう、そこに開始日や終了日を入れられるようにしましょうとか
- もしくは現在の所属しか入っていないみたいな着地にしましょうとか
- 論理設計で検討したものは物理設計で変わることは全然ある
- イミュータブルデータモデルの考えなしでも似たような結論には達するだろうが、イベントを抽出しきった上でそこにたどり着いているか否かが重要
- 着任イベントや離任イベントのレコードどんだけできるんだよ、って辛くなる
イミュータブルデータモデルは制約条件である
こんな感じで、事業要件を満たす最適案に着地するプロセスが良いデータモデリングなんだろうなと。
- イミュータブルモデル前提で論理設計
- UPDATEやDELETEがない制約で存在するリソース、イベントを出し切る
- 物理設計で実際の実装も考慮した整理をすると、「これ辛くないすか...」というポイントが出てくる
- UPDATEも一定許容した最善と思われる案に着地する
- このデータは履歴も追えるようにしたい、これは追えなくても最新さえわかればよい、など