Mongodb 为什么MongodDB中的文档中存储了密钥名

Mongodb 为什么MongodDB中的文档中存储了密钥名,mongodb,Mongodb,我很好奇Kyle Banker's MongoDB在行动中的这句话: 重要的是要考虑你选择的关键名称的长度,因为关键名字存储在文档本身中。这与RDBMS形成对比,RDBMS总是将列名与其所引用的行分开。因此,当使用BSON时,如果您可以使用dob代替date_of_birth作为密钥名,那么每个文档将节省10个字节。这听起来可能不算多,但一旦你有了10亿个这样的文档,只需使用一个较短的键名,你就可以节省近10GB的存储空间。这并不意味着您应该使用不合理的长度来确保较小的键名;要理智。但是,如果您

我很好奇Kyle Banker's MongoDB在行动中的这句话:

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


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

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

因此,当您在应用程序中查询时,转换查询的应用程序可能是:

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

高效的驱动程序,比如C#驱动程序缓存这个映射,所以它不需要为每个查询都查找这个映射

回到问题的标题:

为什么MongodDB中的文档中存储了密钥名

这是搜索文档的唯一方法?
如果没有存储的密钥名称,就没有可以搜索的密钥


希望这有帮助

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

  • 如果您想完成它,目前可以在Application/ORM/ODM级别轻松完成
  • 在所有情况下,这并不一定是性能**的优势—想想具有大量键名的集合,和/或文档之间差异很大的键名
  • 在拥有数百万个文档之前,它可能根本无法提供可测量的性能**优势
  • 如果服务器执行此操作,则必须通过网络传输完整的密钥名
  • 如果压缩密钥名通过网络传输,那么使用javascript控制台时可读性确实会受到影响
  • 压缩整个JSON文档可能会提供更好的性能优势
  • 与所有功能一样,实现它也有成本效益分析,而且(至少到目前为止)其他功能提供了更多的“划算”

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


    *内存中的键名查找表基本上是LZW风格压缩的一个特例——这或多或少是大多数压缩算法所做的

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

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

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


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

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

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

    根据您的使用情况,键名可能会或可能不会占用与附带数据相关的大量空间。通过将FriendlyKeyNames映射到更短的DB密钥等价物,您始终可以从应用程序/ODM实现中解决存储问题

    有一个开放的MongoDB Jira问题和一些进一步的讨论,您可以投票决定在未来的版本中包含此功能的优先级


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

    “一个严重的惩罚”-哦,拜托。。。这是每个键的O(1)查找。O(1)一百万次的查询仍然比您需要做的多一百万次。。。。不过,我同意jira link@Stennie post的说法——如果标记化可以在服务器端实现,那就太好了。不过,这是一个次要的问题,因为我是用驱动程序编写的。既然您提到了这一点,那么问题的标题就有点不幸了(它是从引用中派生出来的)。如果你能想出更好的方法,请随意编辑。a在他们的JIRA sy上发表了类似的评论
    db.myCollection.find({"mlbrpn" : "some value"})