2012-12-10 82 views
22

我有一个通用数据库结构问题。在我的场景中,我碰巧使用了mongodb。MongoDB结构:单个集合vs多个较小的集合

我创建了一个应用程序,用户可以上传歌曲列表(标题,艺术家等),但不知道是否应该为所有用户提供一个songList集合,或者单独的songList.user#collection每个用户。用户只能查询与其相关的歌曲,因此用户A将永远不会知道用户B的歌曲。

代码示例:每用户

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"} 
  • 优点
    • 小集合的大小

      多个集合查询

  • 缺点
    • 可维护性
      • 1000个用户装置1000点的集合

VS与所属单个集合 '用户' 字段

db.songList.find({"user":"A"}) 
{"title": "Some song of user A", "artist": "Some artist of user A", "user": "A"} 
  • 优点
    • 灵活地在用户查询,如果需要不断arised
  • 缺点
    • 性能

我试图建立一个亲/ con list,但仍然在围栏上。鉴于每个用户的歌曲将彼此隔离,哪种方法更好?我主要关心的是维护和查询性能。

在此先感谢。

+3

而不是担心这样的事情,建立*的东西*。你可能会发现通过构建它会发挥什么效果,而不是担心细节。 – SomeKittens

+0

同意@SomeKittens。也就是说,我会为每个用户执行一次操作,因为更容易犯错并将A的歌曲显示给B.无论如何,如果/当我有足够的用户时,我会担心优化。 –

+0

安全方面,每个用户拥有一个集合,可以使用Mongodb的集合级访问控制机制。通过这种方式,可以确保在数据库级别一个用户不会访问他人的数据。 –

回答

8

MongoDB是在水平扩展很大。它可以在动态集群中对集合进行分片,以生成一个快速,可排队的数据集合。

所以拥有一个较小的集合大小并不是真正的专业人士,我不确定这个理论到了哪里,它不在SQL中,它不在MongoDB中。分片的性能如果做得好,应该与查询单个小数据集合的性能有关(开销很小)。如果它不是,那么你已经设置你的分片错误。

MongoDB在垂直伸缩方面并不是很好,正如@Sushant引用的那样,MongoDB的ns大小在这里将是一个严重的限制。引用没有提及的一点是,索引大小和计数也影响ns大小,因此它描述的原因如下:

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

+0

我读过[this](http://stackoverflow.com/questions/11514781/mongodb-performance-issue-single-huge-collection-vs-multiple-small-collections)这导致我相信我会看到一个重要的性能增益与多个较小的集合。你是否在说如果我在用户字段中有一个带有分片键的集合,我应该看到类似的性能增益? – Steven

+0

那里有太多的未知数,无法确切地说明他为什么要获得这些时间,查询时间依赖于硬件,索引,数据,规范化等等。但是他确实注意到,当他有大量记录时查询速度很快,问题是他在他的指数中使用了少量的选择性(价格低于100的类型记录的数量很少),这导致我认为他的指数对他的查询来说不是那么好。 – Sammaye

+1

是的,关于user_id之类的分片键(这里有一点猜测,你应该真的真的会为你的数据研究这个)会对包含user_id的查询产生不错的回报。然而,这不是完整的分片图片,我会强烈建议你在这里和谷歌之前做一些搜索,然后立刻想到user_id将解决你的分片问题。 – Sammaye

11

我会推荐NOT为每个用户分别收集。

阅读documentation

默认情况下,MongoDB的具有每 数据库约24,000命名空间的限制。每个命名空间为628字节,默认情况下,.ns文件为16MB,默认为 。

与每个索引一样,每个集合都计为一个名称空间。因此,如果每个集合有一个索引,我们可以创建多达12,000个 集合。 --nssize参数允许你增加这个限制 (见下文)。

请注意,每个集合有一定的最小开销 - 一个 几KB。此外,任何索引都需要至少8KB的数据空间,因为 的b-tree页面大小为8KB。如果 是很多集合并且元数据被分页,则某些操作可能会变慢。

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

UPDATE

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

docs.mongodb.org/manual/reference/limits/#namespaces

+0

感谢您的信息,但阅读下一段描述如何使用--nssize可以达到此限制(最大.ns文件大小为2GB)。因此,如果每个歌曲列表集合只有1个索引,理论上可以在接近2GB之前拥有240,000个集合。 (如果每集有两个索引,这个限制几乎减半)。 – Steven

+0

你显然可以用任何你想要的方式建模。我所做的一切都是推荐一个优雅的方法:) –

+0

感谢您的输入是非常有用的,阅读此信息多个集合似乎并不必要,因为我可以做我需要的一个集合,同时避免命名空间限制。 – Steven