我还没有准备好让这件事过去,这就是为什么我重新思考这个问题,并编辑了Q(原文如下)。
我在周末项目中使用mongoDB,它需要DB中的一些关系,这就是痛苦的所在:
我有三个收藏品:
Users
Lists
Texts用户可以有文本和列表-列表‘包含’文本。文本可以出现在多个列表中。
我决定使用单独的集合(而不是嵌入),因为子文档并不总是出现在父文档的上下文中(例如。所有的文本,没有列在一个列表中)。
所以,我们需要做的就是把属于特定列表中的文本与这些列表联系起来。可以有无限的列表和文本,尽管列表会比较少。
与我最初想的不同,我也可以将引用放在每个文本文档中,而不是列表文档中的所有文本In中。这实际上会产生不同的效果,因为我可以用一个查询来查找列表中的每个片段。甚至可以索引那个引用。
var TextSchema = new Schema({
_id: Number,
name: String,
inListID: { type : Array , "default" : [] },
[...]文本也很少出现在许多列表中,因此数组不会真的爆炸。然而,问题仍然存在,这种扩展的可能性,或者实际上是用mongoDB实现它的更好的方法?限制文本列表的数量(可能)有帮助吗?有没有几个人的秘诀:许多关系?
如果能得到这样做的项目以及它是如何实施的(很少:许多关系),那就太棒了。我不敢相信,一旦需要一些关系,每个人都会回避mongo。
原始问题
我将把它分解为两个问题:( 1)让我们假设一个列表由5条文本组成。我如何引用清单中的文本?打开一个数组并将文本的_ids存储在那里?似乎这些阵列可能会长到月球和回来,减慢应用程序?另一方面,文本需要在没有列表的情况下使用,因此嵌入并不是一种选择。如果我想要一个包含100条文字的列表的所有文本..。听起来像是两个查询和一个包含100个字段的数组:-/。那么,这种引用方式是否是正确的方法呢?
var ListSchema = new Schema({
_id: Number,
name: String,
textids: { type : Array , "default" : [] },
[...]问题2)我发现这种方法是在删除文本时清除引用。它的引用仍然存在于每个包含文本的列表中,我不想遍历所有的列表来清除那些死引用。或者我会?有什么聪明的办法解决这个问题吗?仅仅是让文本保留引用(在哪些列表中)只会转移问题,所以这不是一种选择。
我想我不是第一个遇到这种问题的人,但我也没能找到关于如何“正确”的明确答案。
我还对这种引用的最佳实践(多对多?)的一般想法感兴趣。尤其是可伸缩性/性能。
发布于 2015-06-03 19:58:53
关系通常不是一个大问题,尽管某些涉及关系的操作可能是。这在很大程度上取决于您要解决的问题,也很大程度上取决于结果集的基数和键的选择性。
我编写了一个简单的试验床,它按照一个典型的长尾发行版生成数据。事实证明,MongoDB在人际关系方面通常比人们所相信的要好。
毕竟,关系数据库只有三个不同之处:
$in的手动子查询可以扩展到$in-clause中的数千项,当然,前提是引用值是索引的Iff您需要执行大连接,也就是说,如果您的查询是真正的关系型的,并且您需要相应地连接大量的数据,那么MongoDB可能不是一个很好的匹配。但是,关系数据库中需要的许多联接并不是真正的关系连接,它们是必需的,因为您必须将对象拆分为多个表,例如,因为它包含一个列表。
一个‘真正的’关系查询的例子可能是“找我所有的客户谁购买的产品,得到超过4星级评论的客户,排名高的营业额在6月份”。除非您构建了一个非常专门的模式来支持此查询,否则您很可能需要查找所有订单,按客户ids对它们进行分组,获取前n个结果,使用这些结果来使用$in查询分级,并使用另一个$in查找实际客户。不过,如果你能把自己限制在顶端,比如说六月的10k客户,这是三次往返旅行,还有一些快速的$in查询。
在典型的云硬件上,只要您的查询得到RAM中的索引的支持,并且网络还没有完全拥挤,这可能会在10到30 as的范围内。在这个例子中,如果数据太少的话,事情就会变得一团糟,例如,前10k的用户几乎不写超过4星光的评论,这将迫使您编写足够聪明的程序逻辑来继续迭代第一步,这既复杂又缓慢,但是如果这是一个非常重要的场景,那么可能有一个更适合的数据结构。
发布于 2015-05-26 13:46:42
将MongoDB与引用一起使用是解决性能问题的一个途径。最好的例子,什么不应该使用。这是一种m:n关系,m和n可以扩展到数百万。MongoDB在我们有1:n(few),1:n(many),m(few):n(many)的地方工作得很好。但在有m(many):n(many)的情况下就不是这样了。它显然会导致2次查询和大量的内务处理。
发布于 2015-06-05 20:57:57
我不知道这个问题是否仍然存在,但我也有类似的经验。
首先,我想说的是什么告诉官方的mongo 文档
当:您有一对一或一对多的model.For模型、多对多使用文档引用的关系时,请使用嵌入式数据模型。
我认为答案是),但这个答案提供了很多问题,因为:
每一项都是一项很大的责任,即使你在周末的项目中工作。这可能意味着您应该编写许多代码来提供系统的简单行为(例如,您可以看到如何在mongo 这里中实现事务)。
我不知道外键约束是如何实现的,我在mongo文档中也没有看到这方面的东西,这就是为什么我认为这是一个惊人的挑战(以及项目的风险)。
最后,mongo引用--它不是mysql join,也不是从父集合接收的所有数据,而是来自子集合的数据(就像mysql中表中的所有字段和联接表中的所有字段一样),您将只收到对另一个集合中的另一个文档的引用,您将需要使用此引用(取消引用)进行操作。它可以很容易地到达节点回调,但只有在情况下,你只需要从一个列表中的一个文本,但如果你需要所有的文本在一个列表-这是可怕的,但如果你需要所有的文本在多个列表-这将成为噩梦.
也许这不是我最好的经历..。但我觉得你应该考虑一下..。
https://stackoverflow.com/questions/30459764
复制相似问题