让我根据我的全球知识和经验给你一些提示:
使用较短的字段名称
MongoDB 为每个文档存储相同的键。这种重复会导致磁盘空间增加。在像您这样的非常庞大的数据库上,这可能会产生一些性能问题。
优点:
- 文档的大小更小,因此磁盘空间更小
- 更多文件以适应 RAM(更多缓存)
- 在某些情况下,do 索引的大小会更小
缺点:
优化索引大小
索引大小越小,它就越适合 RAM,索引未命中的情况就越少。例如,考虑 git 提交的 SHA1 哈希。一个 git commit 多次由前 5-6 个字符表示。然后只需存储 5-6 个字符而不是所有哈希。
了解填充因子
对于文档中发生的更新导致昂贵的文档移动。该文档移动导致删除旧文档并将其更新到新的空位置并更新索引,这是昂贵的。
如果发生某些更新,我们需要确保文档不会移动。对于每个集合,都涉及一个填充因子,它告诉在文档插入期间,除了实际文档大小之外要分配多少额外空间。
您可以使用以下命令查看集合填充因子:
db.collection.stats().paddingFactor
手动添加填充
在您的情况下,您肯定会从一个会增长的小文档开始。在一段时间之后更新您的文档将导致多个文档移动。所以最好为文档添加一个填充。不幸的是,没有简单的方法来添加填充。我们可以通过在插入时向某个键添加一些随机字节来做到这一点,然后在下一个更新查询中删除该键。
最后,如果您确定某些键将来会出现在文档中,则使用一些默认值预先分配这些键,以便进一步更新不会导致文档大小的增长导致文档移动。
您可以获得有关导致文档移动的查询的详细信息:
db.system.profile.find({ moved: { $exists : true } })
大量集合 VS 少数集合中的大量文档
模式是取决于应用程序要求的东西。如果有一个庞大的集合,我们只查询最近 N 天的数据,那么我们可以选择单独的集合,并且可以安全地归档旧数据。这将确保正确完成 RAM 中的缓存。
创建的每个集合都会产生比创建集合的成本更高的成本。每个集合都有一个最小大小,即几个 KB + 一个索引 (8 KB)。每个集合都有一个关联的命名空间,默认情况下我们有一些 24K 的命名空间。例如,每个用户都有一个集合是一个糟糕的选择,因为它不可扩展。在某个时间点之后,Mongo 将不允许我们创建新的索引集合。
通常,拥有许多集合并没有显着的性能损失。例如,如果我们知道我们总是根据月份进行查询,我们可以选择每个月收集一次。
数据的非规范化
始终建议将查询或查询序列的所有相关数据保存在同一磁盘位置。您需要在不同的文档中复制信息。例如,在博客文章中,您需要将文章的评论存储在文章文档中。
优点:
- 索引大小将非常小,因为索引条目的数量会更少
- 查询将非常快,其中包括获取所有必要的详细信息
- 文档大小将与页面大小相当,这意味着当我们将这些数据放入 RAM 时,大多数时候我们不会将其他数据带入页面
- 文档移动将确保我们正在释放一个页面,而不是页面中可能不会用于进一步插入的一小块
封顶集合
Capped 集合的行为类似于循环缓冲区。它们是特殊类型的固定大小的集合。这些集合可以接收非常高速的写入和顺序读取。由于是固定大小,一旦分配的空间被填满,新的文件就会通过删除旧的文件来写入。但是,仅当更新的文档适合原始文档大小时才允许文档更新(使用填充以获得更大的灵活性)。