postgresql - 混合 "Index-like"btree 结构 - PostgreSQL 可以做到这一点吗?

标签 postgresql data-structures customization indexing b-tree

我是 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) 被标记为值,父键“蓝色”被标记为键。

由于这种数据类型不匹配在单个树中可能会很困惑,我认为理想的解决方案是“[btrees] in a btree”,其中“btree”是键,[btrees] 是每组的 btree键的值。

最佳答案

如果你真的坚持这样做,你可以将值存储为数组,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
[...]

其实你可以简单的定义一个 View 就是上面的查询。

一种更规范化的方法是有两个表:一个用于描述键,一个用于将它们与值相关联:

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) 将这些键值转换为实际数据值集(来自键值)。

关于postgresql - 混合 "Index-like"btree 结构 - PostgreSQL 可以做到这一点吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5288871/

相关文章:

java - 无法在 JavaFx 中创建 EntityManager

arrays - postgresql中的数组差异

c# - 创建一个非常简单的单循环列表 C#

algorithm - 用于确定矩形与较大矩形集的交集的数据结构

javascript - 如何创建html5自定义验证?

java - 自定义 JMenuBar(例如背景图像、突出显示颜色...)

postgresql - 如何在本地系统帐户下运行 PostgreSQL DB 服务?

sql - 使用 PostgreSQL 计算和添加在特定日期出现的不同值

algorithm - 我如何存储 gps 坐标以便轻松找到彼此靠近的坐标?

swift - Alamofire 调用中的额外参数 'method' - 使用自定义 ParameterEncoding