我是mongodb的新手,我在DB模式设计方面面临着一个两难境地:

我应该创建一个集合,还是将数据放入多个集合(我想我们可以称之为这些类别).

现在我知道有人问过很多这样的问题,但我认为我的情况有所不同,原因有二:

  • 如果我 Select 了很多系列,我将不得不创造大约120个,仅此而已.这在future 不会增长.
  • 我知道我永远不需要查询或插入多个集合.因为集合X中的文档与其他集合中存储的任何文档都不相关,所以我总是只需要查询一个.不过,文档可能包含对数据库其他部分的引用(如用户ID等).

所以我的问题是:120个集合能否提高查询性能?对我来说,这是一个有用的优化吗?

还是我应该 Select 单集+分片?

每一个藏品预计都能保存数百万份文件.如果只使用一个,它将存储数十亿个文档.

提前谢谢!

-------编辑:

谢谢你的回答.

事实上,120个系列只是一个brew 的限制,并不是最理想的:

这些Collection 中的数据与网络出版商有关.可能有数百万个这样的网站(任何网站都可以加入).

我想理想的情况是,我可以 for each 出版商创建一个集合(只保存他们的数据).但显然,由于mongo的局限性,这是不可能的.

所以我想出了一个固定数量的集合的 idea ,至少以某种方式分发数据.比如:集合"A_XX"将为名称以"A"开头的出版商保存XX平台相关数据..等等.我们只支持其中的几个平台,所以120个集合就足够了.

在另一个网站上,有人建议使用多个数据库,而不是多个集合.但这意味着开销,然后我将不得不使用/管理许多不同的连接.

你怎么看?有更好的解决方案吗?

对不起,我的原始问题不够具体.

提前谢谢

推荐答案

单碎片收集

这个问题的编辑版本使实际需求更加清晰:您有一个可能会增长得非常大的集合,您需要一种划分数据的方法.人工收集限制是您自己计划的分区方案.

在这种情况下,我认为最好使用单个集合,并利用MongoDB的auto-sharding特性,根据需要将数据和工作负载分配到多个服务器.多个集合仍然是一种有效的方法,但不必要地使应用程序代码复杂化&;部署与利用MongoDB的核心功能.假设你是choose a good shard key,你的数据将自动平衡在你的碎片上.

你可以不必立即切碎;您可以推迟做出决定,直到看到您的工作负载实际上需要更大的写规模(但在需要时知道该选项就在那里).在决定切分之前,您还有其他 Select ,例如升级服务器(尤其是磁盘和内存),以更好地支持您的工作负载.相反,您不想等到系统被工作负载压垮后再进行分片,所以您肯定需要监控增长.我建议使用10gen提供的免费MongoDB Monitoring Service (MMS).

在另一个网站上,有人建议使用多个数据库,而不是多个集合.但这意味着开销,然后我将不得不使用/管理许多不同的连接.

多个数据库将显著增加管理开销,这可能会造成过度杀伤力,并可能对您的用例有害.存储是在数据库级别分配的,因此120个数据库将比一个包含120个集合的数据库消耗更多的空间.

固定收集数量(原始答案)

如果你能计划固定数量的藏品(根据你最初的问题描述为120件),我认为采取这种方法比使用单一的藏品更有意义.

NOTE:下面的设计考虑仍然适用,但由于问题已更新,以澄清多个集合是一种try 性的分区方案,因此将单个集合分片将是一种更简单的方法.

使用单独Collection 的动机是:

  • 单个大型集合的文档可能必须包含集合子类型的某些指示,这可能需要添加到多个索引中,并且可能会显著增加索引大小.对于单独的集合,子类型已经隐含在集合命名空间中.

  • 在集合级别启用分片.单个大型集合只提供"要么全有,要么全无"的方法,而单个集合允许您控制哪些数据子集需要分片,并 Select 更合适的分片键.

  • 您可以使用compact to命令对单个集合进行碎片整理.Note: compact是一种阻塞操作,因此对于HA生产环境,通常建议部署一个副本集并使用滚动维护(即,先压缩二级副本,然后退出并压缩主副本).

  • MongoDB 2.4(和2.2)目前具有数据库级写锁粒度.实际上,对于绝大多数用例来说,这并不是一个问题,但是如果需要,多个集合将允许您更轻松地将高活动性集合移动到单独的数据库中.

  • 关于上一点..如果您的数据位于不同的集合中,这些集合将能够利用集合级别锁定的future 改进(请参阅MongoDB Jira问题跟踪器中的SERVER-1240).

Mongodb相关问答推荐

MongoDB $lookup 查找字段值数组

将子元素的数组值提取到 mongodb 中的单个数组中?

MongoDB 按 created_at 月聚合

Spring Boot 升级后未映射 Mongo 模板结果

DB.collection('comments').find() 不工作

Mongoose - $project 嵌套的对象数组到数组的根级别

删除一对一和一对多引用 - Mongoose

MongoDB中的readPreference和readConcern有什么区别?

使用 mgo 从 golang 中的 Mongodb 中 Select 列

在 Mongo 中存储嵌套类别的最有效方法?

在 MongoDB 中按条件分组

有没有办法为 mongoose.js 聚合提供 allowDiskUse 选项?

Python - Pymongo 插入和更新文档

如何在 mongoDB 中聚合巨大的数组?

如何在 MongoDB 的 $match 中使用聚合运算符(例如 $year 或 $dayOfMonth)?

MongoDB服务器仍然可以在没有凭据的情况下访问

我在更新中对 $set 和 $inc 做错了什么

如何在mongoDB中检索其值以特定字符结尾的文档

在 MongoDB 中比较日期(moment.js)

无法从 mongodb 中删除集合