はじめてのデータモデリングやってみたらめちゃくちゃつまずいた
背景
大きめの施策を進める中で、システムに新しい概念が追加されることになりました。
改修対象のドメインは複雑性が高く、これを機に整理をしてみようということでデータモデリングをチームで初めてやってみました!
テックリードの方にサポートしてもらいながらモデリングする中で学んだことを書いていきます。
前置き
なぜデータモデリングをしたか
以下の理由でデータモデリングをすることになりました
- 既存のテーブル構成にとらわれず、最適なテーブル構成を考えたい
- データモデリングに関する考え方をチーム内で定着させたい
やったこと
-
前提
- 業務フロー図作成と疑問解消をチームでやった上でデータモデリングに着手
- 全員モデリングへ初挑戦
-
とりあえず以下を進めてみることに
つまずきポイント
エンティティと属性の違いが分からない
「まずはエンティティを出していきましょう^^」と進めようとしたところ、それぞれが出すエンティティの粒度や定義がばらばらな状態でした。
「それってエンティティ?属性じゃない?」などの会話に。
何をエンティティとして何を属性とすべきか?がチーム内で認識を揃えられていませんでした。
改めて定義を確認。
- エンティティ:特定のデータを表すもので、一意のIDが振られる。それ単体で成り立つもの。
- 属性:エンティティに従属するデータ。単体では成り立たない。
洗い出したエンティティに従属するデータがないのであれば、それは何かのエンティティの属性とみなして良いのかなと理解しました🧐
イベントとリソースの違いが分からない
エンティティを洗い出した後はイベントとリソースに分けます。
そこでまた用語の定義がしっかりされていなかったので混乱を生みました。
以下で認識を揃えました。
- イベント:日時が必要なエンティティ
- リソース:日時が不要なエンティティ
チーム内でドメインに関する解像度がばらついている
モデリングを進める中で、会話が噛み合わなくなることが多々ありました。
業務をなんとなく理解しているがその理解を言語化できていない人、そもそも前提を追えておらず業務理解が浅い人など、それぞれの理解度がまちまちな上に認識を揃えられる情報がなかったことが原因でした😢
一回目のモデリングは中断し、要件整理を改めてすることにしました🧑💻
要件整理の観点として「なぜこの要望があるのか?」について深掘りし、改めてドキュメントにまとめることで認識を揃えました。
イベントによって更新されるデータをカラムとして持つべきかが分からない
モデリングを進める中で、「ステータス変更イベント」がいくつか出てきました。
画面に表示したいのは、最新のステータスです。
最新のステータスはス「テータス変更イベント」の最新レコードから取得できるのですが、それをカラムとして持つべきかどうかが議論になりました🧐
ひとつの「ステータス変更イベント」の最新レコードを参照するのみであればカラムとして持つ必要はなさそうと判断できたのですが、今回は以下のようなケースでした(エンティティ名などすべて仮のものです)
複数のイベントからステータスを算出するものでした。
その場合カラムとして持つか、画面表示時に都度ふたつのテーブルを参照すべきか...🧐と悩みました。
結果カラムとしては持たず、イベントの最新レコードから都度算出することとなりました!
理由は下記です。
- ステータス算出ロジックは複雑でないので都度算出でも負荷にはならない
- 対象の項目(ステータス)は更新されることを前提にしている
- カラムとして持つことによる複雑性を避けたい(ステータスカラムとステータス変更履歴による二重管理のような状態になると複雑性が増す)
- そもそも対象のテーブルが持つカラムがすでに多すぎるため(100カラム以上)これ以上のカラム追加は必要最低限に抑えたい
学び
- 要件の意図を明確にする
- 要望の意図を理解することで適切な設計をしやすくなる
- 参考:https://qiita.com/hirokidaichi/items/61ad129eae43771d0fc3
- カラムを持たずイベントで管理するメリットとデメリット
- メリットデメリットを理解して、状況に合わせて選択すべき(常にカラムなしが最適というわけではない)
- メリット
- イベントはインサートとデリートのみでアップデートがないため処理が複雑になりにくい
- DBカラムのアップデートにロジックを持つと、ロジック変更になった際に対応が大変
- イベントから算出するだけだとロジックに変更があった場合にデータリペアが不要になる
- デメリット
- クエリにjoinが必要になる
- カラム追加するだけよりも実装工数が膨らむ
- 「日時があればイベントで管理でOK」は常に正しいとは限らない
- 更新頻度が低い場合は、イベントとして管理しても恩恵を受けにくいこともある
- 欲しいデータを表現しているカラムがすでにあるかつ頻繁に変更されないデータであれば、イベントで管理せずカラムで管理する方が適切かもしれない
- モデリングとしてはユーザーの行動をイベントとして残すのが適切だが、既存のテーブルの状態やデータ更新頻度を加味して考えるべき
感想
チームでひとつのタスクを進めるのって難しい
Discussion