我是mongodb的新手,我的DB Schema设计面临两难选择:
我应该创建一个单独的集合还是将我的数据放入多个集合中(我们可以将这些类别称为)。
现在我知道很多这样的问题已被提出,但我认为我的情况有所不同有两个原因:
所以我的问题是:120个集合能提高查询性能吗?在我的情况下,这是一个有用的优化吗?
或者我应该去单一收藏+分片?
预计每个集合都会保存数百万份文档。如果只使用一个,它将存储数十亿个文档。
提前致谢!
-------编辑:
感谢您的回答。
事实上,120个系列只是一个自制限制,它并不是最佳选择:
集合中的数据与网络发布者相关。可能有数百万(任何网站都可以加入)。
我想理想的情况是,如果我可以为每个发布者创建一个集合(仅保存他们的数据)。但显然,由于mongo的限制,这是不可能的。
所以我提出了一个固定数量的集合的想法,至少以某种方式分发数据。喜欢:集合“A_XX”将为名称以“A”开头的出版商提供XX平台相关数据等。我们只支持其中的一些平台,因此120个集合应该绰绰有余。
在另一个网站上有人建议使用许多数据库而不是许多集合。但这意味着开销,然后我将不得不使用/管理许多不同的连接。
您如何看待这个?有更好的解决方案吗?
很抱歉我原来的问题不够具体。
提前致谢
答案 0 :(得分:15)
问题的编辑版本使实际需求更加清晰:您有一个可能会变得非常大的集合,并且您需要一种方法来对数据进行分区。人工收集限制是您自己计划的分区方案。
在这种情况下,我认为您最好使用单个集合并利用MongoDB的auto-sharding功能将数据和工作负载分发到多个服务器。多个集合仍然是一种有效的方法,但不必要地使您的应用程序代码复杂化。部署与利用核心MongoDB功能。假设您choose a good shard key,您的数据将在分片中自动平衡。
您不必立即进行碎片;您可以推迟决定,直到您看到您的工作负载实际上需要更多的写入比例(但在您需要时知道该选项)。在决定进行分片之前,您还有其他选择,例如升级服务器(特别是磁盘和内存)以更好地支持您的工作负载。相反,您不希望等到系统在分片之前被工作负载压碎,因此您肯定需要监控增长。我建议使用10gen提供的免费MongoDB Monitoring Service (MMS)。
在另一个网站上有人建议使用许多数据库而不是许多集合。但这意味着开销,然后我将不得不使用/管理许多不同的连接。
多个数据库会增加更多的管理开销,并且可能过度使用并且可能对您的用例有害。存储在数据库级别进行分配,因此120个数据库将占用比具有120个集合的单个数据库更多的空间。
如果您可以计划固定数量的集合(根据原始问题描述120),我认为采用这种方法而不是使用单一集合更有意义。
注意:下面的设计注意事项仍然适用,但由于问题已更新以阐明多个集合是一种尝试的分区方案,因此对单个集合进行分片将是一种更直接的方法。
使用单独收藏的动机是:
单个大型集合的文档可能必须包含一些集合子类型的指示,这可能需要添加到多个索引中,并且可能会显着增加索引大小。对于单独的集合,子类型已隐含在集合命名空间中。
在集合级别启用了分片。单个大型集合仅为您提供“全有或全无”方法,而单个集合允许您控制需要分片的数据子集并选择更合适的分片键。
您可以使用compact
命令对各个集合进行碎片整理。 注意: compact
是阻止操作,因此HA生产环境的正常建议是部署副本集并使用滚动维护(即首先压缩辅助节点,然后逐步降低和压缩小学)。
MongoDB 2.4(和2.2)目前具有数据库级写锁定粒度。实际上,对于绝大多数用例而言,这并未证明是一个问题,但是如果需要,多个集合可以让您更轻松地将高活动集合移动到单独的数据库中。
继上一点之后..如果您将数据放在单独的集合中,这些将能够利用集合级锁定的未来改进(请参阅MongoDB Jira问题跟踪器中的SERVER-1240 )。
答案 1 :(得分:2)
这里的主要问题是,如果将集合分离到同一个数据库中,那么在当前的MongoDB版本中,您将获得很少的性能。要在单个集合设置中获得任何类型的额外性能,您需要将集合移动到单独的数据库中,然后您将有操作开销来判断您应该查询的数据库等。
所以是的,你可以很容易地获得120个收藏,但是,由于:https://jira.mongodb.org/browse/SERVER-1240没有实施(很快就会),你现在无法获得任何收益。
在一个系列中容纳数十亿份文件并不算太糟糕。我认为,即使你要将它放在单独的集合中,它也可能不会在单个服务器上,就像分割单个集合一样,因此在这种情况下,由于多服务器设置而导致的任何速度降低也无关紧要。
在我个人看来,使用单个集合更容易。