我开始学习MongoDB,我曾经问自己如何解决MongoDB中的“一对多”关系设计。在搜索过程中,我在其他帖子/文章中找到了许多评论,比如“你在思考关系”。好吧我同意。有些情况下,像信息的重复不会成为一个问题,例如,客户-订单的例子。
但是,假设您有以下表: ORDERS,它与客户购买的产品具有嵌入的详细结构。因此,对于一件或另一件事,您需要更改已经嵌入在多个订单中的产品名称(或另一种信息)。
最后,您必须在MongoDB中进行一对多的关联(这意味着将ObjectID字段作为另一个集合的链接),这样您就可以解决这个简单的问题了,不是吗?但每次我找到关于这方面的文章/评论时,它都说这将是蒙古族的一个性能缺陷。有点令人失望
在MongoDB中是否有另一种解决/设计此问题的方法,而不存在性能错误?
发布于 2014-08-25 05:53:56
问题是数据标准化过度了。订单是由客户定义的,客户在给定的时间点住在某个地点,支付订单时有效的价格(在应用程序生命期内可能会发生很大变化,您必须记录这些参数和其他几个参数,这些参数只在某个时间点有效)。因此,要记录订单(双关意),您需要在特定时间点保存所有数据。让我举一个例子:
{ _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链接。
https://stackoverflow.com/questions/25485882
复制