目次を表示する

Event Sourcing 深掘り ── 経緯・必須要素・デファクトツール・実践と落とし穴

プロローグ ── 「変化を記録する」という別の世界観

プロローグ ── 「変化を記録する」という別の世界観

シリーズ構成(全8章)

Ch.1 プロローグ(本章) / Ch.2 Event Sourcing が生まれるまで / Ch.3 応える課題 / Ch.4 必要不可欠な5つの要素 / Ch.5 デファクトツール比較 / Ch.6 ベストプラクティス集 / Ch.7 アンチパターン集 / Ch.8 エピローグ


この記事で何を扱うか

「データベースに保存されているのは、現在の状態だ」── ほとんどのアプリケーションは、この前提の上に成り立っている。users テーブルの1行は「現在のユーザー情報」を表し、orders テーブルの1行は「現在の注文の状態」を表す。値が変われば UPDATE で上書きする。古い値はもう取り戻せない。

この設計は素直で、長く使われてきた。だが、ある種のシステムには根本的に合わない。

「この候補者はいつ書類選考を通過したのか」
「なぜ二次面接ではなく最終面接にスキップしたのか」
「3ヶ月前の時点で、選考中だった候補者は何人いたのか」

採用管理システムを運用していると、こうした問いが必ず出てくる。監査・分析・バグ調査・法的開示要求 ── 動機はさまざまだが、共通するのは「過去の状態と、状態が変わった理由」を必要としている、ということだ。

CRUD で UPDATE していくシステムでは、これらに答えられない。履歴テーブルを後付けすれば部分的には対応できるが、それは「データを記録する場所」と「現在の状態を表す場所」が二重化することを意味する。両者がズレたら、どちらが正しいのか?

Event Sourcing(イベントソーシング)は、この問いに対する別の答えだ。

「現在の状態を保存する」のではなく、「状態を変える出来事(イベント)を時系列で記録し、現在の状態はそこから導出する」。これだけのことだが、これだけのことが、データの扱い方を根本から変える。

graph TB
    subgraph crud["CRUD:現在の状態を保存"]
        C1["UPDATE screening_processes<br/>SET stage='final_interview'"]
        C2[("テーブル<br/>──────────<br/>stage = 'final_interview'<br/>updated_at = 2026-02-01")]
        C1 --> C2
        C2 -->|過去の値| C3["❌ 失われている"]
    end

    subgraph es["Event Sourcing:起きた事実を追記"]
        E1["AdvanceScreening Command"]
        E2[("Event Stream<br/>──────────<br/>v1: ScreeningProcessStarted<br/>v2: DocumentScreeningPassed<br/>v3: FirstInterviewScheduled<br/>v4: FirstInterviewCompleted<br/>v5: SecondInterviewSkipped")]
        E3["✅ 全ての変化と理由が残る"]
        E1 --> E2
        E2 --> E3
    end

    style crud fill:#ffe8e8,stroke:#cc6666
    style es fill:#e8f4ff,stroke:#6699cc

左の CRUD では stage カラムを上書きするだけ。右の Event Sourcing では「何が・いつ・どんな理由で起きたか」をすべて時系列で残す。保存しているデータの形が違う ── これが本シリーズで掘り下げる出発点だ。


前作との関係

このシリーズは 「EvansとVernonで学ぶDDD」続編 にあたる。前作の第9章「CQRS と Event Sourcing」で、Event Sourcing の基本概念とコード骨格は触れた。

前作で扱ったこと:
  - Event Sourcing が「集約の状態をイベント列で表す」設計だということ
  - apply メソッドによるイベント再生
  - CQRS と組み合わせると相性が良いこと
  - Vernon が「すべての集約に適用すべきではない」と注意していること

本シリーズで扱うこと(前作の先):
  - そもそもなぜこの設計が生まれたのか(歴史と思想)
  - Event Sourcing が応える「具体的な課題」と適用判断の軸
  - 5つの必須要素(Event / Stream / Store / Projection / Snapshot)の責務
  - 現場で使われるツール/フレームワークの比較と選定
  - イベント設計・スキーマ進化・運用の実務
  - 8つの典型的なアンチパターンと脱出法

前作を読んでいなくても本シリーズは独立して読めるよう書く。ただし「採用管理システムの選考プロセス」という題材は前作から継続して使うので、ピンと来ない箇所があれば前作を併読するのも手だ。


対象読者と前提知識

