【发布时间】:2018-01-18 23:37:33
【问题描述】:
我很好奇如何构建具有多对多关系且可能包含数万条记录的 MongoDB。
假设您有一个餐厅数据库,该数据库跟踪大量餐厅以及所有入住这些餐厅的人。因此,用户可能想要查找一个人并查看他们已登记入住的所有餐厅,但也可以查找一家餐厅并查看所有已登记入住的人。
如何以一种有意义且易于搜索和更新的方式来构建它?
【问题讨论】:
标签: mongodb
我很好奇如何构建具有多对多关系且可能包含数万条记录的 MongoDB。
假设您有一个餐厅数据库,该数据库跟踪大量餐厅以及所有入住这些餐厅的人。因此,用户可能想要查找一个人并查看他们已登记入住的所有餐厅,但也可以查找一家餐厅并查看所有已登记入住的人。
如何以一种有意义且易于搜索和更新的方式来构建它?
【问题讨论】:
标签: mongodb
您给出的示例与大多数真实世界的多对多关系示例一样,实际上是 few-to-few 关系的示例。您可能有许多餐厅和许多食客,但与整个集合相比,任何给定的餐厅只为一小部分食客提供服务,而大多数个人食客只会光顾一小部分餐厅。这听起来像是一个稀疏链接的网络,其中链接密度比明显低于 1。
为了测量网络的链接密度(边缘密度),我们计算 现有链接 m 与可能链接总数的比率。 对于 N 个节点的网络,网络链路密度为 D = m / 0.5*N*(N-1) 全连接网络的(最大)链路密度D为1。 - Network-Science
但是,您问的是多对多,那么我们以神经网络为例如何?神经网络通常形成密集网络,因此代表了真正的多对多网络。在这种情况下,答案很简单——不要使用 mongoDB。使用根据您的特定要求量身定制的自定义结构和序列化策略。毕竟,真正的多对多关系几乎总是异常值,因此需要进行特殊处理。
话虽如此,在 mongoDB 中建模更常见的 few-to-few 关系可以在不牺牲丰富的文档结构的情况下实现,而实现这一点的方式取决于您的访问模式。
因此,以餐厅/餐厅网络示例为例,如果您通常要查询餐厅的用餐者,那么您将创建一个包含每个餐厅的 diner_id 数组。另一种方式意味着每个用餐者都持有一组 restaurant_ids。两者都用于双向查询能力。
必须小心,因为 mongoDB 中没有 foreign_key 约束,因此维护数据的引用完整性是您的责任。
如果性能对您来说最重要,那么您可能希望将数据嵌入到每个文档中,而不是使用 id 来引用它。这是读取(而不是写入)的更高性能选项,因为所有数据都可以一次从磁盘中提取出来。这意味着当您更新数据值以确保数据的完整性时,您将需要做更多的工作,但这通常并不像最初看起来那样可怕。食客多久真正改变一次他们的名字?并且根据文档大小,您可能不一定要嵌入完整文档,数据的子集加上指向完整记录的 id 通常可以解决问题。
简而言之,mongoDB 架构设计应该由应用程序需求驱动。不同应用程序的不同模式,而不是一个单一的关系数据库来统治它们。数据的真实情况如何?应用程序如何实际使用这些数据?存储的文档对象有多大?回答这些问题,您的架构实际上会自行设计。
【讨论】:
...how about we use a neural network as the example;这是正确的,但后来我继续将它从小型、密集的人工神经网络交换到以brain 为代表的巨大、稀疏的自然网络。我现在就去纠正它。谢谢。
我会创建一个checkins 或visits 集合。当用户访问该餐厅时,会创建一个引用用户和餐厅的新文档。这是相当干净和简单的
【讨论】: