通过嵌入实现数据一致性
如果您的模式在多个集合中存储相同的数据,则可以嵌入相关数据以删除重复项。更新后的去规范化模式将数据值保存在单一位置,从而保持数据的一致性。
嵌入相关数据可简化模式,并确保用户始终读取最新数据。然而,嵌入可能不是表示多对多等复杂关系的最佳选择。
关于此任务
如何以最佳方式嵌入相关数据取决于应用程序运行的查询。在单个集合中嵌入数据时,请考虑启用高性能查询的索引,并构建模式以允许高效的逻辑索引。
要比较嵌入文档和引用的优势,请参阅嵌入式数据与引用。
开始之前
查看强制数据一致性的不同方法,确保嵌入是适用于应用程序的最佳方法。有关更多信息,请参阅数据一致性。
更新数据库中的数据存储方式会影响现有索引和查询。更新模式时,也要更新应用程序的索引和查询,以考虑到模式的变化。
以下示例在电商应用程序中实施数据一致性。在初始模式中,产品信息在 products
和sellers
collection中重复。 products
collection中的sellerId
字段是对sellers
collection的引用,并将数据链接在一起。
// 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 } )