イベントソーシングとは?イベント履歴で状態を管理する設計手法を解説
イベントソーシングとは、アプリケーションの現在状態そのものを直接保存するのではなく、状態が変化した理由となる「出来事の履歴」を保存する設計手法です。たとえば、注文データを単に「現在の注文ステータス」として保存するのではなく、「注文が作成された」「支払いが完了した」「商品が発送された」「注文がキャンセルされた」といったイベントを時系列で保存し、その履歴から現在状態を再構築します。Martin Fowlerは、アプリケーション状態のすべての変更をイベントオブジェクトとして捕捉し、そのイベント自体を保存することがイベントソーシングの基本的な考え方だと説明しています。
この設計が重要になるのは、単なるデータ保存ではなく、システムの変化そのものを追跡したい場面が増えているからです。金融、EC、ゲーム、監査システム、マイクロサービス、AIエージェントの行動履歴管理などでは、「現在どうなっているか」だけでなく、「なぜその状態になったのか」を説明できることが重要になります。イベントソーシングは、状態の結果ではなく変化の過程を保存するため、履歴管理、監査、状態復元、非同期連携に強い設計として使われます。
一方で、イベントソーシングは万能な設計ではありません。通常の作成・読み取り・更新・削除型のデータ管理よりも考えることが多く、イベント設計、読み取りモデル、データ量、整合性、運用監視などの難易度が上がります。そのため、すべてのシステムに無理に導入するのではなく、履歴の価値が高い領域、監査が必要な領域、状態変化の追跡が重要な領域に適用することが重要です。
1. イベントソーシングとは?
イベントソーシングとは、アプリケーションの状態変更をイベントとして記録し、そのイベント履歴を正本として扱う設計手法です。通常のデータベース設計では、ユーザーや注文などの現在状態をテーブルに保存し、更新が発生すると値を上書きします。一方、イベントソーシングでは、上書きされた結果だけではなく、「何が起きたのか」というイベントを追加保存します。
イベントソーシングの特徴
| 項目 | 内容 |
|---|---|
| 中心概念 | 現在状態ではなく、状態変更イベントを保存する |
| 保存対象 | 注文作成、支払い完了、住所変更、キャンセルなどの出来事 |
| 状態の作り方 | 保存されたイベントを順番に再生して現在状態を再構築する |
| 強み | 監査性、履歴追跡、状態復元、イベント駆動連携に強い |
| 注意点 | 実装、設計、運用が通常のデータ更新型より複雑になりやすい |
1.1 イベント履歴を保存する設計
| 項目 | 内容 |
|---|---|
| 意味 | 状態変更をイベントとして記録し、履歴として保存する設計 |
| 保存するもの | 現在値ではなく、発生した出来事 |
| 例 | 注文作成、支払い完了、在庫確保、キャンセル |
| メリット | なぜ現在の状態になったのかを追跡できる |
| 注意点 | イベント名やイベント内容の設計が非常に重要になる |
イベント履歴を保存する設計とは、システムで発生した状態変更を「出来事」として記録し続けることです。たとえば、注文の状態を単に「発送済み」と保存するのではなく、「注文が作成された」「支払いが完了した」「出荷処理が開始された」「発送が完了した」という流れをイベントとして保存します。このように履歴を残すことで、現在の状態だけでは見えない変化の過程を後から確認できます。
この考え方は、監査やトラブル調査に非常に強いです。たとえば、ある注文がなぜキャンセルされたのか、誰がいつ変更したのか、どの処理を経由して現在状態になったのかを追跡できます。Microsoftのイベントソーシングパターンの説明でも、各イベントはオブジェクトに対する論理的な変更を表し、追加専用のストアに記録されると説明されています。(Microsoft Learn)
1.2 現在状態はイベントから再生成
| 項目 | 内容 |
|---|---|
| 意味 | 現在状態を直接保存するのではなく、イベントを順番に適用して作る |
| 方法 | イベント履歴を古い順に再生する |
| 例 | 注文作成 → 支払い完了 → 発送完了 = 現在の注文状態 |
| メリット | 任意の時点の状態を復元しやすい |
| 注意点 | イベント数が多くなると再構築コストが増える |
イベントソーシングでは、現在状態は保存されたイベントから再生成されます。たとえば、ユーザー残高を直接「10,000円」と保存するのではなく、「入金 15,000円」「支払い 3,000円」「手数料 2,000円」というイベントを順番に適用し、その結果として現在残高を計算します。この仕組みにより、現在値だけでなく、現在値に至るまでのすべての過程を保持できます。
ただし、イベントを毎回最初から再生して状態を作ると、イベント数が増えたときに処理が重くなります。そのため実務では、スナップショットと呼ばれる途中状態を保存したり、読み取り専用の投影データを用意したりして、性能を調整します。イベントソーシングは、履歴管理の強さと引き換えに、状態再構築の設計が必要になる手法です。
2. 従来型との違い
従来型のデータ管理では、現在の状態を中心に保存します。たとえば、ユーザー名が変更された場合、ユーザーテーブルの名前カラムを上書きします。この方法はシンプルで扱いやすい一方、過去にどのような値だったのか、いつ誰が変更したのか、変更の理由は何だったのかを別途ログとして残さない限り追跡しにくいです。
一方、イベントソーシングでは、現在状態ではなく変更イベントを保存します。現在状態はイベントの積み重ねから導き出されるため、履歴が自然に残ります。Microservices.ioでも、イベントソーシングは注文や顧客のような業務エンティティの状態を、状態変更イベントの並びとして永続化するパターンだと説明されています。(microservices.io)
従来型とイベントソーシングの比較
| 項目 | 作成・読み取り・更新・削除型 | イベントソーシング |
|---|---|---|
| 保存対象 | 現在のデータ | 状態変更イベント |
| 更新方法 | 既存データを上書き | 新しいイベントを追加 |
| 履歴 | 別途ログが必要 | イベント履歴として自然に残る |
| 状態復元 | 難しい場合がある | イベント再生で復元しやすい |
| 実装難易度 | 比較的低い | 高い |
| 向いている用途 | 一般的な業務データ管理 | 監査、履歴追跡、複雑な状態変化管理 |
2.1 作成・読み取り・更新・削除型
| 項目 | 内容 |
|---|---|
| 意味 | 現在のデータをテーブルに保存し、変更時に上書きする方式 |
| 代表例 | ユーザーテーブル、商品テーブル、注文テーブル |
| メリット | 実装が分かりやすく、検索しやすい |
| デメリット | 過去の変更履歴が残りにくい |
| 向いている場面 | 履歴より現在状態が重要な一般的な業務システム |
作成・読み取り・更新・削除型は、多くのアプリケーションで使われる一般的なデータ管理方式です。ユーザー情報を登録し、必要に応じて読み取り、変更があれば更新し、不要になれば削除します。この方式は理解しやすく、データベース設計や検索処理も比較的シンプルです。管理画面、商品マスタ、顧客情報、記事管理など、多くのシステムではこの方式で十分です。
しかし、値を上書きするため、過去の状態は失われやすくなります。もちろん、更新ログや監査ログを別途作れば履歴を残せますが、それは現在データとは別の補助的な仕組みになります。そのため、履歴そのものが重要なドメインでは、作成・読み取り・更新・削除型だけでは不十分になる場合があります。
2.2 イベントソーシング
| 項目 | 内容 |
|---|---|
| 意味 | 状態変更イベントを追加保存し、履歴から状態を再構築する方式 |
| 代表例 | 注文作成イベント、支払い完了イベント、キャンセルイベント |
| メリット | 変更履歴を完全に追跡しやすい |
| デメリット | 読み取りや状態再構築の設計が複雑になる |
| 向いている場面 | 金融、監査、注文履歴、分散システム、イベント駆動設計 |
イベントソーシングでは、データを上書きするのではなく、状態変更をイベントとして追加していきます。イベントは原則として過去の事実であるため、変更や削除を前提にせず、時系列で蓄積します。たとえば、注文がキャンセルされた場合も、注文レコードを単に「キャンセル済み」に更新するのではなく、「注文キャンセル済み」というイベントを追加します。
この方式では、現在状態はイベント履歴から導き出されます。そのため、過去の状態を再現したり、特定時点の状態を調べたり、別の読み取りモデルを後から作り直したりしやすくなります。一方で、イベント設計や読み取りモデルの管理が必要になるため、通常のデータ更新よりも設計難易度は高くなります。
3. イベントとは?
イベントとは、システム内で実際に発生した状態変更の記録です。イベントは「これから何かをしてください」という命令ではなく、「すでに何かが起きました」という事実を表します。この違いは非常に重要です。命令は失敗する可能性がありますが、イベントは過去に起きた事実として記録されます。
イベントソーシングでは、イベントの設計品質がシステム全体の品質に直結します。イベント名が曖昧だったり、イベントの粒度が大きすぎたり小さすぎたりすると、後から状態を再構築しにくくなります。そのため、イベントは業務上意味のある出来事として設計する必要があります。
イベントの基本整理
| 項目 | 内容 |
|---|---|
| 意味 | システム内で発生した状態変更の事実 |
| 形式 | イベント名、発生時刻、対象ID、変更内容、メタデータなど |
| 代表例 | ユーザー登録済み、注文作成済み、支払い完了済み |
| 特徴 | 過去に起きた事実として扱う |
| 設計ポイント | 業務上意味のある単位で命名する |
3.1 状態変更の記録
| 項目 | 内容 |
|---|---|
| 意味 | データや業務状態が変わったことを記録する |
| 例 | ユーザー登録済み、注文作成済み、支払い完了済み |
| 保存内容 | 対象ID、イベント種別、発生時刻、変更内容 |
| メリット | 変更の過程を後から追跡できる |
| 注意点 | イベントに必要な情報を不足なく含める必要がある |
イベントは、状態変更の記録です。たとえば、ユーザーが登録された場合は「ユーザー登録済み」、注文が作成された場合は「注文作成済み」、支払いが完了した場合は「支払い完了済み」というイベントを発生させます。このようなイベントを保存することで、システムは単に現在状態を持つだけでなく、状態変化の流れを理解できます。
イベントには、イベント名だけでなく、対象ID、発生時刻、変更内容、実行者、関連する取引IDなどの情報を含めることがあります。これらの情報が不足していると、後から状態を再構築したり、監査したりする際に困ります。イベントは一度保存されると長期的に使われるため、最初の設計が非常に重要です。
3.2 「何が起きたか」を表現
| 項目 | 内容 |
|---|---|
| 意味 | 命令ではなく、過去に発生した事実を表す |
| 命令の例 | 注文を作成せよ |
| イベントの例 | 注文が作成された |
| メリット | 事実として履歴に残しやすい |
| 注意点 | イベント名は過去形・完了形で表現するのが自然 |
イベントは「何をしろ」という命令ではなく、「何が起きたか」という事実を表します。たとえば、「注文を作成する」はコマンドであり、「注文が作成された」はイベントです。この違いを明確にしないと、イベントソーシングの設計が混乱します。
イベントは過去の事実なので、名前は「登録済み」「作成済み」「完了済み」「キャンセル済み」のように、完了した出来事として表現するのが自然です。これにより、イベント履歴を読んだときに、業務上何が起きたのかを時系列で理解しやすくなります。イベントソーシングでは、イベント名そのものが業務履歴の言語になります。
4. イベントソーシングの構造
イベントソーシングは、主にイベントストア、集約、投影という構成要素で成り立ちます。イベントストアは履歴を保存する場所であり、集約はイベントから業務状態を再構築する単位です。投影は、イベント履歴から検索や画面表示に適した読み取りデータを作る仕組みです。
イベントソーシングを理解するうえで重要なのは、書き込みモデルと読み取りモデルを分けて考えることです。イベントストアは正本としての履歴を保存しますが、画面表示や検索にはそのまま使いにくい場合があります。そのため、投影によって読み取り用のデータを別途生成することが多くなります。
イベントソーシングの構成要素
| 構成要素 | 役割 | 実務での意味 |
|---|---|---|
| イベントストア | イベント履歴を保存する | システム状態の正本になる |
| 集約 | イベントから業務状態を構築する | 注文、顧客、口座などの状態管理単位 |
| 投影 | 表示・検索用データを作る | 読み取りモデルや一覧画面を生成する |
4.1 イベントストア
| 項目 | 内容 |
|---|---|
| 意味 | イベント履歴を保存する専用の保存領域 |
| 役割 | 状態変更イベントを時系列で保持する |
| 特徴 | 追加専用として扱われることが多い |
| 代表例 | EventStoreDB、Kafka、データベース上のイベントテーブル |
| 注意点 | イベントの順序、整合性、永続性が重要 |
イベントストアは、イベントソーシングにおける中心的な保存場所です。通常のデータベースが現在状態を保存するのに対し、イベントストアは状態変更の履歴を保存します。Microsoftのイベントソーシングパターンでも、イベントは追加専用ストアに記録されると説明されています。(Microsoft Learn)
イベントストアでは、イベントの順序、永続性、重複防止、同時更新制御が重要になります。たとえば、注文に関するイベントの順序が入れ替わると、現在状態の再構築結果が変わってしまう可能性があります。また、同じイベントが二重に保存されると、残高や在庫数の計算に影響することがあります。そのため、イベントストアは単なるログ置き場ではなく、システム状態の正本として慎重に設計する必要があります。
4.2 集約
| 項目 | 内容 |
|---|---|
| 意味 | 関連する状態変更をまとめる業務単位 |
| 例 | 注文集約、顧客集約、口座集約 |
| 役割 | イベントを適用して現在状態を構築する |
| メリット | 業務ルールを一つのまとまりとして管理しやすい |
| 注意点 | 集約を大きくしすぎると複雑になる |
集約とは、関連する状態と業務ルールをまとめる単位です。たとえば、注文システムでは、注文作成、商品追加、支払い完了、キャンセルなどのイベントを注文集約に適用し、現在の注文状態を構築します。集約は、イベント履歴から現在状態を再構築し、その状態に対して次の操作が可能かどうかを判断します。
集約設計では、業務上の境界を適切に決めることが重要です。集約が大きすぎると、一つの処理に多くのイベントやルールが絡み、複雑になります。逆に小さすぎると、複数の集約をまたぐ整合性管理が難しくなります。イベントソーシングでは、集約がイベントの意味を受け止める中心になるため、ドメイン理解が非常に重要です。
4.3 投影
| 項目 | 内容 |
|---|---|
| 意味 | イベント履歴から読み取り用データを生成する仕組み |
| 役割 | 画面表示や検索に適したデータを作る |
| 例 | 注文一覧、売上集計、ユーザー履歴画面 |
| メリット | 読み取り性能を高めやすい |
| 注意点 | イベントストアとの整合性や遅延を考慮する必要がある |
投影とは、イベント履歴をもとに、画面表示や検索に適した読み取り用データを作ることです。イベントストアには状態変更の履歴が保存されていますが、そのままでは一覧画面や検索画面に使いにくい場合があります。たとえば、注文一覧画面では、注文ID、顧客名、現在ステータス、合計金額をすぐに表示したいですが、毎回イベントをすべて再生すると効率が悪くなります。
そこで、投影によって読み取りモデルを作ります。イベントが保存されるたびに、注文一覧用テーブルや売上集計用テーブルを更新し、画面表示ではその読み取りモデルを参照します。コマンド・クエリ責務分離と組み合わせる場合、書き込み側はイベントを保存し、読み取り側は投影されたデータを参照する構成になります。
5. 処理の流れ
イベントソーシングの処理は、コマンド受信、イベント生成、イベントストア保存、状態再構築という流れで理解できます。通常のデータ更新では、ユーザー操作によってテーブルを直接更新しますが、イベントソーシングでは、まず業務操作をコマンドとして受け取り、その結果としてイベントを生成し、イベント履歴に保存します。
この流れを理解すると、イベントソーシングが単なるログ保存ではないことが分かります。イベントは、システム状態を構築するための正本であり、後続処理、読み取りモデル、他サービス連携の起点にもなります。
イベントソーシングの処理フロー
| ステップ | 内容 | 実務上の意味 |
|---|---|---|
| コマンド受信 | ユーザー操作や外部要求を受け取る | 注文作成、支払い実行などの依頼 |
| イベント生成 | 業務ルールを通過した結果としてイベントを作る | 注文作成済み、支払い完了済み |
| イベントストア保存 | イベント履歴へ追加する | 状態変更の正本として残す |
| 状態再構築 | イベントを再生して状態を作る | 現在状態や読み取りモデルを生成する |
5.1 コマンド受信
| 項目 | 内容 |
|---|---|
| 意味 | ユーザー操作や外部要求を受け取ること |
| 例 | 注文作成依頼、支払い実行依頼、住所変更依頼 |
| 役割 | 処理を開始するきっかけになる |
| 注意点 | コマンドはまだ事実ではなく、拒否される可能性がある |
| 設計ポイント | 入力検証と業務ルール確認が必要 |
コマンド受信とは、ユーザーや外部システムから「何かを実行したい」という要求を受け取ることです。たとえば、ユーザーが購入ボタンを押した場合、それは「注文を作成したい」というコマンドになります。コマンドは命令や依頼であり、まだ実際に起きた事実ではありません。
イベントソーシングでは、コマンドを受け取った後、業務ルールを確認します。在庫があるか、支払い可能か、注文状態が変更可能かなどを判断し、問題がなければイベントを生成します。つまり、コマンドはイベントの前段階であり、イベントはコマンドが成功した結果として発生します。
5.2 イベント生成
| 項目 | 内容 |
|---|---|
| 意味 | コマンド処理の結果として、状態変更イベントを作ること |
| 例 | 注文作成済み、支払い完了済み、在庫確保済み |
| 役割 | システムで起きた事実を表す |
| 注意点 | イベントは過去の事実として設計する |
| 設計ポイント | イベント名と内容を業務上意味のある単位にする |
イベント生成とは、コマンドが業務ルールを満たした結果として、状態変更の事実を作ることです。たとえば、「注文を作成したい」というコマンドが成功した場合、「注文作成済み」というイベントが生成されます。イベントはすでに発生した事実であり、以後の状態再構築や他サービス連携の根拠になります。
イベント生成で重要なのは、イベントの粒度です。粒度が粗すぎると後から何が起きたのか分かりにくくなり、細かすぎるとイベント数が増えすぎて管理が難しくなります。たとえば、「注文更新済み」だけでは内容が曖昧ですが、「配送先変更済み」「支払い方法変更済み」のように業務上意味のある単位で分けると、後から履歴を理解しやすくなります。
5.3 イベントストア保存
| 項目 | 内容 |
|---|---|
| 意味 | 生成されたイベントを履歴として保存すること |
| 保存先 | イベントストア、イベントテーブル、専用DBなど |
| 役割 | システム状態の正本としてイベントを保持する |
| 注意点 | 順序、重複、永続性、整合性が重要 |
| 設計ポイント | 追加専用に近い形で安全に保存する |
イベントストア保存では、生成されたイベントを永続化します。イベントソーシングでは、保存されたイベントがシステム状態の正本になります。そのため、イベントを失うことは状態を失うことに近く、保存処理の信頼性が非常に重要です。
イベントストアには、専用のイベントストア製品を使う場合もあれば、リレーショナルデータベースやメッセージング基盤を組み合わせる場合もあります。EventStoreDBのドキュメントでは、EventStoreDBはイベントソーシング向けに設計されたデータベースだと説明されています。(Kurrent Docs)
5.4 状態再構築
| 項目 | 内容 |
|---|---|
| 意味 | 保存されたイベントを順番に適用して現在状態を作ること |
| 方法 | 対象集約のイベントを古い順に再生する |
| 例 | 注文作成 → 商品追加 → 支払い完了 → 発送完了 |
| メリット | 任意の時点の状態や現在状態を再現できる |
| 注意点 | イベント数が多い場合は性能対策が必要 |
状態再構築とは、イベント履歴を順番に適用して現在状態を作ることです。たとえば、注文集約であれば、注文作成イベントから始まり、商品追加、支払い完了、発送完了などのイベントを順番に適用することで、現在の注文状態を再現します。
この仕組みにより、過去の任意の時点の状態を再現したり、読み取りモデルを後から作り直したりできます。一方で、イベント数が多くなると毎回すべてを再生するのは重くなるため、スナップショットや投影を使って性能を調整します。状態再構築はイベントソーシングの強みであり、同時に設計上の重要な課題でもあります。
6. イベントソーシングのメリット
イベントソーシングのメリットは、完全な履歴管理、監査ログへの強さ、状態復元、イベント駆動設計との相性です。現在状態だけを保存する設計では、過去に何が起きたのかを後から追跡するには別途ログが必要になりますが、イベントソーシングでは履歴そのものがシステムの正本になります。
6.1 完全な履歴管理
イベントソーシングでは、状態変更がイベントとしてすべて保存されるため、過去の変化を時系列で追跡できます。たとえば、ある注文がどのような操作を経てキャンセルされたのか、ある口座残高がどの取引によって変化したのかを、イベント履歴から確認できます。
この履歴管理は、単なるログよりも業務的な意味を持ちます。ログは技術的な記録になりがちですが、イベントは業務上の出来事として設計されるため、後から人間が読んでも意味を理解しやすいです。履歴そのものが価値になるシステムでは、イベントソーシングの強みが大きくなります。
6.2 監査ログに強い
監査が必要なシステムでは、誰が、いつ、何を変更したのかを説明できることが重要です。イベントソーシングでは、状態変更イベントが時系列で保存されるため、監査ログとして利用しやすい構造になります。金融、会計、注文管理、権限変更、契約管理などでは、この性質が大きな価値を持ちます。
ただし、イベントソーシングを導入しただけで監査要件を完全に満たせるわけではありません。イベントに実行者、発生時刻、関連ID、変更理由、リクエスト元などのメタデータを適切に含める必要があります。監査ログとして使う場合は、イベント設計の段階で監査要件を考慮することが重要です。
6.3 状態復元が可能
イベントソーシングでは、イベント履歴を再生することで状態を復元できます。たとえば、システム障害やデータ破損が発生した場合でも、イベント履歴が残っていれば、読み取りモデルや現在状態を再構築できる可能性があります。この性質は、長期運用システムにおいて大きな安心材料になります。
また、状態復元は障害対応だけでなく、分析や検証にも使えます。過去のある時点に戻って、その時点での状態を再現し、なぜ特定の判断が行われたのかを確認できます。これは、単に現在データだけを保存する設計では実現しにくいメリットです。
6.4 イベント駆動設計と相性が良い
イベントソーシングは、イベント駆動アーキテクチャと非常に相性が良いです。イベントが発生したら、それを他のサービスへ通知し、在庫更新、メール送信、分析処理、通知処理などを非同期に実行できます。Microservices.ioでも、イベントソーシングは状態を更新しながらイベントを発行するための関連パターンとして位置づけられています。(microservices.io)
この構成では、サービス同士が直接強く依存せず、イベントを通じて連携できます。たとえば、注文サービスが「注文作成済み」イベントを発行し、在庫サービス、通知サービス、分析サービスがそれぞれ必要な処理を行います。これにより、分散システムで疎結合な設計を作りやすくなります。
7. デメリット
イベントソーシングには大きなメリットがありますが、実装が複雑で、学習コストが高く、データ量が増え、イベント設計が難しいという課題もあります。履歴管理が強いからといって、すべてのシステムに導入すべきではありません。現在状態だけで十分なシステムに導入すると、不要な複雑性を持ち込む可能性があります。
7.1 実装が複雑
イベントソーシングは、通常のデータ更新型よりも実装が複雑です。イベントストア、集約、投影、読み取りモデル、スナップショット、イベントバージョン管理、再処理など、考える要素が多くなります。単純な登録・更新・削除だけの業務では、作成・読み取り・更新・削除型の方が簡単で保守しやすい場合が多いです。
実務では、イベントソーシングの一部だけを適用する選択もあります。たとえば、全システムではなく、監査が重要な注文履歴や決済履歴だけイベントソーシングにする方法です。Martin Fowlerも、イベントソーシングはシステム全体に適用しなければならないわけではなく、会計のような強い監査が必要な部分で使われることが多いと述べています。(martinfowler.com)
7.2 学習コストが高い
イベントソーシングは、従来のデータベース設計に慣れている開発者にとって、考え方の転換が必要です。現在状態を保存するのではなく、過去の出来事から状態を作るという発想に慣れるまで時間がかかります。また、コマンド、イベント、集約、投影、コマンド・クエリ責務分離など、関連概念も多くあります。
チーム全体がこの考え方を理解していないと、イベント名の付け方がばらついたり、イベントに現在状態を詰め込みすぎたり、読み取りモデルとイベントストアの責務が混ざったりします。イベントソーシングは、技術選定だけでなく、チームの設計力と共通理解が必要な手法です。
7.3 データ量増加
イベントソーシングでは、状態変更をすべてイベントとして保存するため、データ量が増えやすくなります。現在状態だけを保存する方式では1レコードで済む場合でも、イベントソーシングでは数十、数百、数千のイベントが蓄積されることがあります。
このデータ量増加に対応するには、保存期間、アーカイブ、スナップショット、読み取りモデル、イベント圧縮などの設計が必要です。ただし、イベントはシステム状態の正本であるため、安易に削除できません。データ量と監査要件、復元要件のバランスを考えることが重要です。
7.4 イベント設計が難しい
イベントソーシングで最も難しい部分の一つがイベント設計です。イベント名、粒度、含めるデータ、バージョン管理、将来の変更への対応を考える必要があります。イベントは長期間保存され、後から再生されるため、一度設計したイベント形式を簡単に変更できない場合があります。
イベント設計が悪いと、後から状態を再構築しにくくなったり、読み取りモデルを作りにくくなったりします。たとえば、「更新済み」という曖昧なイベントでは、何が更新されたのか分かりません。イベントは、業務上の意味を持つ事実として、明確な名前と十分なデータを持たせる必要があります。
8. コマンド・クエリ責務分離との関係
コマンド・クエリ責務分離とは、データの更新処理と読み取り処理を分ける設計パターンです。イベントソーシングでは、書き込み側はイベントを保存し、読み取り側は投影された読み取りモデルを参照する構成になることが多いため、コマンド・クエリ責務分離と組み合わせて使われることがよくあります。
Microsoftのコマンド・クエリ責務分離パターンの説明では、読み取り操作と書き込み操作を別々のデータモデルに分離することで、それぞれを独立して最適化できるとされています。(Microsoft Learn)
8.1 コマンド・クエリ責務分離とは?
| 項目 | 内容 |
|---|---|
| 意味 | 更新処理と読み取り処理を分離する設計 |
| コマンド | 状態を変更する操作 |
| クエリ | 状態を読み取る操作 |
| メリット | 書き込みと読み取りを別々に最適化できる |
| 注意点 | データ同期や結果整合性を考慮する必要がある |
コマンド・クエリ責務分離とは、書き込み処理と読み取り処理を明確に分ける設計です。たとえば、注文を作成する、支払いを完了する、住所を変更するような処理はコマンドです。一方、注文一覧を表示する、売上集計を見る、顧客履歴を確認する処理はクエリです。
通常のシステムでは、同じデータモデルを更新にも検索にも使うことが多いですが、複雑なシステムではこれが問題になる場合があります。書き込みに最適な構造と、読み取りに最適な構造は必ずしも同じではありません。コマンド・クエリ責務分離を使うことで、書き込み側は整合性や業務ルールを重視し、読み取り側は検索性能や表示しやすさを重視できます。
8.2 イベントソーシングと組み合わせ
| 項目 | 内容 |
|---|---|
| 書き込み側 | コマンドを処理し、イベントを保存する |
| 読み取り側 | 投影された読み取りモデルを参照する |
| メリット | 履歴管理と高速な読み取りを両立しやすい |
| 注意点 | イベント反映に遅延が発生する場合がある |
| 向いている場面 | 複雑な業務状態、監査、分散システム |
イベントソーシングとコマンド・クエリ責務分離を組み合わせると、書き込み側ではイベントを保存し、読み取り側では投影されたデータを参照する構成になります。たとえば、注文作成イベントを保存した後、注文一覧用の読み取りモデルを更新します。画面表示ではイベントストアを直接読むのではなく、読み取りやすい形に加工されたデータを使います。
この組み合わせにより、履歴管理の強さと読み取り性能を両立しやすくなります。ただし、イベントストアに保存されたイベントが読み取りモデルに反映されるまでに遅延が発生する場合があります。そのため、ユーザー体験や業務要件に応じて、結果整合性をどの程度許容できるかを設計する必要があります。
9. ユースケース
イベントソーシングは、履歴が価値を持つ領域に向いています。金融システム、ECサイト、ゲーム、監査システムなどでは、「現在どうなっているか」だけでなく、「どのような経緯でそうなったか」が重要になります。逆に、単純なマスタ管理や履歴が重要でないデータでは、イベントソーシングは過剰な設計になる場合があります。
9.1 金融システム
| 項目 | 内容 |
|---|---|
| 活用場面 | 取引履歴、残高管理、送金履歴、会計処理 |
| 保存するイベント | 入金済み、出金済み、送金完了済み、手数料発生済み |
| メリット | 残高の根拠を履歴から説明できる |
| 注意点 | 整合性、順序、監査要件が非常に重要 |
| 向いている理由 | 変更履歴そのものが業務価値を持つため |
金融システムでは、現在の残高だけでなく、その残高に至るまでの取引履歴が非常に重要です。たとえば、口座残高が10万円であることだけでなく、どの入金、出金、手数料、振込によってその残高になったのかを説明できる必要があります。このような領域では、イベントソーシングの考え方が自然に合います。
ただし、金融領域ではデータ整合性と監査性が非常に重要です。イベントの順序が変わったり、二重に処理されたりすると重大な問題になります。そのため、イベントソーシングを使う場合でも、トランザクション制御、重複排除、監査メタデータ、アクセス制御を厳密に設計する必要があります。
9.2 ECサイト
| 項目 | 内容 |
|---|---|
| 活用場面 | 注文履歴、在庫変更、支払い、配送、キャンセル |
| 保存するイベント | 注文作成済み、商品追加済み、支払い完了済み、発送済み |
| メリット | 注文状態の変化を追跡しやすい |
| 注意点 | すべてのEC機能に適用すると複雑になりすぎる |
| 向いている理由 | 注文や決済の履歴追跡が重要なため |
ECサイトでは、注文の状態が複数の段階を経て変化します。注文作成、在庫確保、支払い完了、発送、配送完了、返品、キャンセルなど、多くのイベントが発生します。これらを履歴として保存しておくと、顧客問い合わせやトラブル対応で、注文がどの段階で問題になったのかを確認しやすくなります。
一方で、ECサイトのすべてのデータにイベントソーシングを適用する必要はありません。商品マスタやカテゴリ管理のような単純なデータは、通常の作成・読み取り・更新・削除型で十分な場合もあります。実務では、注文や決済など履歴価値が高い部分に限定して使う判断が重要です。
9.3 ゲーム
| 項目 | 内容 |
|---|---|
| 活用場面 | プレイヤー行動履歴、アイテム取得、スコア変化、対戦履歴 |
| 保存するイベント | アイテム獲得済み、レベル上昇済み、クエスト完了済み |
| メリット | プレイヤー行動を詳細に分析できる |
| 注意点 | イベント数が非常に多くなりやすい |
| 向いている理由 | 行動履歴が分析や不正検知に役立つため |
ゲームでは、プレイヤーの行動履歴が非常に価値を持ちます。アイテム獲得、レベルアップ、クエスト完了、課金、対戦結果などをイベントとして保存すれば、ユーザー体験の分析、不正検知、バランス調整、リプレイ機能に活用できます。
ただし、ゲームはイベント数が非常に多くなりやすいため、すべてを永続的なイベントソーシングとして扱うとデータ量が膨大になります。そのため、重要な状態変更と分析用ログを分けたり、保存期間や集計方法を設計したりする必要があります。イベントソーシングを使う場合は、業務価値のあるイベントに絞ることが重要です。
9.4 監査システム
| 項目 | 内容 |
|---|---|
| 活用場面 | 権限変更、設定変更、承認履歴、操作履歴 |
| 保存するイベント | 権限付与済み、設定変更済み、承認完了済み |
| メリット | 誰がいつ何を変更したか追跡しやすい |
| 注意点 | 改ざん防止やアクセス制御が重要 |
| 向いている理由 | 履歴そのものが監査証跡になるため |
監査システムでは、変更履歴そのものが重要なデータになります。誰がいつ権限を変更したのか、どの設定がいつ変更されたのか、どの承認フローを通ったのかを後から説明できる必要があります。イベントソーシングは、これらの変更を時系列で保存するため、監査証跡として使いやすい構造です。
ただし、監査用途で使う場合は、イベントが改ざんされないこと、適切なメタデータが含まれていること、アクセス権限が管理されていることが重要です。単にイベントを保存するだけではなく、監査要件を満たす保存方法や運用ルールを設計する必要があります。
10. マイクロサービスとの関係
イベントソーシングは、マイクロサービスやイベント駆動アーキテクチャと相性が良い設計です。マイクロサービスでは、各サービスが独立したデータを持ち、他サービスと疎結合に連携することが求められます。イベントを通じて状態変更を伝えることで、サービス間の直接依存を減らしやすくなります。
10.1 イベント駆動アーキテクチャ
イベント駆動アーキテクチャでは、サービスがイベントを発行し、他のサービスがそのイベントを受け取って処理します。イベントソーシングでは、状態変更がイベントとして保存されるため、そのイベントを他サービス連携の起点として使いやすくなります。たとえば、注文サービスが「注文作成済み」イベントを発行し、在庫サービス、通知サービス、分析サービスがそれぞれ処理を行います。
この構成では、注文サービスが在庫サービスや通知サービスを直接呼び出す必要がなくなります。イベントを通じて連携するため、サービス同士の結合度を下げられます。Microservices.ioでも、イベント駆動アーキテクチャに関連するパターンとしてイベントソーシングが挙げられています。(microservices.io)
10.2 非同期連携
イベントソーシングは、非同期連携と相性が良いです。イベントが保存された後、別の処理が非同期にイベントを購読し、必要な処理を進められます。たとえば、注文が作成された後、メール送信、在庫更新、売上集計、レコメンド更新などを別々のサービスが処理できます。
非同期連携のメリットは、ユーザー操作を待たせずに後続処理を進められることです。一方で、処理の順序、再試行、失敗時の補償、結果整合性を考える必要があります。イベントソーシングは非同期処理に向いていますが、分散システム特有の難しさも伴います。
10.3 分散システムとの相性
分散システムでは、複数のサービスが独立して動作し、それぞれが異なるデータを管理します。このとき、すべてのサービスが同じデータベースを直接更新すると、結合度が高くなり、変更に弱い構造になります。イベントソーシングを使うと、状態変更をイベントとして扱い、必要なサービスがそれを購読する形にできます。
ただし、分散システムでイベントソーシングを使う場合、結果整合性を受け入れる設計が必要です。あるサービスでイベントが保存されても、別サービスの読み取りモデルに反映されるまでには時間差が発生することがあります。この遅延をUXや業務上どこまで許容できるかを設計することが重要です。
11. よく使われる技術
イベントソーシングでは、イベントストアやメッセージング基盤、フレームワークが使われます。代表的な技術には、Kafka、EventStoreDB、RabbitMQ、Axon Frameworkなどがあります。ただし、これらは役割が異なるため、すべてが同じ用途で使われるわけではありません。
11.1 Kafka
Kafkaは、大量のイベントやメッセージを処理するための分散ストリーミング基盤として使われます。イベントソーシングそのものの専用データベースではありませんが、イベント駆動アーキテクチャやイベント配信基盤として利用されることがあります。注文イベント、ログイベント、ユーザー行動イベントなどを複数サービスへ配信する用途に向いています。
ただし、Kafkaをイベントストアとして使う場合は、保持期間、イベントの再処理、スキーマ管理、順序保証、永続性要件を慎重に設計する必要があります。Kafkaは強力なイベント基盤ですが、イベントソーシングのドメイン状態管理をすべて自動で解決するわけではありません。
11.2 EventStoreDB
EventStoreDBは、イベントソーシング向けに設計されたデータベースとして知られています。EventStoreDBのドキュメントでは、イベントソーシングのために設計されたデータベースであり、関連する概念や運用上の関心事を扱うと説明されています。(Kurrent Docs)
EventStoreDBは、イベントストリーム、イベント順序、購読、投影など、イベントソーシングに必要な考え方を扱いやすい形で提供します。イベントソーシングを本格的に導入する場合、通常のリレーショナルデータベースで自作するよりも、専用DBの方が設計しやすい場面があります。ただし、導入には学習コストもあるため、チームの技術理解が必要です。
11.3 RabbitMQ
RabbitMQは、メッセージキューとして使われる技術です。イベントソーシングのイベントストアそのものというより、イベントやメッセージを非同期に配信するために使われることが多いです。たとえば、注文作成イベントを受け取った後、通知処理や在庫更新処理を非同期で実行する構成に利用できます。
RabbitMQは、タスクキューやサービス間連携に向いていますが、イベント履歴を長期間保存して状態を再構築する用途には、別途イベントストアを用意することが多くなります。イベントソーシングでは、イベントの永続保存とイベント配信を分けて考えることが重要です。
11.4 Axon Framework
Axon Frameworkは、Java系のアプリケーションでコマンド・クエリ責務分離やイベントソーシングを実装するために使われるフレームワークです。コマンド、イベント、集約、イベントハンドラ、読み取りモデルなどの構造を扱いやすくするための仕組みを提供します。
フレームワークを使うメリットは、イベントソーシングの典型的な構造を標準化しやすいことです。ただし、フレームワークを導入するだけで良い設計になるわけではありません。イベント設計、集約設計、読み取りモデル設計、運用設計は開発チームが理解して行う必要があります。
12. AI時代との関係
AI時代においても、イベントソーシングの考え方は重要になります。AIエージェントや生成AIアプリでは、ユーザー入力、モデル応答、ツール実行、判断結果、フィードバックなど、多くの出来事が時系列で発生します。これらを履歴として管理できれば、AIの動作分析、改善、監査、再現性確保に役立ちます。
12.1 AI行動履歴管理
AIシステムでは、ユーザーからの入力、AIの判断、参照したデータ、呼び出したツール、生成した回答を履歴として残すことが重要になります。単に最終回答だけを保存しても、なぜその回答になったのかを後から説明できません。イベントソーシング的な考え方を使えば、AIシステムの行動履歴を時系列で管理しやすくなります。
これは、AI品質改善にも役立ちます。どの入力で誤回答が発生したのか、どの参照データを使ったのか、どのツール呼び出しが失敗したのかを追跡できれば、プロンプト改善やデータ改善につなげられます。AI時代には、AIの出力だけでなく、出力に至る過程を記録することが重要になります。
12.2 エージェント行動追跡
AIエージェントは、複数のステップを通じてタスクを実行します。たとえば、目標を理解し、計画を立て、検索を行い、ツールを呼び出し、結果を評価し、最終回答を生成します。この一連の行動をイベントとして記録すれば、エージェントがどのように判断したのかを後から追跡できます。
エージェント行動追跡は、安全性や監査性の観点でも重要です。AIが誤ったツールを呼び出した場合、どのイベントの時点で問題が起きたのかを確認できます。今後、AIエージェントが業務処理を担う場面が増えるほど、イベント履歴による追跡の重要性は高まります。
12.3 推論履歴分析
生成AIや機械学習モデルでは、推論履歴を分析することで、品質改善や異常検知ができます。どの入力に対してどのモデルがどのような出力を返したのか、ユーザーがその結果をどう評価したのかを保存すれば、モデル改善やプロンプト改善に利用できます。
推論履歴は、単なるログとして保存するだけでなく、イベントとして構造化しておくと分析しやすくなります。たとえば、「ユーザー質問受信」「検索結果取得」「モデル回答生成」「ユーザー低評価」というイベントを保存すれば、回答品質低下の原因を調べやすくなります。
12.4 リアルタイム分析基盤
イベントソーシングやイベント駆動の考え方は、リアルタイム分析基盤とも相性があります。AIアプリで発生する入力、回答、評価、エラー、ツール実行などをイベントとして流せば、リアルタイムに品質監視や異常検知を行えます。
たとえば、特定のプロンプトで急に低評価が増えた場合や、特定のモデルで応答遅延が増えた場合に、イベントデータをもとに検知できます。AIシステムが複雑化するほど、イベント履歴を使った観測性と分析基盤が重要になります。
13. 本質
イベントソーシングの本質は、データの現在状態ではなく、状態が変化した出来事そのものを中心にシステムを設計することです。通常のデータ設計では、現在値が主役になります。しかしイベントソーシングでは、現在値はイベント履歴から導き出される結果であり、本当に重要なのは「何が起きたか」という履歴です。
13.1 「状態」ではなく「履歴」を保存する
イベントソーシングでは、現在の状態を直接保存するのではなく、状態を変化させた履歴を保存します。この考え方により、現在状態だけでは見えない業務の流れや意思決定の過程を記録できます。たとえば、注文がキャンセル済みであることだけでなく、いつ作成され、いつ支払われ、なぜキャンセルされたのかまで追跡できます。
この設計では、履歴が単なる補助ログではなく、システム状態の正本になります。Martin Fowlerも、イベントストアが主要な真実の源となり、システム状態はそこから派生すると説明しています。(martinfowler.com)
13.2 システムを時系列で理解する設計
イベントソーシングは、システムを時系列で理解するための設計です。現在のデータだけを見ると、そこに至るまでの過程は分かりません。しかしイベント履歴を見れば、状態がどのように変化したのかを順番に追えます。
これはトラブル調査や監査だけでなく、業務理解にも役立ちます。ユーザーがどのような行動を取り、システムがどのように反応し、どの段階で問題が起きたのかを時系列で確認できます。イベントソーシングは、システムを静的なデータ集合ではなく、時間とともに変化するプロセスとして捉える設計です。
13.3 変更そのものが価値になる
通常のデータ管理では、変更は現在状態を更新するための手段です。しかしイベントソーシングでは、変更そのものが価値を持ちます。誰が、いつ、何を、なぜ変更したのかという情報は、監査、分析、改善、復元に使える重要な資産になります。
この考え方は、金融、会計、EC、ゲーム、AI行動履歴などで特に重要です。現在値だけでは説明できない情報が、イベント履歴には残ります。イベントソーシングは、変化の過程をデータ資産として扱う設計です。
13.4 イベント駆動時代の状態管理
イベント駆動アーキテクチャでは、システム内の出来事がサービス間連携の起点になります。イベントソーシングは、その出来事を永続化し、状態管理の中心に置く設計です。つまり、イベント駆動が「イベントで処理を動かす」考え方だとすれば、イベントソーシングは「イベントで状態を管理する」考え方です。
この組み合わせにより、履歴管理と非同期連携を両立しやすくなります。ただし、イベントの順序、重複、結果整合性、読み取りモデルの遅延など、分散システム特有の問題も出てきます。そのため、イベントソーシングは強力ですが、設計力が求められる手法です。
13.5 「データ」ではなく「出来事」が中心
イベントソーシングの最も重要な本質は、「データ」ではなく「出来事」が中心になることです。ユーザーが登録された、注文が作成された、支払いが完了した、権限が変更された、AIが回答を生成したといった出来事を中心にシステムを捉えます。
この考え方により、システムは単なる現在状態の保存場所ではなく、業務活動の履歴を保持する構造になります。イベントソーシングは、状態を保存する設計ではなく、システムの出来事を記録し、その出来事から状態と意味を作る設計です。
おわりに
イベントソーシングは、現在の状態ではなく、状態変化を引き起こした「イベントの履歴」を保存する設計手法です。通常のCRUD型データ管理では、最新状態のみを保持することが一般的ですが、イベントソーシングでは「何が起きたのか」という出来事そのものを記録します。その履歴を積み重ねることで、任意の時点の状態を再構築できるため、監査、履歴管理、状態復元、分散システム連携に強い特徴があります。金融取引やユーザー行動履歴など、「変化の過程」に価値がある領域で特に有効な設計です。
一方で、イベントソーシングは実装や運用が複雑になりやすいという課題もあります。イベントストア、集約、投影、読み取りモデル、CQRS、結果整合性など、多くの概念を理解しながら設計する必要があります。単純なCRUDシステムと比較すると、データの流れや整合性管理が複雑になりやすく、導入コストも高くなります。そのため、すべての機能へ適用するのではなく、履歴の価値が高い領域や、監査・追跡が重要な領域に限定して導入することが現実的です。適切な境界を見極めることが、イベントソーシング設計では非常に重要になります。
イベントソーシングの本質は、「現在のデータ」ではなく、「どのような出来事が積み重なって現在に至ったのか」を中心にシステムを理解することにあります。イベント駆動アーキテクチャやマイクロサービス、AI行動履歴管理が重要になる時代において、この考え方はますます価値を持つようになります。単なるデータ保存技術ではなく、状態管理と履歴管理を統合的に扱うための設計思想として理解することが重要です。
EN
JP
KR