Cer*_*rin 18 sql postgresql relational-database sparse-matrix
在PostgreSQL中表示稀疏数据矩阵的最佳方法是什么?我看到的两个明显的方法是:
将数据存储在单个表中,每个表都有一个单独的列(可能是数百万),但未使用的功能的默认值为NULL.这在概念上非常简单,但我知道在大多数RDMS实现中,这通常非常低效,因为NULL值通常会占用一些空间.但是,我读了一篇文章(遗憾的是找不到它的链接),声称PG没有占用NULL值的数据,使其更适合存储稀疏数据.
创建单独的"行"和"列"表,以及用于链接它们并在该行存储列值的中间表.我相信这是更传统的RDMS解决方案,但它有更多的复杂性和开销.
我还发现了PostgreDynamic,它声称可以更好地支持稀疏数据,但我不想仅仅为了这个功能而将整个数据库服务器切换到PG分支.
还有其他解决方案吗?我应该使用哪一个?
Teb*_*bas 15
我假设您正在考虑数学上下文中的稀疏矩阵:http: //en.wikipedia.org/wiki/Sparse_matrix(其中描述的存储技术用于存储器存储(快速算术运算),而不是持久存储(低磁盘)用法).)
由于人们通常在客户端而不是服务器端对此矩阵进行操作,因此SQL-ARRAY []是最佳选择!
问题是如何利用矩阵的稀疏性?这里是一些调查的结果.
建立:
竞争方法:
bit varying(xx)).(一个双精度比一位大64倍.理论上(忽略开销),如果<= 98%非零,则该方法应该是改进;-).)服务器端压缩被激活.(使用第二个索引-ARRAY []索引非零元素并不是很有希望,因此没有经过测试.)
结果:
结论:从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)
);
Run Code Online (Sandbox Code Playgroud)
将相同的矩阵插入所有表中.具体数据取决于特定表.由于未使用但已分配的页面,请勿更改服务器端的数据.或做一个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;
Run Code Online (Sandbox Code Playgroud)
一些解决方案浮现在脑海中,
1)将您的功能分成通常设置在一起的组,为每个组创建一个表,与主数据具有一对一的外键关系,仅在查询时加入表所需的表
2)使用EAV反模式,使用主表中的外键字段以及字段名和值列创建"功能"表,并将功能存储为该表中的行而不是主表中的属性表
3)与PostgreDynamic的工作方式类似,为主表中的每个"列"创建一个表(它们为这些表使用单独的命名空间),并创建函数以简化(以及有效索引)访问和更新数据那些表
4)使用XML或VARCHAR在主数据中创建一个列,并在其中存储表示数据的一些结构化文本格式,使用功能索引创建数据索引,编写更新数据的函数(或者如果您使用XML函数正在使用那种格式)
5)使用contrib/hstore模块创建一个类型为hstore的列,该列可以保存键值对,并且可以索引和更新
6)住着很多空地
| 归档时间: |
|
| 查看次数: |
8360 次 |
| 最近记录: |