イベントソーシングとは? ― データを「結果」ではなく「出来事」で記録する設計
イベントソーシング(Event Sourcing)とは、アプリケーションの状態変化を「イベント」という不変の記録として時系列に蓄積し、現在の状態はそれらのイベントを再生して導出する設計パターンです。従来のCRUD方式がデータの「現在の姿」だけを上書き保存するのに対し、イベントソーシングは「何が起きたか」の履歴をすべて保持します。
銀行の通帳をイメージするとわかりやすいでしょう。通帳には「入金 5,000円」「出金 2,000円」「振込 10,000円」と取引(イベント)が順番に記録されています。現在の残高はこれらの取引を上から順に計算すれば求められます。イベントソーシングはこの「通帳方式」をシステム設計に応用したものです。
なぜ従来のCRUDでは不十分なのか
一般的なWebアプリケーションでは、データベースのレコードを直接更新(UPDATE)します。たとえばECサイトの注文ステータスを「処理中→発送済み」に変えると、「処理中」だった事実はデータベースから消えてしまいます。
これは多くのケースで問題になりませんが、以下のような場面では深刻な課題を引き起こします。
監査とコンプライアンス:金融系システムでは「いつ・誰が・何を変更したか」の完全な履歴が法的に求められます。UPDATEで上書きしてしまうと、この証跡を失います。
バグの原因調査:「なぜこのデータがおかしくなったのか」を調べたいとき、変更履歴がなければ原因の特定は困難です。
ビジネスインサイトの喪失:ユーザーが「カートに追加→削除→再追加→購入」した行動パターンは、最終結果だけ見ても読み取れません。
イベントソーシングの仕組み ― イベントストアと状態の再構築
イベントソーシングの中核はイベントストア(Event Store)と呼ばれる追記専用のデータストアです。すべての状態変化はイベントとしてイベントストアに書き込まれ、一度書き込まれたイベントは変更も削除もされません。
たとえばECサイトの注文処理では、次のようなイベントが順に記録されます。
① OrderCreated(注文作成)→ ② PaymentReceived(入金確認)→ ③ ItemShipped(商品発送)→ ④ OrderCompleted(注文完了)
現在の注文状態を知りたいときは、その注文に関するイベントを最初から順に「再生(リプレイ)」して状態を組み立てます。これをプロジェクションと呼びます。
イベントソーシングとCQRSの関係
イベントソーシングは、しばしばCQRS(Command Query Responsibility Segregation)と組み合わせて使われます。CQRSは「データの書き込み」と「データの読み取り」を別々のモデルに分離するパターンです。
イベントソーシングで書き込み側(コマンド側)はイベントを記録し、読み取り側(クエリ側)はイベントから構築されたビュー(リードモデル)を参照します。この組み合わせにより、書き込みは追記のみで高速、読み取りは最適化されたビューで高速、という両立が可能になります。
ただし、CQRSなしでイベントソーシングを使うことも、イベントソーシングなしでCQRSを使うことも可能です。両者は独立した概念であり、常にセットで使う必要はありません。
メリットとデメリットを正直に比較
| 観点 | メリット | デメリット |
|---|---|---|
| データの完全性 | すべての変更履歴が残り、監査やデバッグが容易 | イベント数が膨大になり、ストレージコストが増加 |
| 柔軟性 | 過去のイベントから新しいビューを後から構築できる | イベントスキーマの変更(バージョニング)が複雑 |
| パフォーマンス | 書き込みは追記のみで高速 | 状態の再構築にイベント再生が必要(スナップショットで緩和可能) |
| 開発難易度 | ドメインイベントがビジネスプロセスを自然に表現 | 学習コストが高く、CRUDに慣れた開発者には馴染みにくい |
| 結果整合性 | マイクロサービス間の疎結合を実現しやすい | 「結果整合性」を許容する設計が必要で、即時一貫性が求められる場面には不向き |
どんなシステムに向いているか
向いているケース:金融取引システム(完全な監査証跡が必要)、ECサイトの注文管理(複雑な状態遷移がある)、IoTデータの蓄積(大量のセンサーイベントを時系列で記録)、ゲームのリプレイ機能(操作履歴からゲーム状態を再現)。
向いていないケース:単純なCRUDアプリケーション(ブログやToDoリストなど)、リアルタイム性が極めて重要なシステム(結果整合性が許容できない場合)、小規模で変更頻度が低いシステム(設計の複雑さに見合わない)。
よくある質問(FAQ)
Q. イベントが増え続けるとパフォーマンスは大丈夫ですか?
A. 定期的に「スナップショット」を保存することで対処します。スナップショットはある時点の状態を丸ごと保存したもので、再生時はスナップショット以降のイベントだけを処理すれば済みます。
Q. イベントの形式を後から変えたいときはどうしますか?
A. イベントのバージョニングで対応します。新しいバージョンのイベントを定義し、古いイベントを読み込む際にアップキャスト(変換)する仕組みを用意します。
Q. イベントソーシングを実装するためのフレームワークはありますか?
A. Java/Kotlinでは Axon Framework、C#では EventStoreDB + Marten、Node.jsでは NestJS の CQRS モジュールなどが代表的です。
まとめ
イベントソーシングは「何が起きたか」を忠実に記録し続ける設計パターンです。監査証跡・柔軟なデータ分析・マイクロサービスとの親和性といった強みがある一方、学習コストや設計の複雑さというトレードオフがあります。すべてのシステムに適用すべきではなく、ビジネス要件に応じて「CRUD で十分か、イベントソーシングが必要か」を見極めることが重要です。

コメント