MakingSenseofStreamProcessing / Event Sourcing From the DDD Community


イベントソーシング:DDDコミュニティより

要約

イベントソーシングという考えかたの紹介。

詳細

ここで少し話題を変えて、別の分野におけるよく似たアイデアを見てみよう。 イベントソーシングはDDDコミュニティから生まれたアイデアだ*1。エンタープライズソフトウェア開発者の間では有名だけど、ネット企業にはそれほど広まっていない。 独特の用語がやたら出てくるので戸惑うけど、アイデアとしてはなかなかよさげなものもある。

msos_0108.png

図1-8:イベントソーシングはDDDコミュニティでうまれたアイデア

ここではそれを、独特の用語をできるだけ使わずに説明してみたい。 先ほどのサンプルと驚くほどに似通ったところも見つかるだろう。

イベントソーシングは、データベース内でのデータ構造に関する考えかただ。 ここではショッピングサイトのカートを扱うデータベースを例に考えてみよう。 顧客ごとにさまざまな商品をカートに入れられるし、それぞれの商品を何個でもカートに入れられる。

msos_0109.png

図1-9:サンプルデータベース。一般的なリレーショナルスキーマでまとめたショッピングカート

ここで、顧客123がカートを更新したとしよう。商品999を1個だけ入れていたけどやっぱり3個欲しくなったことにする。 これをデータベースに記録しようとするなら、普通にUPDATE文を使うことだろう。 顧客123と商品999でマッチした行の数量を、1から3に更新すればいい。

msos_0110.png

図1-10:UPDATEクエリでカートを更新する

ここではリレーショナルデータモデルを使ったけど、そんなことはどうでもいい。 リレーショナルデータベースじゃなくても、やることはそんなに変わらないはずだ。 何かが変わったときには、その値を新しい値で上書きするということ。

しかしイベントソーシングの世界では、これはデータベース設計としてあまりよろしくないとされている。 データベースに対するあらゆる変更は、個別のレコードにすべきだという考えかたである。

たとえば図1-11は、ユーザーセッションの中で記録されたイベントの一例だ。 顧客123が商品888を1個カートに追加すると、AddedToCart?イベントが発生する。 次に、数量を3に変更したときに、UpdatedCartQuantity?イベントが発生する。 その後、顧客の気が変わって、数量を2に減らしてからチェックアウトした。

msos_0111.png

図1-11:ショッピングカート上のあらゆる変更を記録する

これらのアクションがすべて個別のイベントとして記録され、タイムスタンプつきでデータベースに追記されていく。

このようなデータ構造にすると、ショッピングカートに対するあらゆる変更がイミュータブルなイベント(すなわちファクト)になる。 最終的に数量を2に変更したのだとしても、あるタイミングでは数量が3だったという事実(ファクト)は変わらない。 データを上書きしてしまうと、かつては3だったこともあるという事実がデータベースから消えてしまう。 すべての変更をイミュータブルなイベントとして記録していけば、値を上書きするよりもリッチな情報を保持できるようになる。

msos_0112.png

図1-12:データベース上の値を直接書き換えるのではなく、イミュータブルなイベントとして書き込む

データベースへの書き込みで破壊的なステート変更をするのではなく、すべてをイミュータブルなイベントとして記録すべき。 これこそがイベントソーシングの本質だ。

担当者のつぶやき

『実践ドメイン駆動設計』でまるまる1章を割いている内容がコンパクトにまとまっていますね。あっちよりもよっぽどわかりやすいのでは……。

みんなの突っ込み