web-dev-qa-db-ja.com

DocumentDBのコレクションごとの単一または複数のエンティティ

ドキュメントDBのコレクションごとに1つのエンティティが必要ですか?

下の図で外部キーの関係があると考えてください。 enter image description here

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に関連エンティティを実装する標準的な方法は何ですか?

22
Abhijeet

通常、コレクションごとに複数のエンティティタイプを保存することをお勧めします。エンティティタイプを単一のドキュメントに格納するかどうかについては、もう少し検討が必要です。

Davidが述べたように、データをモデル化する方法は少し主観的です。

コレクション内に複数のエンティティタイプを格納する

まず...コレクションに複数のエンティティを保存する方法について説明しましょう。 DocumentDBコレクションはnotテーブルです。コレクションはスキーマを強制しません。つまり、同じコレクションに、スキーマが異なるさまざまな種類のドキュメントを保存できます。ドキュメントにtype属性を追加するだけで、さまざまなタイプのエンティティを追跡できます。

コレクションは、クエリとトランザクションを実行するためのパーティションと境界の単位と考える必要があります。したがって、同じコレクション内にさまざまなエンティティタイプを格納することの大きなメリットは、sprocを介してすぐにトランザクションサポートを利用できることです。

ドキュメント内に複数のエンティティタイプを保存する

1つのドキュメント内に複数のエンティティタイプを格納するかどうかについては、もう少し検討が必要です。これは一般に、非正規化(単一のドキュメントにデータを埋め込むことによってデータ間の関係をキャプチャする)および正規化と呼ばれます(他のドキュメントへの弱いリンクを作成することによってデータ間の関係をキャプチャする)データ。

通常非正規化はより良い読み取りパフォーマンスを提供します。

一般的な操作を完了するために、アプリケーションが発行する必要のあるクエリと更新が少なくなる場合があります。

一般に、次の場合に非正規化データモデルを使用します。

  • エンティティ間に「contains」の関係がある
  • エンティティ間に1対少数の関係がある
  • 非正規化されたデータ変更頻度が低い
  • 非正規化されたデータは無制限に成長しません
  • 非正規化されたデータは、ドキュメント内のデータに対して積分です

非正規化されたデータモデルの例:

{
  "Id": 1001,
  "Type": "Company",
  "Industry": "Software",
  "Employees": [
    {
      "Id": 10011,
      "Type": "Employee",
      "Name": "John Doe"
    },
    {
      "Id": 10012,
      "Type": "Employee",
      "Name": "Jane Doe"
    }
  ]
}

通常正規化はより良い書き込みパフォーマンスを提供します。

非正規化よりも柔軟性があります

クライアント側のアプリケーションは、参照を解決するためにフォローアップクエリを発行する必要があります。言い換えると、正規化されたデータモデルでは、サーバーへのラウンドトリップがさらに必要になる可能性があります。

一般に、正規化されたデータモデルを使用します。

  • 非正規化するとデータが重複しますが、重複の影響を上回る十分な読み取りパフォーマンスの利点が得られない場合。
  • 1対多の関係を表す
  • 多対多の関係を表します。
  • 関連データ頻繁に変更

正規化されたデータモデルの例:

{
  "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"
  }, ]
}]
59
Andrew Liu

あなたがエンティティの設計を求めているので、あなたの質問は少し主観的です、そしてそのために、単一の正しい答えはありません。

ただし、より目的の観点から:コレクション内に複数のエンティティタイプを含めることを妨げるものは何もありません(例:CompanyドキュメントタイプとEmployeeドキュメントタイプ(あなたの場合)。

クエリを実行するときに2つを区別するために、何らかのヒント(おそらくtypeプロパティ)を含める必要があります。ただし、同じコレクション内に両方のタイプを含めることで、コレクションスコープ内で作業できるようになります。 typeプロパティについて:DocumentDBはデフォルトですべてのプロパティにインデックスを付けるため、typeプロパティはクエリに簡単に統合できます。

[〜#〜] edit [〜#〜] DocumentDBがプレビューから本番環境に移行したときにその配置が削除されたため、容量単位あたり3コレクションに関する部分が削除されました。

6
David Makogon