対象:
  - DDD の基本概念(集約・エンティティ・ドメインイベント)を実務で触ったことがあるエンジニア
  - 「Event Sourcing は名前は知っているが、プロダクション運用の勘所が分からない」方
  - 既存システムへの監査要件・履歴追跡導入を判断するアーキテクト

難易度:★★★☆☆〜★★★★☆(章による)
読了時間:約2時間
前提知識:
  - DDD の基本概念(集約・ドメインイベント)
  - CQRS の概要(読み書きモデル分離)
  - SQL データベースの基本(楽観的並行性制御がわかれば十分)
コード例:TypeScript(前作と統一)

CQRS が初耳だという方は、本シリーズと並行して前作の第9章を読むことを推奨する。


到達点

このシリーズを読み終えると、次のことができるようになる。

1. Event Sourcing が「いつ・誰が・どんな問題に応えるために」生み出したかを
   人に説明できる
2. 自分のシステムに Event Sourcing を導入すべきかどうかを、根拠を持って判断できる
3. KurrentDB / Axon / Marten / Akka Persistence などのツールから、
   要件に応じて適切なものを選べる
4. イベント設計とスキーマ進化、Snapshot 戦略の実装方針を立てられる
5. よくあるアンチパターン(Updated イベント地獄・Replay 地獄など)を
   設計時点で回避できる

「Event Sourcing は理解しているつもりだったが、実際にプロダクションに入れる怖さがあった」という状態から、「設計判断の軸が手に入った」という状態へ持っていくことが目的だ。


なぜ今、深掘り編なのか

Event Sourcing は決して新しいパターンではない。Martin Fowler が概念を整理したのは2005年、Greg Young が CQRS とセットで体系化したのは2010年だ。それでも、近年あらためて注目度が上がっている理由が3つある。

1. イベント駆動アーキテクチャの普及
   Kafka・EventBridge・Pulsar などのイベントインフラが当たり前になり、
   「イベントを永続化する」発想がインフラ側で支援されるようになった

2. 監査・コンプライアンスの厳格化
   GDPR・SOX・金融規制などで「変更履歴の完全保持」が要件になるケースが増え、
   CRUD の事後対応では追いつかなくなった

3. AI / 分析パイプラインとの親和性
   イベントストリームはそのまま分析・機械学習の入力になる。
   「業務トランザクションが、そのまま分析データになる」設計が現実的になった

つまり、Event Sourcing が応える課題は、20年前より「ありふれた要件」になっている。にもかかわらず、現場で正しく運用するための情報はまだ散在しがちだ。本シリーズはその穴を埋める。


このシリーズで使う題材

前作と同じく 採用管理システムの選考管理コンテキスト を題材にする。具体的には次のドメインを想定する。

登場人物:
  - 候補者(Candidate)
  - 求人(Job)
  - 採用担当者(Recruiter)
  - 面接官(Interviewer)

主要な集約:
  - 選考プロセス(ScreeningProcess)
    候補者×求人の組み合わせで作られ、書類選考→一次面接→二次面接→最終面接→
    内定通知 のステージを進んでいく

ビジネス上の問い:
  - 「いつ・誰が・どの理由で・どのステージへ動かしたか」を完全に追跡したい
  - 監査要件として、過去の任意時点の状態を再現できる必要がある
  - 採用ダッシュボードは複数集約を横断する非正規化ビューを持つ

このドメインは Event Sourcing の特徴を引き出すのに向いている。状態遷移が業務上の重要イベントと直結し、履歴追跡が業務要件として実在し、書き込みと読み取りの最適化要求が異なる ── ちょうど CQRS と Event Sourcing が噛み合う形だ。


章の歩き方

graph LR
    A["Ch.2<br/>歴史"] --> B["Ch.3<br/>応える課題"]
    B --> C["Ch.4<br/>5つの必須要素"]
    C --> D["Ch.5<br/>ツール比較"]
    D --> E["Ch.6<br/>ベストプラクティス"]
    E --> F["Ch.7<br/>アンチパターン"]
    F --> G["Ch.8<br/>採用判断"]

    A -.->|なぜ・何のために| B
    C -.->|何で構成されているか| D
    D -.->|どう作り運用するか| E
    F -.->|何を避けるべきか| G

    style A fill:#fff3e0
    style B fill:#fff3e0
    style C fill:#e3f2fd
    style D fill:#e3f2fd
    style E fill:#e8f5e9
    style F fill:#ffebee
    style G fill:#f3e5f5

では、Event Sourcing が「いつ・誰によって・なぜ生まれたのか」から始めよう。話は1494年のヴェネツィアから始まる。