問題は、データを過度に正規化することです。注文は、特定の時点で特定の場所に住んでいて、注文時に有効な特定の価格を支払う顧客によって定義されます(これは、アプリケーションの存続期間中に大幅に変更される可能性があり、とにかく文書化する必要があります。 特定の時点でのみ有効なその他のパラメータ 。したがって、ドキュメント 注文(しゃれを意図したもの)の場合、その特定の時点のすべてのデータを保持する必要があります。例を挙げましょう:
{ _id: "order123456789",
date: ISODate("2014-08-01T16:25:00.141Z"),
customer: ObjectId("53fb38f0040980c9960ee270"),
items:[ ObjectId("53fb3940040980c9960ee271"),
ObjectId("53fb3940040980c9960ee272"),
ObjectId("53fb3940040980c9960ee273")
],
Total:400
}
これで、顧客もアイテムの詳細も変更されない限り、この注文が送信された場所、注文の価格などを再現できます。しかし、顧客が住所を変更するとどうなりますか?または、アイテムの価格が変更された場合はどうなりますか?それぞれのドキュメントでこれらの変更を追跡する必要があります。 多く 次のように注文を保存するのが簡単で十分に効率的です:
{
_id: "order987654321",
date: ISODate("2014-08-01T16:25:00.141Z"),
customer: {
userID: ObjectId("53fb3940040980c9960ee283"),
recipientName: "Foo Bar"
address: {
street: "742 Evergreen Terrace",
city: "Springfield",
state: null
}
},
items: [
{count:1, productId:ObjectId("53fb3940040980c9960ee300"), price: 42.00 },
{count:3, productId:ObjectId("53fb3940040980c9960ee301"), price: 0.99},
{count:5, productId:ObjectId("53fb3940040980c9960ee302"), price: 199.00}
]
}
このデータモデルと集約パイプラインの使用により、いくつかの利点があります。
- 顧客の価格や住所、名前の変更、ギフトの購入を個別に追跡する必要はありません。すでに文書化されています。
- 集計パイプラインを使用すると、価格データを個別に保存しなくても価格トレンドを作成できます。 現在を保存するだけです 注文書のアイテムの価格。
- 価格弾力性、州/市別の売上高などの複雑な集計でも、非常に単純な集計を使用して実行できます。
一般に、ドキュメント指向データベースでは、将来変更される可能性のあるすべてのプロパティまたはフィールドと、この変更によって異なる意味が作成されるため、ドキュメント内に格納する必要があると言っても過言ではありません。将来変更される可能性があるが、意味的な意味に触れないもの(例ではユーザーのパスワード)はすべて、GUIDを介してリンクされる可能性があります。