我假设您正在考虑数学上下文中的稀疏矩阵:
http ://en.wikipedia.org/wiki/Sparse_matrix (那里描述的存储技术用于内存存储(快速算术运算),而不是持久存储(低磁盘用法)。)
因为通常在客户端而不是在服务器端对这个矩阵进行操作,所以 SQL-ARRAY[] 是最好的选择!
问题是如何利用矩阵的稀疏性?这里是一些调查的结果。
设置:
- Postgres 8.4
- 具有双精度(8 字节)的 400*400 个元素的矩阵 --> 每个矩阵 1.28MiB 原始大小
- 33% 非零元素 --> 每个矩阵 427kiB 有效大小
- 使用约 1000 个不同的随机填充矩阵进行平均
参赛方式:
- 依靠使用 SET STORAGE MAIN 或 EXTENDED 的列的自动服务器端压缩。
- 只存储非零元素加上一个位图(
bit varying(xx)
),描述在矩阵中定位非零元素的位置。(一个双精度比一位大 64 倍。理论上(忽略开销)如果 <=98% 非零,则此方法应该是一种改进;-)。)服务器端压缩已激活。
- 用 NULL替换矩阵中的零。(RDBMS 在存储 NULL 方面非常有效。)服务器端压缩被激活。
(使用第二个索引-ARRAY[] 对非零元素进行索引不是很有希望,因此没有经过测试。)
结果:
- 自动压缩
- 没有额外的实施工作
- 没有减少网络流量
- 最小的压缩开销
- 持久存储 = 原始大小的 39%
- 位图
- 可接受的实施工作
- 网络流量略有下降;依赖于稀疏性
- 持久存储 = 原始大小的 33.9%
- 用 NULL 替换零
- 一些实现工作(API 需要知道在构造 INSERT 查询时在哪里以及如何在 ARRAY[] 中设置 NULL)
- 网络流量没有变化
- 持久存储 = 原始大小的 35%
结论:从 EXTENDED/MAIN 存储参数开始。如果您有空闲时间调查您的数据并使用我的测试设置和您的稀疏度级别。但效果可能低于你的预期。
我建议始终使用矩阵序列化(例如行主顺序)加上两个整数列作为矩阵维度 NxM。由于大多数 API 使用文本 SQL,因此您为嵌套的“ARRAY[ARRAY[..]、ARRAY[..]、ARRAY[..]、ARRAY[..]、..]”节省了大量网络流量和客户端内存!!!
特巴斯
CREATE TABLE _testschema.matrix_dense
(
matdata double precision[]
);
ALTER TABLE _testschema.matrix_dense ALTER COLUMN matdata SET STORAGE EXTERN;
CREATE TABLE _testschema.matrix_sparse_autocompressed
(
matdata double precision[]
);
CREATE TABLE _testschema.matrix_sparse_bitmap
(
matdata double precision[]
bitmap bit varying(8000000)
);
将相同的矩阵插入所有表中。具体数据以某表为准。由于未使用但已分配的页面,请勿更改服务器端的数据。或者做一个真空。
SELECT
pg_total_relation_size('_testschema.matrix_dense') AS dense,
pg_total_relation_size('_testschema.matrix_sparse_autocompressed') AS autocompressed,
pg_total_relation_size('_testschema.matrix_sparse_bitmap') AS bitmap;