我正在使用 MongoDB,我的字段名称是 10-20 个字符的字符串。一个典型的文档由 30.000 列组成,其中大部分是浮点数,如 1.2、10.5、2.55。它的大小是 1MB。
长字符串字段名称会影响 MongoDB 数据库的大小吗?
这在开发人员常见问题解答中包含,一些相关摘录:
MongoDB 将所有字段名称存储在每个文档中。对于大多数文档,这代表了文档所用空间的一小部分;但是,对于小文档,字段名称可能会按比例表示大量的空间
而且,只是关于索引的一个说明:
较短的字段名称不会减少索引的大小,因为索引具有预定义的结构
因此,是的,减少字段名称大小将使存储更高效,尽管它不会对索引大小产生影响。您所做的节省是否值得(相对于描述性的丧失)将取决于您。作为近似值,如果您将字段名称从 20(例如)减少到 2 个字符,则每个字段可能会节省大约 16 个字节,这意味着文档大小将减少 40% 以上(~400k)。
这是使用 MongoDB shell 进行估算的一种简单方法:
$ ./mongo --nodb
MongoDB shell version: 3.0.2
> testObject = {"12345678901234567890" : 1.23324}
{ "12345678901234567890" : 1.23324 }
> Object.bsonsize(testObject)
35
> testObject = {"1" : 1.23324}
{ "1" : 1.23324 }
> Object.bsonsize(testObject)
16
> testObject = {"12" : 1.23324}
{ "12" : 1.23324 }
> Object.bsonsize(testObject)
17
Run Code Online (Sandbox Code Playgroud)
该Object.bsonsize方法将以字节为单位为您提供任何文档的近似大小,但不包括在数据库中存储文档时实际使用的填充、索引等。因此,这些都是非常近似的数字 - 我建议使用实际数据进行测试以获得更明确的示例。
我执行了一些基准测试,将 Excel 中的 252 行数据上传到两个集合 testShortNames 和 testLongNames 中,如下所示:
长名称:
{
"_id": ObjectId("6007a81ea42c4818e5408e9c"),
"countryNameMaster": "Andorra",
"countryCapitalNameMaster": "Andorra la Vella",
"areaInSquareKilometers": 468,
"countryPopulationNumber": NumberInt("77006"),
"continentAbbreviationCode": "EU",
"currencyNameMaster": "Euro"
}
Run Code Online (Sandbox Code Playgroud)
简称:
{
"_id": ObjectId("6007a81fa42c4818e5408e9d"),
"name": "Andorra",
"capital": "Andorra la Vella",
"area": 468,
"pop": NumberInt("77006"),
"continent": "EU",
"currency": "Euro"
}
Run Code Online (Sandbox Code Playgroud)
然后,我获取了每个文件的统计信息,保存在磁盘文件中,然后对两个文件进行“比较”:
pprint.pprint(db.command("collstats", dbCollectionNameLongNames))
Run Code Online (Sandbox Code Playgroud)
下图显示了两个感兴趣的变量:大小和存储大小。我的阅读表明 storageSize 是压缩后使用的磁盘空间量,基本上 size 是未压缩的大小。所以我们看到 storageSize 是相同的。显然,Wired Tiger 引擎压缩字段名的效果相当好。

该问题仅询问磁盘空间。但是,我随后运行了一个程序来检索每个集合中的所有数据,并检查了响应时间。
尽管这是一个亚秒级的查询,但长名称始终花费大约 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
Run Code Online (Sandbox Code Playgroud)
在 Python 中,我只是执行了以下操作(我必须实际循环遍历项目以强制读取,否则查询仅返回游标):
results = dbCollectionLongNames.find(query)
for result in results:
pass
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3498 次 |
| 最近记录: |