我应该在更新的数据模型中使用hstore吗?

时间:2014-05-12 17:04:32

标签: postgresql hstore

在我的遗留数据库(Postgres 9.1)中,我有几个包含各种文档的表格(让我们说它们是父表'表格)。 此外,还有一个包含这些文档的各种参数的表格:

create table params (
    kind integer,
    docid integer,
    parname text,
    parvalue text,
    constraint params_pk primary key (kind, docid, parname));

一个文档可能有很多(parname,parvalue)对。 由于 kind 指向不同的表,因此不能将其用作外键。

由于 params 仅用于打印文档,因此多年来一直运作良好。 现在这个表包含5百万行,并且还需要数据用于其他目的。 所以现在是更新这个模型的时候了。

基本上 params 为文档插入一次,很少更新。它们将作为一个整体阅读(对于文档)。无需搜索特定的 parname

我有三个想法:

变体A. 根据父表将表 params 拆分为多个表,并使用 docid 作为外键。

变种B. 将表 params 拆分为变体A,并将(parname,parvalue)存储为hstore。

变体C. 在每个父表中添加一个hstore字段,并忘记其他表。

我没有使用hstore的经验。 每种变体的缺点和优点是什么?你会选哪一个?可以用一些奇怪的东西让我感到困惑吗?

2 个答案:

答案 0 :(得分:3)

如果您说需要使用文档获取字段,那么Denormalized hstore variant更好,因为服务器将能够从磁盘上的单个位置获取整个文档,而不是使用多个位置来索引连接文档与田地。我用hstore看到的唯一问题是一种有点不同寻常的语法。使用JSON可能更容易。 PostgreSQL 9.4将对(indexed) binary JSON提供出色的支持。 hstore作者使用二进制JSON是recommended,BTW。

因此,计划可能是在9.3中使用json列,然后在9.4中将其转换为jsonb

答案 1 :(得分:2)

我投票支持第三种选择。表越少,睡眠越好。

Hstore是为一级参数列表而发明的。它稳定,快速,简单,完全符合您的需求。前段时间我有类似的任务。我写了一个汇总以便于转换。

create or replace function hstore_add(hstore, text, text)
returns hstore language plpgsql 
as $$
begin
    return case
        when $1 isnull then hstore($2, $3)
        else $1 || hstore($2, $3) end;
end $$;

create aggregate hstore_agg (text, text) (
    sfunc = hstore_add,
    stype = hstore
);

我认为这可以节省你的时间。

select kind, docid, hstore_agg(parname, parvalue)
from params
group by 1, 2
order by 1, 2;