Docs Menu
Docs Home
/
MongoDB マニュアル
/

重複データの処理

項目一覧

  • このタスクについて
  • 例: E Commerge スキーマでのデータの重複
  • 手順
  • データを重複させることの利点
  • 例: 製品レビューの重複データ
  • 手順
  • データを重複させることの利点
  • 詳細

単一のドキュメントに関連データを埋め込む場合、2 つのコレクション間でデータを複製できます。データを重複させることにより、アプリケーションは、モデル内のエンティティを論理的に分離しながら、1 つのクエリで複数のエンティティについての関連情報をクエリできます。

データを重複させることに関する懸念事項の 1 つは、ストレージ コストの増加です。 ただし、アクセス パターンを最適化する利点は通常、ストレージによる潜在的なコストの増加を超える。

データを複製する前に、以下の要素を考慮してください。

  • 重複したデータをどのくらいの頻度でアップデートする必要があるか。 重複したデータを頻繁に更新すると、重いワークロードとパフォーマンスの問題が発生する可能性があります。 ただし、頻度の低い更新を処理するために必要な追加ロジックは、読み取り操作で結合(ルックアップ)を実行するよりもコストが低くなります。

  • データが重複している場合の読み取りのパフォーマンス上の利点。 データを重複させることで、複数のコレクションにわたって結合を実行する必要がなくなるため、アプリケーションのパフォーマンスが向上します。

次の例は、データアクセスとパフォーマンスを向上させるために、eコマース アプリケーション スキーマでデータを複製する方法を示しています。

1
use eCommerce
2

eCommerceデータベースに次のコレクションを作成します。

コレクション名
説明
サンプルドキュメント
customers
名前、メール、電話番号などのカスタマー情報を保存します。
db.customers.insertOne( {
customerId: 123,
name: "Alexa Edwards",
email: "a.edwards@randomEmail.com",
phone: "202-555-0183"
} )
products
価格、サイズ、素材などの製品情報を保存します。
db.products.insertOne( {
productId: 456,
product: "sweater",
price: 30,
size: "L",
material: "silk",
manufacturer: "Cool Clothes Co"
} )
orders
日付や合計金額などの注文情報を保存します。 Documents in the orders collection embed the corresponding products for that order in the lineItems field.
db.orders.insertOne( {
orderId: 789,
customerId: 123,
totalPrice: 45,
date: ISODate("2023-05-22"),
lineItems: [
{
productId: 456,
product: "sweater",
price: 30,
size: "L"
},
{
productId: 809,
product: "t-shirt",
price: 10,
size: "M"
},
{
productId: 910,
product: "socks",
price: 5,
size: "S"
}
]
} )

productsコレクションの次のプロパティはorders コレクションに重複しています。

  • productId

  • product

  • price

  • size

アプリケーションが注文情報を表示すると、対応する注文の行項目が表示されます。 注文情報と製品情報が別々のコレクションに保存されている場合、2 つのコレクションのデータを結合するには、アプリケーションは $lookupを実行する必要があります。 ルックアップ操作は、多くの場合、コストとパフォーマンスが低下します。

ordersコレクションに行項目のみを埋め込むのではなく、製品情報を複製する理由は、アプリケーションが注文を表示するときにのみ製品情報のサブセットのみを必要とするためです。 必須 フィールドのみを埋め込むことで、アプリケーションは追加の製品の詳細を保存することができ、 ordersコレクションに不要な肥大化を引き起こすことはありません。

次の例では、 サブセット パターンを使用して、オンライン ストアのアクセス パターンを最適化します。

たとえば、ユーザーが製品を表示すると、アプリケーションに製品の情報と最新の 5 件のレビューが表示されるアプリケーションを考えてみましょう。 レビューは、 productsコレクションとreviewsコレクションの両方に保存されます。

新しいレビューが書き込まれると、次の書き込みが行われます。

  • レビューは reviews コレクションに挿入されます。

  • products コレクション内の最近のレビューの配列が $pop$push で更新されます。

1
use productsAndReviews
2

productsAndReviewsデータベースに次のコレクションを作成します。

コレクション名
説明
サンプルドキュメント
products
製品情報を保存します。 productsコレクション内のドキュメントには、 recentReviewsフィールドに最新の 5 つの製品レビューが埋め込まれています。
db.products.insertOne( {
productId: 123,
name: "laptop",
price: 200,
recentReviews: [
{
reviewId: 456,
author: "Pat Simon",
stars: 4,
comment: "Great for schoolwork",
date: ISODate("2023-06-29")
},
{
reviewId: 789,
author: "Edie Short",
stars: 2,
comment: "Not enough RAM",
date: ISODate("2023-06-22")
}
]
} )
reviews
製品のすべてのレビュー(最近のレビューのみ)を保存します。 reviewsコレクション内のドキュメントには、レビューに関連する製品を示すproductIdフィールドが含まれています。
db.reviews.insertOne( {
reviewId: 456,
productId: 123,
author: "Pat Simon",
stars: 4,
comment: "Great for schoolwork",
date: ISODate("2023-06-29")
} )

アプリケーションは、表示する必要があるすべての情報を返すために、データベースを 1 回呼び出すだけで済みます。 データが完全に別々のコレクションに保存されている場合、アプリケーションはproducts reviewsコレクションと コレクションのデータを結合する必要があるため、パフォーマンスの問題が発生する可能性があります。

レビューはほとんど更新されないため、重複データの保存コストは低く、コレクション間でデータの一貫性を保つことは困難ではありません。

重複データの整合性を保つ方法については、「データの整合性 」を参照してください。

戻る

運用上の要因