17

我很好奇 Kyle Banker 的 MongoDB In Action 中的这句话:

考虑您选择的键名的长度很重要,因为键名存储在文档本身中。这与 RDBMS 形成对比,在 RDBMS 中,列名始终与它们所引用的行分开。因此,在使用 BSON 时,如果您可以使用 dob 代替 date_of_birth 作为键名,则每个文档将节省 10 个字节。这听起来可能不多,但是一旦您拥有 10 亿个这样的文档,只需使用较短的键名,您就可以节省近 10 GB 的存储空间。这并不意味着您应该花费不合理的长度来确保小的键名;理智点。但是,如果您期望有大量数据,那么节省键名将节省空间。

我对在数据库服务器端没有优化的原因很感兴趣。包含集合中所有键名的内存查找表是否会带来太多的性能损失,不值得潜在的空间节省?

4

3 回答 3

11

您所指的通常称为“密钥压缩”*。没有实施的原因有几个:

  1. 如果你想完成它,你现在可以很容易地在 Application/ORM/ODM 级别上完成它。
  2. 在所有情况下,这不一定是性能**优势——想想具有很多键名的集合,和/或在文档之间有很大差异的键名。
  3. 在您拥有数百万个文档之前,它可能根本无法提供可衡量的性能**优势。
  4. 如果服务器这样做,则仍然必须通过网络传输完整的密钥名称。
  5. 如果通过网络传输压缩的密钥名称,那么使用 javascript 控制台的可读性确实会受到影响。
  6. 压缩整个 JSON 文档可能会提供更好的性能优势。

像所有功能一样,实现它有一个成本效益分析,并且(至少到目前为止)其他功能提供了更多的“物有所值”。

完整的文档压缩正在[正在考虑][1] 用于未来的 MongoDB 版本。从 3.0 版开始可用(见下文)

* 用于键名的内存查找表基本上是 LZW 样式压缩的一种特殊情况——这或多或少是大多数压缩算法所做的。

** 压缩提供空间优势和性能优势。更小的文档意味着每个 IO 可以读取更多的文档,这意味着在一个固定 IO 的系统中,每秒可以读取更多的文档。

更新

MongoDB 3.0 及更高版本现在具有使用WiredTiger存储引擎的完整文档压缩功能。

有两种压缩算法可用:snappyzlib。目的是让 snappy 成为全面性能的最佳选择,而 zlib 成为最大存储容量的最佳选择。

在我的个人(非科学,但与商业项目相关)实验中,快速压缩(我们没有评估 zlib)显着提高了存储密度,而没有明显的净性能成本。事实上,在某些情况下,性能稍好一些,大致符合我之前的评论/预测。

于 2012-07-11T10:19:29.253 回答
3

我相信将键名与文档一起存储的最初原因之一是允许更容易扩展的无模式数据库。每个文档在更大程度上是自包含的,因为如果您将文档移动到另一台服务器(例如,通过复制或分片),您可以索引文档的内容,而无需引用单独或集中的元数据,例如映射键名称到更紧凑的键 ID。

由于 MongoDB 集合没有强制架构,因此同一集合中的每个文档的字段名称可能不同。在分环境中,对每个分片的插入(有意)是独立的,因此在文档级别,原始数据最终可能会有所不同,除非每个分片的键映射能够保持一致。

根据您的用例,键名可能会也可能不会占用相对于随附数据的大量空间。您始终可以通过将 YourFriendlyKeyNames 映射到较短的 DB 密钥等效项来解决应用程序/ODM 实现中的存储问题。

有一个开放的 MongoDB Jira 问题和一些进一步的讨论让服务器标记字段名称,您可以投票以帮助优先考虑在未来版本中包含此功能。

MongoDB 当前的设计目标包括动态模式的性能、复制和高可用性、自动分片和就地更新……一个潜在的权衡是一些额外的磁盘使用。

于 2012-07-11T10:36:16.710 回答
1

必须为每个查询在数据库中查找它将是一个严重的惩罚。
大多数驱动程序允许您指定 ElementName,以便MyLongButReadablePropertyName在您的域模型中成为mlbrpnmongodb。

因此,当您在应用程序中查询时,应用程序会转换查询:

db.myCollection.find({"MyLongButReadablePropertyName" : "some value"})

进入

db.myCollection.find({"mlbrpn" : "some value"})

高效的驱动程序,如 C# 驱动程序缓存此映射,因此无需为每个查询查找此映射。

回到你的问题的标题:

为什么在mongoddb的文档中存储键名

这是唯一可以搜索文档的方法吗?
如果没有存储键名,就没有可搜索的键。

希望这可以帮助

于 2012-07-11T09:50:32.917 回答