我很好奇如何构建一个拥有多对多关系的MongoDB,可能有数万条记录。
假设您有一个餐馆数据库,可以跟踪大量的餐馆和所有已经入住这些餐馆的人。因此,用户可能想要查看一个人并查看他们检查过的所有餐馆,还可以查找餐馆并查看已登记的所有人。
如何以一种有意义且易于搜索和更新的方式构建它?
答案 0 :(得分:4)
您提供的示例与大多数真实世界的多对多关系示例一样,实际上是少数到关系的示例。您可能有许多餐馆和许多用餐者,但与整套餐厅相比,任何一家餐厅只供应一小部分食客,大多数个人用餐者只会访问一小部分餐馆。这听起来像是一个稀疏链接的网络,其链路密度比明显低于1。
为了测量网络的链路密度(边缘密度),我们计算 现有链接的比率m与可能链接的总数。 对于N个节点的网络,网络链路密度为D = m / 0.5 * N *(N-1)完全连接网络的(最大)链路密度D为1. - Network-Science
但是,您询问了多对多,那么我们如何使用神经网络作为示例呢?神经网络通常形成密集网络,因此代表真正的多对多网络。在这种情况下答案很简单 - 不要使用mongoDB。使用根据您的特定要求定制的自定义结构和序列化策略。毕竟,真正的多对多关系几乎总是异常,因此可以证明具体的治疗方法。
话虽如此,可以在不牺牲丰富的文档结构的情况下实现对mongoDB中更常见的少数到关系的建模,以及如何实现这一点取决于您的访问模式。
因此,通过餐厅/餐馆网络示例,如果您通常要在其食客上查询餐馆,那么您将创建一个与每个餐厅一起保存的diner_ids数组。另一种方式意味着每个用餐者都会举办一系列restaurant_ids。两者都是为了双向查询能力。
必须小心,因为mongoDB中没有foreign_key约束,因此维护数据的引用完整性是您的责任。
如果性能对您来说最重要,那么您可能希望将数据嵌入到每个文档中,而不是使用id引用它。这是用于读取的更高性能选项(不是用于写入),因为所有数据都可以在一次命中中从磁盘中拉出。这意味着在更新数据值时需要做更多工作以确保数据的完整性,但通常这并不像它最初看起来那么可怕。用餐者经常改变名字的频率是多少?根据文档大小的不同,您可能不一定要嵌入完整的文档,数据的子集加上指向完整记录的ID通常都可以解决问题。
简而言之,mongoDB架构设计应该由应用程序要求驱动。不同应用程序的不同模式,而不是一个单片关系数据库来统治它们。数据的实际情况是什么?应用程序如何实际使用此数据?文件对象的存储量有多大?回答这些问题,您的架构将实际设计自己。
答案 1 :(得分:1)
我会创建一个checkins
或visits
集合。当用户访问该餐馆时,创建一个引用用户和餐馆的新文档。这是相当干净和直接的