缩短MongoDB属性名称是否值得?

时间:2012-10-08 23:25:33

标签: mongodb database-schema

Blog rolling with mongoDB, express and Node.js中,作者提到缩短属性名称是个好主意:

  

....经常报告mongoDB的问题是   磁盘上数据的大小...每个记录都存储所有字段名称   ....这意味着它通常可以   更具空间效率的东西,比如't'或'b'   比起'头衔'或'身体',但是为了避免混淆,我会避免   除非确实需要,否则这个!

我知道如何做到的解决方案。我更感兴趣的是什么时候才真正需要?

6 个答案:

答案 0 :(得分:21)

引用Donald Knuth

  

过早优化是所有邪恶的根源(或者至少是大部分的   它在编程中。

构建您的应用程序然而似乎最合理,可维护和合乎逻辑。然后,如果您遇到性能或存储问题,请处理那些影响最大的问题,直到表现令人满意或收益递减法则意味着进一步优化没有意义。

如果您不确定特定设计决策(如长属性名称)的影响,请创建一个原型来测试各种假设(例如“将更短的属性名称节省更多空间”)。不要指望测试的结果是决定性的,但它可能会教你不想要学习的东西。

答案 1 :(得分:10)

保持有意义名称的优先级高于短名称的优先级,除非您自己的情况和测试提供了改变这些优先级的具体原因。

正如comments SERVER-863中所述,如果您使用带有WiredTiger存储选项的 MongoDB 3.0 + 且启用了snappy压缩,则长字段名称会变为<因为压缩有效地解决了你的缩短问题。

答案 2 :(得分:6)

自下而上:所以要保持紧凑,因为它仍然有意义。

我认为这并不是每个真正必需缩短为一个字母的名称。无论如何,你应该尽可能地缩短它们,并且你觉得它很舒服。假设您有一个用户名称:{FirstName,MiddleName,LastName} 您甚至可以选择名称:{first,middle,last} 。如果您感觉舒服,可以使用名称:{f,m,l} 您应该使用短名称:因为它会消耗磁盘空间,内存,因此可能会减慢您的应用程序速度(较少的对象要保留在内存中,较慢的查找时间由于更大的大小和更长的查询时间,因为搜索数据需要更长的时间)。 /> 一个好的模式文档可能会告诉开发人员t代表城镇而不是标题。根据您的堆栈,您甚至可以隐藏开发人员通过一些帮助工具来处理这些快捷方式来映射它。

最后我要说的是,没有指导你何时以及应该缩短你的模式名称。它在很大程度上取决于您的环境和要求。但是如果你能提供一个很好的文档来解释所有内容和/或提供工具来简化开发人员和管理员的生活,你就可以保持紧凑。无论如何管理员可能会直接与mongodb互动,所以我想不应该错过一个好的文档。

答案 3 :(得分:1)

如果使用verbose xml,尝试使用自定义名称改进它可能非常重要。 SERVER-863票证中的用户评论在他的情况下说;我&#39; m&#39;使用详细命名存储外部定义的XML对象:字段名可能是总记录大小的70%。因此,在I / O和内存效率方面,fieldname标记化可能是一个巨大的胜利。&#39;

答案 4 :(得分:1)

加上我的2美分..

在设计数据模型时,可以避免长命名属性(或“AbnormallyLongNameAttributes”)。在我之前的组织中,我们测试了保持简短的命名属性策略,例如,组织定义了4-5个字母编码的字符串,例如:

  1. 名字= FSTNM,
  2. 姓氏= LSTNM,
  3. 每月利润损失百分比= MTPCT,
  4. 年度销售预测= YOYSP,依此类推..)
  5. 虽然我们观察到查询性能有所提高,主要是由于通过网络传输的数据大小减少,或者(因为我们使用JAVA和MongoDB)MongoDB文档/ Java Map中“密钥”长度的减少堆空间,整体性能提升不到15%。

    在我个人看来,这是一种微观优化,为每个数据模型维护/设计管理数据属性字典的附加系统需要额外的成本(并且是一个巨大的麻烦)。在调试应用程序/应答客户端查询时,要求该系统具有组织范围的透明度。

    如果您发现自己处于这种策略性能提升高达20%的位置对您来说是有利可图的,可能是时候扩展您的MongoDB服务器/选择其他数据建模/查询策略,或者是完全选择一个不同的数据库。

答案 5 :(得分:1)

我进行了一个小基准测试,我将 252 行数据从 Excel 上传到两个集合 testShortNames 和 testLongNames 中,如下所示:

长名称:

{
    "_id": ObjectId("6007a81ea42c4818e5408e9c"),
    "countryNameMaster": "Andorra",
    "countryCapitalNameMaster": "Andorra la Vella",
    "areaInSquareKilometers": 468,
    "countryPopulationNumber": NumberInt("77006"),
    "continentAbbreviationCode": "EU",
    "currencyNameMaster": "Euro"
}

简称:

{
    "_id": ObjectId("6007a81fa42c4818e5408e9d"),
    "name": "Andorra",
    "capital": "Andorra la Vella",
    "area": 468,
    "pop": NumberInt("77006"),
    "continent": "EU",
    "currency": "Euro"
}

然后我获得了每个的统计信息,保存在磁盘文件中,然后对两个文件进行了“差异”:

pprint.pprint(db.command("collstats", dbCollectionNameLongNames))

下图显示了两个感兴趣的变量:size 和 storageSize。 我的阅读显示 storageSize 是压缩后使用的磁盘空间量,基本上 size 是未压缩的大小。所以我们看到 storageSize 是相同的。显然,Wired Tiger 引擎很好地压缩了字段名。 enter image description here

然后我运行了一个程序来检索每个集合中的所有数据,并检查响应时间。

即使是亚秒级的查询,长名称也始终需要大约 7 倍的时间。将较长的名称从数据库服务器发送到客户端程序当然需要更长的时间。

-------LongNames-------
Server Start DateTime=2021-01-20 08:44:38
Server End   DateTime=2021-01-20 08:44:39
StartTimeMs= 606964546  EndTimeM= 606965328
ElapsedTime MilliSeconds= 782
-------ShortNames-------
Server Start DateTime=2021-01-20 08:44:39
Server End   DateTime=2021-01-20 08:44:39
StartTimeMs= 606965328  EndTimeM= 606965421
ElapsedTime MilliSeconds= 93

在 Python 中,我只执行了以下操作(我必须实际遍历项目以强制读取,否则查询仅返回游标):

results = dbCollectionLongNames.find(query)
for result in results:
    pass