通过嵌入强制数据一致性
如果您的模式在多个集合中存储相同的数据,您可以通过嵌入相关数据来删除重复项。通过在单个位置维护数据值,更新后的非规范化模式通过维护数据值在单个位置来保持数据的一致性。
嵌入相关数据简化了您的模式,并确保用户始终读取最新的数据。然而,对于表示如多对多等复杂关系,嵌入可能不是最佳选择。
关于此任务
如何最优地嵌入相关数据取决于您的应用程序运行的查询。当您在单个集合中嵌入数据时,请考虑启用高效查询的索引,并构建您的模式以允许高效的逻辑索引。
要比较嵌入文档和引用的好处,请参阅嵌入数据与引用.
开始之前
回顾不同的方法来强制数据一致性,以确保嵌入是您应用程序的最佳方法。有关更多信息,请参阅数据一致性。
更新数据库中数据的存储方式可能会影响现有的索引和查询。当您更新您的模式时,也更新您应用程序的索引和查询以考虑模式更改。
以下示例在电子商务应用程序中强制数据一致性。在初始模式中,产品信息在products
(产品)和 sellers
(卖家)集合。在 products
集合中的 sellerId
字段是对 sellers
集合的引用,并将数据链接在一起。
// products collection [ { _id: 111, sellerId: 456, name: "sweater", price: 30, rating: 4.9, color: "green" }, { _id: 222, sellerId: 456, name: "t-shirt", price: 10, rating: 4.2, color: "blue" }, { _id: 333, sellerId: 456, name: "vest", price: 20, rating: 4.7, color: "red" } ]
// sellers collection [ { _id: 456, name: "Cool Clothes Co", location: { address: "21643 Andreane Shores", state: "Ohio", country: "United States" }, phone: "567-555-0105", products: [ { id: 111, name: "sweater", price: 30 }, { id: 222, name: "t-shirt", price: 10 }, { id: 333 name: "vest", price: 20 } ] } ]
步骤
为了规范化模式并强制一致性,在 sellers
集合中内嵌产品信息
db.sellers.insertOne( { _id: 456, name: "Cool Clothes Co", location: { address: "21643 Andreane Shores", state: "Ohio", country: "United States" }, phone: "567-555-0105", products: [ { id: 111, name: "sweater", price: 30, rating: 4.9, color: "green" }, { id: 222, name: "t-shirt", price: 10, rating: 4.2, color: "blue" }, { id: 333, name: "vest", price: 20, rating: 4.7, color: "red" } ] } )
结果
更新后的模式在用户查询特定卖家时返回所有产品信息。由于数据在单个集合中进行了非规范化,因此更新后的模式不需要额外的逻辑或维护来保持数据一致性。
下一步
在重新结构化您的模式后,您可以创建索引以支持常见查询。例如,如果用户经常按颜色查询产品,您可以在 products.color
字段上创建索引
db.sellers.createIndex( { "products.color": 1 } )