シンプルは作れる!イミュータブルデータモデルの真髄
JJUG CCC 2025 Spring で話したものです。
https://gyazo.com/3f5aa0d8b5c0d2c7e9619337e6a3b6f5
昨今の生成AIによって、偶有的な難しさは激減した。し、これからも減り続けることだろう。
https://gyazo.com/9a7c25b95ef3f3e7f731b7e21058285a
だが、本質的な難しさ(複雑さ)が変わるわけではない。
https://gyazo.com/183e6c4df16737b7ab8f61534f9fab2c
「本質的な複雑さ」とは何か? 本質的な複雑さにはどうアプローチすれば良い?
https://gyazo.com/ee629cd570af2b82961c7d5dcf7fc9e3
本質的な複雑さはどう設計しても変わらない。
https://gyazo.com/8ccf3d17f954710aa6f5cfbe44c820f5
すなわち本質的複雑さは保存法則がある。
https://gyazo.com/d1ceb9050d180ea339165fe2b619362f
だが、本質的複雑さはその度合いに応じてComplexとComplicatedの複雑さがある。Complexな状態では、本質的複雑さがどれだけ含まれているかが把握できないことがある。動かしてみないと分からない、動かしてみても分からないことも…
https://gyazo.com/21002ca8573c7bef755c834a3cdf85e1
したがって、データモデリングを通じて「時間と労力さえかければ理解可能」な状態にしておくことが重要。
https://gyazo.com/c82b4a066519b408908b48103abd02d7
Complicatedな状態に持っていくために、イミュータブルデータモデルでモデリングすると良い。
https://gyazo.com/cde43acc179972a5096e2412a1fb9434
このようなComplexのサインを見逃さず、データモデリングしよう。
https://gyazo.com/bcee7a58021d33015e4093a32ec0f44f
https://gyazo.com/9234c6edaf49dc86433adc4cbeb962db
https://gyazo.com/5bad23a4e56c53f312582b4249401d2e
FAQ
Q1. イミュータブルデータモデルはテーブル設計の指針なの?
No
あくまでも実装のことは一旦おいておき、要求の本質的な複雑さをデータモデリングを通じて明らかにすることが狙いです。
とはいえ、せっかくSimpleなエンティティを見出したのに、それらをまた混ぜこぜにして、1つのテーブルとして実装する意義は薄い(特にイベントエンティティ)。
なので、テーブル設計の指針とも言えなくもない(特にイベントエンティティ)
Q2. UPDATEを一切やらずにシステムは作れるのか?
「イベントエンティティに対して更新はしない」なので、通常は…
イベントエンティティは原則UPDATEしないように作ります。
リソースエンティティは通常UPDATEするように作ります。
Q3. クエリが大変になるのでは?
多数のテーブルに実装されるのは主にイベントエンティティ。
イベントエンティティについて複雑なクエリになるのは、ロングタームイベントパターンみたいなもの。
これは偶有的複雑さ(イベントの進行状態を表すエンティティ)を導入し、現実的な速度でSQLが実行できるように実装するのがおすすめ。
Q4. テーブル数が増えるので理解が困難になるのでは?
本質的複雑さは、どう実装しようが変わらない。少ないテーブル数の方が「分かりやすい」と感じるのであれば、要求の複雑さを過小にとらえているサイン。
多数のテーブルに実装されるのはイベントエンティティ。
イベントエンティティは、Bounded Contextに分割しやすいので、適切な分割統治すれば一度に把握すべきものは多くない。
実装にあたって、Complexな状態(いくつかの論理エンティティをまとめて1つのテーブルで実装する)にするのももちろんナシではないが、振る舞いの方にその皺寄せがいくことを忘れてはならない。
https://gyazo.com/a05b6b1a29029da2c7d0a4ce64f31e7c
Q5. 実際どこまでイベントを作るべきか?
全部が全部必要ではない。記録・保管にも金がかかる。
イベントがお金を産む
イベントの記録がないとお金を失うリスクがある
ような性質のものを優先的に考えるようにしよう。
Q6. イベントのデータ量がめちゃ増えてコスト嵩むのでは?
まずQ5の回答の通り、お金を産む・失うリスクがあるもの以外を記録しないようにしよう。
それから、これはどう設計してもトラフィックの多いイベントを記録していくと、データ量が膨大になるが、これは定期的にパージ(またはアーカイブ)するより他にない。
この時、イベントがComplexなエンティティになっていると、複数の業務調整が必要になるためパージの要件がまとまりにくい。Complicatedな状態にしておけば、パージの設計も比較的容易になるはずだ。