ドキュメントDBのコレクションごとに1つのエンティティが必要ですか?
下の図で外部キーの関係があると考えてください。
1つは従業員用、もう1つは会社用の2つのコレクションを作成する必要があります。または、それらを1つのコレクションに保存する必要がありますか?
here ストアドプロシージャのdocumentdbスコープでは、トリガーなどがコレクション内にあることを読みました。したがって、異なるエンティティを個別のコレクションに分割することで、すぐに使用できる機能を失うことになります。
したがって、以下のように、両方のクラスを単一のエンティティとしてダンプする方がよいのではないでしょうか。
{
"Id": 1001,
"Industry": "Software",
"Employees": [
{
"Id": 10011,
"Name": "John Doe",
"CompanyId": 1001
},
{
"Id": 10012,
"Name": "Jane Doe",
"CompanyId": 1001
}
]
}
DocumentDBに関連エンティティを実装する標準的な方法は何ですか?
通常、コレクションごとに複数のエンティティタイプを保存することをお勧めします。エンティティタイプを単一のドキュメントに格納するかどうかについては、もう少し検討が必要です。
Davidが述べたように、データをモデル化する方法は少し主観的です。
コレクション内に複数のエンティティタイプを格納する
まず...コレクションに複数のエンティティを保存する方法について説明しましょう。 DocumentDBコレクションはnotテーブルです。コレクションはスキーマを強制しません。つまり、同じコレクションに、スキーマが異なるさまざまな種類のドキュメントを保存できます。ドキュメントにtype属性を追加するだけで、さまざまなタイプのエンティティを追跡できます。
コレクションは、クエリとトランザクションを実行するためのパーティションと境界の単位と考える必要があります。したがって、同じコレクション内にさまざまなエンティティタイプを格納することの大きなメリットは、sprocを介してすぐにトランザクションサポートを利用できることです。
ドキュメント内に複数のエンティティタイプを保存する
1つのドキュメント内に複数のエンティティタイプを格納するかどうかについては、もう少し検討が必要です。これは一般に、非正規化(単一のドキュメントにデータを埋め込むことによってデータ間の関係をキャプチャする)および正規化と呼ばれます(他のドキュメントへの弱いリンクを作成することによってデータ間の関係をキャプチャする)データ。
通常非正規化はより良い読み取りパフォーマンスを提供します。
一般的な操作を完了するために、アプリケーションが発行する必要のあるクエリと更新が少なくなる場合があります。
一般に、次の場合に非正規化データモデルを使用します。
非正規化されたデータモデルの例:
{
"Id": 1001,
"Type": "Company",
"Industry": "Software",
"Employees": [
{
"Id": 10011,
"Type": "Employee",
"Name": "John Doe"
},
{
"Id": 10012,
"Type": "Employee",
"Name": "Jane Doe"
}
]
}
通常正規化はより良い書き込みパフォーマンスを提供します。
非正規化よりも柔軟性があります
クライアント側のアプリケーションは、参照を解決するためにフォローアップクエリを発行する必要があります。言い換えると、正規化されたデータモデルでは、サーバーへのラウンドトリップがさらに必要になる可能性があります。
一般に、正規化されたデータモデルを使用します。
正規化されたデータモデルの例:
{
"Id": 1001,
"Type": "Company",
"Industry": "Software"
}
{
"Id": 10011,
"Type": "Employee",
"Name": "John Doe",
"CompanyId": 1001
}
{
"Id": 10012,
"Type": "Employee",
"Name": "Jane Doe",
"CompanyId": 1001
}
ハイブリッドアプローチ
正規化と非正規化のどちらを選択するかは、白黒の選択である必要はありません。勝利のデザインパターンは、オブジェクトのフィールドの部分的なセットを正規化し、他のフィールドを非正規化することを選択できるハイブリッドアプローチであることがよくあります。
言い換えると、頻繁に読み取られる安定した(または不変の)プロパティを非正規化してフォローアップクエリの必要性を減らし、頻繁に書き込まれる/変更するフィールドを正規化して書き込みをファンアウトする必要性を減らすことを選択できます。
ハイブリッドアプローチの例:
// Author documents:
[{
"id": 1,
"firstName": "Thomas",
"lastName": "Andersen",
"countOfBooks": 3,
"books": [1, 2, 3],
"images": [{
"thumbnail": "http://....png"
}, {
"profile": "http://....png"
}, {
"large": "http://....png"
}]
}, {
"id": 2,
"firstName": "William",
"lastName": "Wakefield",
"countOfBooks": 1,
"books": [1, 4, 5],
"images": [{
"thumbnail": "http://....png"
}]
}]
// Book documents:
[{
"id": 1,
"name": "DocumentDB 101",
"authors": [{
"id": 1,
"name": "Thomas Andersen",
"thumbnailUrl": "http://....png"
}, {
"id": 2,
"name": "William Wakefield",
"thumbnailUrl": "http://....png"
}]
}, {
"id": 2,
"name": "DocumentDB for RDBMS Users",
"authors": [{
"id": 1,
"name": "Thomas Andersen",
"thumbnailUrl": "http://....png"
}, ]
}]
あなたがエンティティの設計を求めているので、あなたの質問は少し主観的です、そしてそのために、単一の正しい答えはありません。
ただし、より目的の観点から:コレクション内に複数のエンティティタイプを含めることを妨げるものは何もありません(例:Company
ドキュメントタイプとEmployee
ドキュメントタイプ(あなたの場合)。
クエリを実行するときに2つを区別するために、何らかのヒント(おそらくtype
プロパティ)を含める必要があります。ただし、同じコレクション内に両方のタイプを含めることで、コレクションスコープ内で作業できるようになります。 type
プロパティについて:DocumentDBはデフォルトですべてのプロパティにインデックスを付けるため、type
プロパティはクエリに簡単に統合できます。
[〜#〜] edit [〜#〜] DocumentDBがプレビューから本番環境に移行したときにその配置が削除されたため、容量単位あたり3コレクションに関する部分が削除されました。