我假设你想到的是从数学角度考虑的稀疏矩阵:
http://en.wikipedia.org/wiki/Sparse_matrix(那里描述的存储技术是为了内存存储(快速算术运算),而不是持久性存储(低磁盘使用率)。)
由于通常在客户端而不是服务器端上对这些矩阵执行操作,因此 SQL-ARRAY[] 是最佳选择!
问题是如何利用矩阵的稀疏性?以下是一些调查结果。
设置:
- Postgres 8.4
- 具有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[..], ..]" !!!
Tebas
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)
);
将相同的矩阵插入所有表格中。具体的数据取决于特定的表。
由于未使用但已分配的页面,请勿在服务器端更改数据。或者可以执行VACUUM操作。
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;