イベントソーシングという考えかたの紹介。
ここで少し話題を変えて、別の分野におけるよく似たアイデアを見てみよう。 イベントソーシングはDDDコミュニティから生まれたアイデアだ*1。エンタープライズソフトウェア開発者の間では有名だけど、ネット企業にはそれほど広まっていない。 独特の用語がやたら出てくるので戸惑うけど、アイデアとしてはなかなかよさげなものもある。
図1-8:イベントソーシングはDDDコミュニティでうまれたアイデア
ここではそれを、独特の用語をできるだけ使わずに説明してみたい。 先ほどのサンプルと驚くほどに似通ったところも見つかるだろう。
イベントソーシングは、データベース内でのデータ構造に関する考えかただ。 ここではショッピングサイトのカートを扱うデータベースを例に考えてみよう。 顧客ごとにさまざまな商品をカートに入れられるし、それぞれの商品を何個でもカートに入れられる。
図1-9:サンプルデータベース。一般的なリレーショナルスキーマでまとめたショッピングカート
ここで、顧客123がカートを更新したとしよう。商品999を1個だけ入れていたけどやっぱり3個欲しくなったことにする。 これをデータベースに記録しようとするなら、普通にUPDATE文を使うことだろう。 顧客123と商品999でマッチした行の数量を、1から3に更新すればいい。
図1-10:UPDATEクエリでカートを更新する
ここではリレーショナルデータモデルを使ったけど、そんなことはどうでもいい。 リレーショナルデータベースじゃなくても、やることはそんなに変わらないはずだ。 何かが変わったときには、その値を新しい値で上書きするということ。
しかしイベントソーシングの世界では、これはデータベース設計としてあまりよろしくないとされている。 データベースに対するあらゆる変更は、個別のレコードにすべきだという考えかたである。
たとえば図1-11は、ユーザーセッションの中で記録されたイベントの一例だ。 顧客123が商品888を1個カートに追加すると、AddedToCart?イベントが発生する。 次に、数量を3に変更したときに、UpdatedCartQuantity?イベントが発生する。 その後、顧客の気が変わって、数量を2に減らしてからチェックアウトした。
図1-11:ショッピングカート上のあらゆる変更を記録する
これらのアクションがすべて個別のイベントとして記録され、タイムスタンプつきでデータベースに追記されていく。
このようなデータ構造にすると、ショッピングカートに対するあらゆる変更がイミュータブルなイベント(すなわちファクト)になる。
最終的に数量を2に変更したのだとしても、あるタイミングでは数量が3だったという
図1-12:データベース上の値を直接書き換えるのではなく、イミュータブルなイベントとして書き込む
データベースへの書き込みで破壊的なステート変更をするのではなく、すべてをイミュータブルなイベントとして記録すべき。 これこそがイベントソーシングの本質だ。
『実践ドメイン駆動設計』でまるまる1章を割いている内容がコンパクトにまとまっていますね。あっちよりもよっぽどわかりやすいのでは……。