Command Query Responsibility Segregation — 状態を変更する Command と、状態を読み取る Query を別モデル・別経路で扱う設計パターン。Greg Young が提唱した。Bertrand Meyer の CQS(Command Query Separation)をアーキテクチャレベルに拡張したもの。
概要
通常の CRUD では、同じドメインモデルが「書き込み」と「読み取り」の両方の責務を抱える。複雑なドメインでは、書き込み側で必要な不変条件と、読み取り側で必要な集約・整形が大きく食い違うため、 モデル自体を 2 つに分離するのが CQRS の本質。
構造
Client
├─ Command(書き込み) → ドメインモデル → 書き込み DB
│ ↓
│ イベント発行
│ ↓
└─ Query(読み取り) ← Read Model(参照用) ← イベント反映
CQRS が効く場面
| 場面 | 理由 |
|---|---|
| 読み込みと書き込みの負荷比が大きい | 読み取り側だけスケールできる |
| 集計・検索・レポートが多い | クエリ用に最適化された Read Model を作れる |
| 複雑なビジネスルールが書き込み側にある | 書き込みモデルを純粋に保てる |
| マルチチャネル配信(EC・モール連携) | 配信先ごとに Read Model を分けられる |
CQRS が過剰な場面
| 場面 | 理由 |
|---|---|
| 単純な CRUD | 二重モデル化のコストが価値を上回る |
| トランザクション一貫性が最重要 | 結果整合性の運用に追加コスト |
| 小規模チーム | 学習コストが投資効果に見合わない |
イベントソーシングとの関係
CQRS はイベントソーシングとよく組み合わせて使われる。書き込み側でイベントを永続化し、そのイベントを購読して Read Model を構築する流れが典型。ただし両者は独立した概念であり、CQRS だけ・イベントソーシングだけの採用も成立する。
マルチモール EC での適用イメージ
CTS-EC 共通商品マスタのように 共通商品マスタへの更新(Command) と 各モール向け出品ビューの参照(Query) が大きく非対称なドメインは、CQRS の利得が出やすい典型例。書き込み側はバリエーション・SKU・画像紐付けなどビジネスルールが厚く、読み取り側はモール別の表示・在庫・配信状態を高速に引きたいため、モデルを分離するメリットが大きい。
関連記事
- 開発手法ガイド:概要 — DDD の発展としての CQRS の位置づけ
- CTS-EC 共通商品マスタ — Command/Query が非対称になる典型ドメインの実例