MongoDB结构:单个集合与多个较小集合

MongoDB结构:单个集合与多个较小集合,mongodb,database-design,Mongodb,Database Design,我有一个一般的数据库结构问题。在我的场景中,我碰巧使用了mongodb 我正在创建一个应用程序,其中用户可以上载歌曲列表(标题、艺术家等),但不确定是否应该为所有用户创建一个歌曲列表集合,还是为每个用户创建一个单独的歌曲列表。用户#集合。用户只能查询与其关联的歌曲,因此用户A永远不会知道用户B的歌曲 代码示例: 每个用户有多个集合 专业人士 要查询的集合大小较小 缺点 维修性 1000个用户意味着1000个集合 与拥有“用户”字段的单个集合相比 专业人士 如果需要,可以灵活地

我有一个一般的数据库结构问题。在我的场景中,我碰巧使用了mongodb

我正在创建一个应用程序,其中用户可以上载歌曲列表(标题、艺术家等),但不确定是否应该为所有用户创建一个歌曲列表集合,还是为每个用户创建一个单独的歌曲列表。用户#集合。用户只能查询与其关联的歌曲,因此用户A永远不会知道用户B的歌曲

代码示例:

每个用户有多个集合

  • 专业人士
    • 要查询的集合大小较小
  • 缺点
    • 维修性
      • 1000个用户意味着1000个集合
与拥有“用户”字段的单个集合相比

  • 专业人士
    • 如果需要,可以灵活地跨用户查询
  • 缺点
    • 演出
我正试图建立一个赞成/反对的名单,但仍在犹豫之中。考虑到每个用户的歌曲将彼此隔离,哪种方法更好?我主要关心的是维护和查询性能


提前感谢。

我建议
不要
为每个用户单独收集

阅读

默认情况下,MongoDB的每个名称空间限制约为24000个 数据库每个名称空间为628字节,.ns文件的大小为16MB 默认

每个集合和每个索引都算作名称空间。因此如果 每个集合都有一个索引,我们最多可以创建12000个索引 收藏。--nssize参数允许您增加此限制 (见下文)

请注意,每个集合都有一定的最小开销——a 几KB。此外,任何索引都需要至少8KB的数据空间 b树页面大小为8KB。如果出现这种情况,某些操作可能会变慢 有很多集合,元数据被分页出来

因此,如果您的用户超过名称空间限制,您将无法优雅地处理它。而且,随着用户群的增长,它的性能也不会很高

更新

正如@Henry Liu在评论中提到的那样。对于使用WiredTiger存储引擎的Mongodb 3.0或更高版本,它将不再是限制


MongoDB非常擅长水平扩展。它可以在动态集群中共享一个集合,以生成一个快速、可查询的数据集合

因此,拥有较小的集合大小并不是一个真正的优点,我不确定这一理论是从哪里来的,它不在SQL中,也不在MongoDB中。切分的性能,如果做得好的话,应该与查询单个小数据集合的性能有关(开销很小)。如果不是这样,则说明您的切分设置错误

MongoDB不擅长垂直扩展,正如@Sushant所引用的,MongoDB的ns大小在这里将是一个严重的限制。quote没有提到的一点是,索引大小和计数也会影响ns大小,因此它描述了:

因此,如果每个集合都有一个索引,我们最多可以创建12000个集合。--nssize参数允许您增加此限制(见下文)


与其担心这样的事情,不如做点什么。你可能会通过构建它来发现什么最有效,而不是担心细节。同意@SomeKittens。也就是说,我会按照每个用户进行操作,因为这样更容易出错并将a的歌曲显示给B。无论如何,如果/当我有足够的用户时,我会担心优化。从安全角度看,每个用户有一个集合可以使用Mongodb的集合级访问控制机制。这样,就可以确保在数据库级别,一个用户永远不会访问另一个用户的数据。@Steven我很想知道您使用的是哪种设计,因为我目前也面临着类似的困境。感谢您提供的信息,但阅读下一段描述了如何使用--nssize来达到此限制(最大.ns文件大小为2GB)。因此,如果每个歌曲列表集合只有一个索引,理论上,在接近2GB之前,我可以拥有240000多个集合。(如果我每个集合有2个索引,那么这个限制几乎减少了一半)。显然,您可以以任何方式建模。我所做的只是推荐了一种优雅的方法:)感谢您的输入非常有用,在阅读此信息后,似乎没有必要使用多个集合,因为我可以在单个集合中完成我需要的操作,同时避免命名空间限制。从mongodb 3.0或更高版本开始,如果您使用WiredTiger存储引擎,它将不再是限制。谢谢@HenryLiu我早在2012年就写下了答案。谢谢你更新信息。我在回答中添加了更新。我读过这篇文章,这让我相信我会看到多个较小的集合带来显著的性能提升。你是说如果我在用户字段上有一个带有切分键的集合,我会看到类似的性能提升吗?有太多的未知因素无法确切说明他为什么会得到这些时间,查询时间如此依赖于硬件、索引、数据,标准化等。然而,他确实注意到,当他有大量记录时,查询速度很快,问题是当他在索引中使用少量选择性时(价格>100的类型记录数量较少),这让我相信他的索引对他的查询不太好。是的,像user\u id之类的东西上的切分键(这里有一点猜测,你真的应该为你的数据研究一下)将为包含用户id的查询产生不错的回报。但是,这不是切分的全部情况,我强烈建议您在立即认为用户id将解决切分问题之前,在这里和谷歌上进行一些搜索。感谢您的输入非常有用,如果我需要在我将对单个集合进行更多的研究
db.songList.userA.find()
{"title": "Some song of user A", "artist": "Some artist of user A"}

db.songList.userB.find()
{"title": "Some song of user B", "artist": "Some artist of user B"}
db.songList.find({"user":"A"})
{"title": "Some song of user A", "artist": "Some artist of user A", "user": "A"}