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

c08*_*089 16 mongodb

我对Kyle Banker的MongoDB In Action中的引用感到好奇:

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

我感兴趣的是在数据库服务器端没有优化它的原因.内存查找表中是否包含集合中的所有键名称是否会导致性能损失太大而不值得节省空间?

Sea*_*lly 10

你所指的通常被称为"密钥压缩"*.有几个原因导致它没有实施:

  1. 如果您希望它完成,您现在可以非常轻松地在Application/ORM/ODM级别执行此操作.
  2. 在所有情况下,它不一定是性能**优势 - 认为具有许多关键名称的集合和/或在文档之间变化很大的关键名称.
  3. 在您拥有数百万份文档之前,它可能无法提供可衡量的性能**优势.
  4. 如果服务器执行此操作,则仍必须通过网络传输完整的密钥名称.
  5. 如果压缩的密钥名称是通过网络传输的,那么可读性确实会受到使用javascript控制台的影响.
  6. 压缩整个JSON文档可能会提供更好的性能优势.

像所有功能一样,有一个成本效益分析来实现它,并且(至少到目前为止)其他功能提供了更多的"降压".

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

*键名称的内存查找表基本上是LZW样式压缩的一个特例 - 这或多或少是大多数压缩算法所做的.

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

更新

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

有两种压缩算法:snappyzlib.目的是使snappy成为全方位性能的最佳选择,并使zlib成为最大存储容量的最佳选择.

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

  • "关键名称的内存查找表基本上是LZW样式压缩的特例" - 问题在于压缩是*每个文档*.集合中有很多重复,但文档中没有多少重复. (3认同)