モノリシックアーキテクチャからマイクロサービスへ移行することは、データについて考える方法を変える。これは単なるコードの再構成作業ではなく、情報の流れ、永続化、システム全体における関係性の根本的な変化である。初心者エンジニアにとっては、データ関係をモデル化する際に特定の課題が伴うことが多い。分散環境内でモノリスの馴染み深いパターンを再現しようとする直感は強いが、危険でもある。
エンティティ関係図(ERD)はデータレイヤーの設計図として機能する。マイクロサービスの文脈では、設計が不十分なERDは、密結合、データの不整合、後で解決が困難な運用上の悪夢を招く可能性がある。このガイドでは、初期段階のデータモデリングで見られる重大な落とし穴を検討し、それらを回避する構造的なアプローチを提示する。特定のツールに依存せずに、共有スキーマ、関係の扱い、ドメイン境界について検討し、代わりにアーキテクチャの原則に焦点を当てる。

💡 モノリス遺産の罠
多くのエンジニアは、モノリスアプリケーションでキャリアをスタートする。この環境では、単一のデータベースが複数のモジュールをサポートすることが多い。エンティティ関係図は、すべてをつなぐ膨大なテーブルと外部キーのネットワークとして、この現実を反映している。初心者エンジニアがマイクロサービスに取り組む際、自然に以前の作業を拡大したようなER図を描きたくなる傾向がある。
このアプローチは失敗する。なぜならマイクロサービスは技術的実装の詳細ではなく、ビジネス機能を中心に設計されているからである。モノリスのERDは、システム全体にわたる書き込みの一貫性とトランザクション整合性を最適化する。一方、マイクロサービスのERDは、サービスの分離と独立したデプロイを最適化しなければならない。全体を一つのデータベースとして表す単一の図を描くということは、分散サービスをデプロイしようとしていても、無意識のうちにモノリスを設計していることになる。
- モノリス思考:すべてのデータに対して単一の真実の源を仮定する。
- マイクロサービス思考:特定のサービスが管理する複数の真実の源を受け入れる。
- ERDの範囲:組織全体ではなく、各サービスごとに範囲を定めるべきである。
最初の誤りは、グローバルERDを描くことである。代わりに、各サービスは独自のスキーマ設計を持つべきである。図はアプリケーション全体の集約状態ではなく、特定のサービスの内部状態を表すものである。この違いは、マイクロサービスの実現可能性を維持するための独立性を保つ上で極めて重要である。
🗄️ 誤り1:共有データベースのアンチパターン
最も一般的な誤りの一つは、サービスがデータベーススキーマを共有すべきだという前提にある。図では、異なる2つのサービスが同じテーブルセットから読み書きしているように見える。データアクセスの効率性を考えると魅力的に見えるが、これは隠れた依存関係を生み出す。
Service AとService Bが同じデータベーステーブルにアクセスしている場合、それらは密結合している。Service Aが新しい機能に対応するためにカラム名を変更したい場合、Service Bは壊れてしまう。これにより、両方のサービスが互換性を保つために同時にデプロイしなければならなくなる。これはマイクロサービスの主な目的である独立したデプロイとスケーリングを無効にする。
なぜこれが失敗するのか
- デプロイの結合:スキーマの変更には、チーム間の調整が必要になる。
- 障害の伝播:1つのサービスでのスキーマ移行問題が他のサービスに影響を与える。
- セキュリティリスク:テーブルへの広範なアクセスは、データ漏洩のリスクを広げる。
ER図では、この問題はテーブルが複数のサービスの名前でラベル付けされている、または他のサービスが所有するテーブルを指す外部キーを持つことで現れることが多い。正しいアプローチは、各サービスがデータを独占的に所有することを保証することである。データ共有は、直接的なデータベースアクセスではなく、API呼び出しや非同期イベントを通じて行うべきである。
正しいアプローチの可視化
図をレビューする際は、テーブルの所有権に注目するべきである。すべてのテーブルは1つのサービスに属すべきである。2つのサービス間で関係が必要な場合、外部キー制約ではなく、参照またはイベントトリガーとしてモデル化すべきである。
🔗 誤り2:外部キーをグローバルな真実として扱う
外部キーは、単一のデータベース内でのデータ整合性を維持するための強力なツールである。分散システムでは、サービス境界を越えて外部キー制約を強制することは技術的に複雑であり、しばしば逆効果である。初心者エンジニアは、異なるサービスのデータベースをまたぐ外部キーを使って関係をモデル化しようとする傾向がある。
2つの別々のデータベース間で外部キー関係を強制しようとすると、分散トランザクションが必要になる。これにより遅延と複雑性が生じる。Service Aのデータベースが利用不可の場合、Service Bの整合性チェックが失敗する。これはアーキテクチャ全体に連鎖的な障害を引き起こす可能性がある。
整合性のトレードオフ
マイクロサービスでは、強一貫性と可用性のどちらかを選ぶことがよくあります。外部キーは強一貫性を強制します。分散環境では、複数のサービスにわたって強一貫性を維持することはコストがかかります。書き込み操作の速度が低下し、システムダウンのリスクが高まります。
- 強一貫性:すべてのノードでデータが即座に同一であることを保証します。分散システムでは実現が難しい。
- 最終的一貫性:データが収束するまで一時的に異なる可能性を許容します。マイクロサービスでは好まれます。
外部キーの代わりに論理参照を使用してください。関連するエンティティのIDを保存するが、データベースレベルで関係性を強制してはいけません。検証はアプリケーションレベルまたはイベント検証を通じて行うべきです。これにより、他のサービスがデータ整合性を検証するのを待たずに、サービスが独立して進化できるようになります。
🌍 ミス3:スキーマ設計におけるドメイン境界の無視
データモデリングは、技術的インフラではなく、ビジネスドメインに従うべきです。この考え方はドメイン駆動設計(DDD)の中心にあります。よくある誤りは、ビジネス能力ではなく技術的利便性に基づいてデータをグループ化することです。例えば、請求サービスと認証サービスの両方で共有される「Users」テーブルを作成することです。
ER図がビジネス境界よりも技術的利便性を反映していると、高い結合度が生じます。請求サービスはユーザーの支払い履歴が必要になる一方、認証サービスは資格情報のみが必要です。これらを1つの「User」エンティティに統合すると、保守が困難な肥大化したスキーマが生まれます。
バウンデッドコンテキストの特定
これを避けるためには、データが使用されるコンテキストを定義してください。各サービスは特定のバウンデッドコンテキストを表すべきです。ER図はその特定のコンテキストの用語と構造を反映すべきです。
- 認証コンテキスト:アイデンティティ、資格情報、セッションに焦点を当てる。
- 注文コンテキスト:製品、価格、配送状態に焦点を当てる。
- 通知コンテキスト:チャネル、メッセージ、配送ログに焦点を当てる。
図の中に5つの異なるサービスから参照されているテーブルが見られたら、その配置を疑ってください。それは共有ライブラリに属しているか、複数のサービス固有のエンティティに分割すべきです。異なるコンテキストを満たすためにデータを複製すべきであり、異なる技術的要件を満たすために共有すべきではありません。
🔄 ミス4:結合のための過剰最適化
従来のデータベース設計では、正規化が冗長性を減らす鍵です。エンジニアはデータを効率的に格納するために第三正規形を目指します。マイクロサービスでは、この考え方により過剰正規化が生じる可能性があります。あるサービスが別のサービスに存在するデータを必要とする場合、ネットワークをまたいで効率的な結合を可能にするスキーマを設計したくなる誘惑があります。
サービス間の結合は高コストです。ネットワーク呼び出し、シリアライズ、集約が必要です。ERDがこれらの結合を容易にするように設計されていると、システムは脆弱になります。ネットワーク遅延がボトルネックとなり、システムは独立したスケーリング能力を失います。
非正規化戦略
サービス内でのデータの非正規化は、しばしばより良い選択です。Service AがService Bのデータを必要とする場合、Service Aは必要なフィールドのコピーを保持すべきです。これをリードモデルと呼びます。Service AのER図は、この非正規化構造を反映すべきです。
- 書き込みモデル:更新と厳格な整合性に最適化されている(通常は正規化されている)。
- 読み込みモデル:クエリとパフォーマンスに最適化されている(通常は非正規化されている)。
図を作成する際には、「この関係性はビジネス上の質問に答えるために結合を必要とするか?」と問うべきです。もしそうであれば、そのデータが必要なサービス内でデータを複製することを検討してください。これにより遅延が低減され、他のサービスのデータベースの可用性に依存しなくなります。
📈 ミス5:データの進化とバージョン管理の無視
スキーマは時間とともに変化します。サービスも進化します。初期のER図でよく見られる見落としは、スキーマ移行の計画が欠けている点です。若手エンジニアは、6か月後の変化を考慮せずに、現在の要件に完全なスキーマを設計しがちです。
モノリスでは、1回のデプロイでカラムを削除し、アプリケーションを更新できます。マイクロサービスでは、外部APIや別のサービスで使用されているカラムを削除するには、慎重な非推奨戦略が必要です。ERDは現在の状態を示すだけでなく、バージョン管理戦略の兆しを示すべきです。
スキーマ変更の対応
データ構造が新しいフィールドをどのように扱うかを検討してください。直接カラムを追加するのではなく、柔軟なデータ型や別々のメタデータテーブルを使用することを検討してください。これにより、既存のコンシューマーを破壊せずに新しい属性を導入できます。
- 後方互換性:新しいフィールドは、既存のクライアントにとってオプションであるべきです。
- 非推奨:古いフィールドは、図の注記で削除予定であることを明記すべきです。
- バージョン管理:APIのバージョンは、しばしばデータ構造のバージョンを決定します。
図内にフィールドのライフサイクルを文書化することで、将来のエンジニアが変更がいつ導入されたか、いつ削除される可能性があるかを理解しやすくなります。これにより、異なるサービスが同じデータを異なる方法で解釈する「スキーマのずれ」を防ぐことができます。
📊 比較:モノリス vs. マイクロサービスのデータパターン
| 機能 | モノリスアプローチ | マイクロサービスアプローチ |
|---|---|---|
| データ所有権 | 1つのデータベースに集中 | 各サービスごとに分散 |
| 関係性 | 外部キー | API呼び出しまたはイベント |
| 整合性 | 強力(ACID) | 最終的(CAP定理) |
| スキーマ変更 | 1回のデプロイ | 独立したデプロイ |
| 結合操作 | データベース結合 | アプリケーション集約 |
| 障害領域 | 単一障害点 | 隔離されたサービス障害 |
✅ 初心者エンジニア向け検証チェックリスト
エンティティ関係図を最終確定する前に、このチェックリストを確認して、一般的なアーキテクチャの落とし穴を避けていいるか確認してください。
- 所有権:すべてのテーブルが正確に1つのサービスに属していますか?
- 依存関係:サービス外のテーブルを指す外部キーは存在しますか?
- 範囲:この図は全体システムではなく、境界付きコンテキストを表していますか?
- 読み取りモデル:読み取り最適化構造は書き込みモデルから分離されていますか?
- イベント:データの変更は、他のサービスが利用できるイベントとしてモデル化されていますか?
- 冪等性:データ更新は重複せずに安全に再試行できますか?
- プライバシー:機密情報が設計段階で分離または暗号化されていますか?
🛠️ 実践的な実装ステップ
図を描き始める際は、これらのステップに従ってアーキテクチャの整合性を保ちましょう。
- コンテキストを定義する:まず、サービスが支援するビジネス機能をリストアップします。
- エンティティを特定する:これらの機能に関連する名詞をリストアップします(例:注文、顧客、請求書)。
- 関係性を決定する:これらのエンティティがどのように相互作用するかをマッピングします。サービス間のリンクを避けてください。
- データ型を選択する:必要な操作をサポートする型を選択します(柔軟なデータにはJSON、識別子には文字列)。
- 結合度の確認:どのエンティティも、他のサービスからのデータを正しく動作するために必要としないか確認してください。
- ドキュメントの制約:整合性チェックが行われる場所(例:APIレイヤー vs データベースレイヤー)に注記する。
🔒 セキュリティおよびコンプライアンスの考慮事項
データモデリングにはセキュリティも含まれます。よくある誤りは、データベースのセキュリティだけで十分だと考えることです。分散システムではデータがサービス間を移動します。ERDは、機密データがどこに存在するかを反映すべきです。
サービスが個人を特定できる情報(PII)を格納する場合、図にそのことを明示すべきです。アクセス制御はサービスの境界を基準に設計しなければなりません。PIIが異なるサービス内の複数のテーブルに分散するスキーマを設計すると、コンプライアンスの遵守が難しくなります。機密データは、そのデータタイプを管理する責任を持つサービス内に留めておくようにしましょう。
🧠 データアーキテクチャに関する最終的な考察
マイクロサービス向けのER図を設計するには、視点の転換が必要です。可能な限り多くの点をつなぐことではなく、点を独立して移動できるように分離することです。図はチーム間のコミュニケーションツールです。データがどこに存在するか、誰が所有しているか、どのように流れているかを明確に示すべきです。
中央集権的な見栄えを整える誘惑に屈しないでください。分散データの不整を受容しましょう。パフォーマンスや分離のためには、複製が時として必要であることを受け入れましょう。ドメイン境界とサービス所有権に注目することで、長期的な成長と安定性を支える基盤を築けます。
データを保存することだけが目的ではないことを思い出してください。組織のビジネス機能を可能にすることが目的です。図がデータベースのメカニクスではなく、ビジネスロジックを反映しているとき、それはエンジニアリングチーム全体にとって貴重な資産になります。分離性、明確性、システムを壊さずに進化できる能力に注目し続けましょう。
図を定期的に見直しましょう。システムが成長するにつれて、パターンが変化する可能性があります。最初のサービスで機能したことが、10番目のサービスでは通用しないかもしれません。データモデルの継続的な改善により、アーキテクチャが堅牢であり、技術的目標と整合した状態を保ちます。モノリスパターンに警戒を払い、耐障害性とスケーラビリティに優れたシステムを構築しましょう。












