我想有效地在数据库(特别是PostgreSQL)中存储“set”,但我不确定如何有效地执行此操作。
有几个选项可供选择:
以文本或二进制列的形式存储为列表({'first item', 2, 3.14}
)。这具有在插入数据库和拔出时需要解析的缺点。对于仅一组文本字符串,这似乎工作得很好,并且解析是最小的。对于任何更复杂的事情,解析变得困难。
在二进制列中存储为pickle。这似乎应该很快,并且它是完整的(任何可选择的工作),但不能跨语言移植。
以json形式存储(作为二进制对象或文本流)。比纯文本更大的问题,但更好地定义解析。
还有其他选择吗?有没有人有这些经验?
答案 0 :(得分:2)
您要做的是在表格中的一行与该组成员之间存储一对多的关系。
您的解决方案都不允许SQL查询集合的成员。你不能做select * from mytable where 'first item' in myset
之类的事情。相反,您必须检索text / blob并使用另一种编程语言来解码或解析它。这意味着如果你想对集合的元素进行查询,你必须每次都进行全表扫描。
我非常不愿意让你在 my 数据库中做一些类似的事情。
我认为你应该把你的集合分成一个单独的表。我的意思是(因为这显然不像我想象的那么明显),每个元素元素一行,索引你引用的表的主键,或者,如果你不强制执行重复项以一点额外空间为代价,你引用的表的主键 + 设置元素值。
由于你的set元素看起来是异构类型,我认为将它们存储为字符串没什么坏处,只要你以某种方式规范化数字。
答案 1 :(得分:1)
可能的方法之一是JSONB阵列。它能够存储任何类型的元素,并且可以编制索引以提高搜索速度:
create table t as
select '["first item", 2, 3.14]'::jsonb as x
from generate_series(1,100000);
insert into t values('["second item", 3, 2.72]');
create index idx on t using gin(x);
explain analyse select * from t where x @> '3';
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ QUERY PLAN │
╞═══════════════════════════════════════════════════════════════════════════════════════════════════════════════╡
│ Bitmap Heap Scan on t (cost=36.78..327.18 rows=100 width=47) (actual time=0.055..0.056 rows=1 loops=1) │
│ Recheck Cond: (x @> '3'::jsonb) │
│ Heap Blocks: exact=1 │
│ -> Bitmap Index Scan on idx (cost=0.00..36.75 rows=100 width=0) (actual time=0.028..0.028 rows=1 loops=1) │
│ Index Cond: (x @> '3'::jsonb) │
│ Planning time: 0.188 ms │
│ Execution time: 0.121 ms │
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
explain analyse select * from t where x @> '[3, "second item"]';
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ QUERY PLAN │
╞═══════════════════════════════════════════════════════════════════════════════════════════════════════════════╡
│ Bitmap Heap Scan on t (cost=68.78..359.18 rows=100 width=47) (actual time=0.087..0.089 rows=1 loops=1) │
│ Recheck Cond: (x @> '[3, "second item"]'::jsonb) │
│ Heap Blocks: exact=1 │
│ -> Bitmap Index Scan on idx (cost=0.00..68.75 rows=100 width=0) (actual time=0.048..0.048 rows=1 loops=1) │
│ Index Cond: (x @> '[3, "second item"]'::jsonb) │
│ Planning time: 0.248 ms │
│ Execution time: 0.187 ms │
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
<强>缺点:强>