PostgreSQL 将空列存储为位图,但是每行的开销很大。让我们计算一下两种存储方案的存储效率:
Average row length for wide table with thousands of columns:
23 bytes row header + 1000*1bit + average 2 bytes of alignment + 4 bytes id
+ 8 bytes timestamp + 10*8 bytes values = 242 bytes
Average number of bytes for storing each value separately:
10 values * (23 bytes row header + 1 byte alignment + 4 bytes id
+ 8 bytes timestamp + 4 bytes key + 8 bytes value) = 480 bytes
因此,千列的效率大约是按键拆分的两倍。单独存储密钥更有效的交叉点约为 0.45%。
然而,这种方法不会扩展得很远。PostgreSQL 中的最大列数限制为 1600。要进一步扩展它,您可以将值垂直拆分为许多表。这也会有一些查询问题,因为结果集也不能大于 1600。
另一种选择是将键值对编码为数组。在这种情况下,表的结构是(id serial, ts timestamptz, keys int2[], values int8[])。相同 1000 个属性的存储开销,1% 填充因子将是:
23 bytes row header + 1 byte alignment + 4 bytes id + 8 bytes timestamp
+ 20 bytes array header + 10*2 byte values + 20 bytes array header
+ 10*8 byte values = 176 bytes per entry
但是,在这种情况下,查询奇异值需要更多的基础设施。
如果需要更好的存储效率或灵活性,可以添加自定义数据类型。
我知道传感器数据的大量列模式已在许多 PostgreSQL 安装中成功使用。至于数据库的选择,我可能会有些偏颇,但我建议使用 PostgreSQL,因为您将拥有更好的工具,如数组、谓词索引和自定义数据类型来重新排列数据存储以提高效率。要记住的最重要的事情是从一开始就使用分区。