30

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

我正在创建一个应用程序,用户可以在其中上传歌曲列表(标题、艺术家等),但我不确定我是否应该为所有用户提供一个 songList 集合,或者为每个单独的用户提供一个单独的 songList.user# 集合。用户只能查询与他们关联的歌曲,因此用户 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"}
  • 优点
    • 要查询的更小的集合大小
  • 缺点
    • 可维护性
      • 1,000 个用户意味着 1,000 个集合

与拥有“用户”字段的单个集合

db.songList.find({"user":"A"})
{"title": "Some song of user A", "artist": "Some artist of user A", "user": "A"}
  • 优点
    • 如果需要,可以灵活地跨用户查询
  • 缺点
    • 表现

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

提前致谢。

4

2 回答 2

15

我建议NOT为每个用户单独收集。

阅读文档

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

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

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

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

更新

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

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

于 2012-12-10T07:18:52.977 回答
9

MongoDB 擅长水平扩展。它可以跨动态集群对集合进行分片,以生成快速、可查询的数据集合。

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

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

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

于 2012-12-10T08:24:04.987 回答