我是PostgreSQL的新手。我对我需要构建的混合数据库有一个非常不寻常的要求。从我见过的模块来看,对我来说似乎以下是可能的。
我需要能够将键 - [值]添加到索引中,而无需实际向表中添加数据。简单地说,我需要一个key- [values]存储,理想情况下是btree(查找速度)。索引结构是理想的。也许另一种结构可以做到这一点。
非常具体,我希望存储类似的内容:
KEY [IDs]
Blue 10, 20, 23, 47
Green 5, 12, 40
我不希望存储此数据并将其编入索引的开销。我只需要“索引但未存储”的数据即可。
同样重要的是能够查询这些结构并获取数据(ID),并能够在ID上执行INTERSECTS等,并在键上执行IN,BETWEEN,=等。
正如您可能猜到的那样,最终目标是ID的最终列表,然后将其发送到客户端,并随意查看。
修改
我不想要的是记录每个值的关键字。使用上面的例子,我不想存储{Blue,10},{Blue,20}等。我想存储{Blue,[10,20,23,47]}。
如果我将其存储为传统表格,我无法找到解决这个重复问题的方法。
再看看Blue,[10,20,23,47]},这在技术上只不过是一个btree,其中ID(10,20,23,47)被标记为值,而父键“蓝色”被标记为关键。
由于这个数据类型不匹配在单个树中可能会很混乱,我认为理想的解决方案是“btree中的[btree]”,其中“btree”是关键,而[btree]是每个组的btree。钥匙的价值。
答案 0 :(得分:3)
如果你真的坚持这样做,你可以将值存储为数组,intarray模块提供操作符来操作它们。那就是:
create table data(key text primary key, values int[] not null);
insert into data
values('Blue', '{10,20,23,47}'),('Green','{5,12,40}'),('Red', '{5,10,28}');
用这个你可以写:
select unnest(values) from data where key = 'Blue'
intersect
select unnest(values) from data where key = 'Red';
理想情况下,您需要一个聚合函数将int []转换为集合并计算交叉点等,但似乎没有提供它们。
实际上,这只是更典型结构的一个稍微紧凑的存储:
select key, unnest(values) as value from data;
key | value
-------+-------
Blue | 10
Blue | 20
Blue | 23
[...]
实际上,您只需将视图定义为上述查询即可。
更加规范化的方法是拥有两个表:一个用于描述键,一个用于将值与值相关联:
create table key_dimension(key_id serial primary key, key text not null unique);
insert into key_dimension(key) values('Blue'),('Green'),('Red');
create table key_value(key_id int not null references key_dimension(key_id), value int not null, primary key(key_id, value));
insert into key_value(key_id, value)
select key_id, unnest(values) from key_dimension join data using (key);
现在:
select value from key_value
where key_id = (select key_id from key_dimension where key = 'Red')
intersect
select value from key_value
where key_id = (select key_id from key_dimension where key = 'Blue')
因此,任何选择键值的查询都只需要对键组(key_dimension)运行,然后使用最小的合成键(key_id)将这些键转换为实际的数据值集(来自key_value)。