在PostgreSQL中提供版本化行的好方法是什么?如何查询?

时间:2012-02-13 00:39:02

标签: sql postgresql ddl

我想在表格中存储不同版本的不同文本和其他数据。对于文本,我的表格如下:

id BigSerial, PRIMARY KEY  
version Integer  
text Text  
origin BigInt

现在我想在此表中存储不同版本的文本,如下所示:

1,0,"My Text, first Version",null  
2,1,"My Text, second Version",1  
3,0,"My 2nd Text v1",null  
4,1,"My 2nd Text v2",3

我还不知道如何查询每组文本的版本号最高的行。

3 个答案:

答案 0 :(得分:3)

Bigserial身份证号码没有用处。

create temp table my_table (
  id integer not null,
  version integer not null check(version > 0),
  -- Give a lot of thought to whether text should also be unique. *I* think
  -- it probably should, but it's really application-dependent.
  text Text not null unique,
  primary key (id, version)
);

insert into my_table values 
(1, 1, 'My Text, first Version'),
(1, 2, 'My Text, second Version'),
(2, 1, 'My 2nd text v1'),
(2, 2, 'My 2nd text v2')

每个身份证的版本数量。

select id, count(*)
from my_table
group by id;

每个ID的当前版本。

with current_ver as (
  select id, max(version) as version
  from my_table
  group by id
)
select m.* from my_table m
inner join current_ver c on c.id = m.id and c.version = m.version

虽然我用公共表表达式编写了这个,但您可能想要创建当前版本的视图。我认为大多数访问此数据的应用程序都需要当前版本。

答案 1 :(得分:2)

由于并非所有的集文本中以同样的速度,有&#39可能会得到新的版本; S使得上赢得&#39版本号的断言没有真正的方法; t有涉及到这两个ID和原产地

例如,要知道" 5"是特定文本集的最新版本,您必须确定没有版本" 6"。这样做的方法是查看是否有一行版本" 6"具有版本" 5"的行的原点。但这只是减少了找到没有其他行声称它作为原点的行;你不需要版本号。

因此,您可以重新解释"我是否拥有最高版本号" as"没有其他行以我的id作为其起源"。如果没有其他行,那么这是您的最新行,您可以返回结果。您可以使用以下查询完成此操作:

select t.id 
from table parent
left join table descendants on parent.id = descendants.origin 
where descendants.id is null;

结果连接表中descendant.id为null的唯一行是最新的行。请注意,父级和子级都是同一个表中的别名。这就是所谓的" self-join",当您在单个表中存储分层数据(如版本控制机制)时,这很方便。

值得注意的是,这只能为您找到最新版本。如果您想知道这是哪个版本,那么您肯定会受益于您的版本列。否则,您最终将不得不进行递归查询,因为您事先不知道版本列表的深度。没有人喜欢写那些。

希望这有帮助。

答案 2 :(得分:0)

时间表扩展程序可能会有所帮助,如果您不想自己推送...

https://github.com/arkhipov/temporal_tables