2012-02-13 29 views
0

我想存儲不同的版本不同的文本和其他數據表。對於文字,我的表是這樣的:在PostgreSQL中提供版本化行的好方法是什麼?如何查詢他們?

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 

我還不知道如何查詢了每行文本的版本號最高。

回答

1

的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') 

每個id的版本數。

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 

雖然我寫了一個公共表表達式,你可能需要創建當前版本的視圖。我認爲大多數訪問這些數據的應用程序都需要當前版本。

+0

解決問題明智的方式。但我錯過了自動遞增(串行)ID字段的能力 - 在觸發器中不那麼難: CREATE SEQUENCE serial_my_table START 1; CREATE OR REPLACE FUNCTION ins_my_table() \t RETURNS觸發AS $$ \t BEGIN \t \t IF NEW.id IS NULL THEN \t \t \t NEW.id:= NEXTVAL( 'serial_my_table'); \t \t ELSE/*做一些很酷的東西,雖然可能會更好,因爲後觸發*/ \t \t END IF; \t \t RETURN NEW; \t END; \t $$ language'plpgsql'; DROP TRIGGER IF EXISTS tr_my_table_ins0 ON my_table; CREATE TRIGGER tr_my_table_ins0 \t插入之前my_table \t FOR EACH ROW EXECUTE PROCEDURE ins_my_table(); – Reinsbrain 2016-05-05 23:01:45

1

由於並非所有的集文本可以以相同的速度獲得新版本的,有做的版本號的斷言,就不必同時涉及ID和原產地沒有真正的方法。

例如,要知道,「5」是一個特定的文本集的最新版本,你必須證明沒有版本「6」。要做到這一點的方法是查看是否有一個版本爲「6」的行具有版本爲「5」的行的起源。但是,這只是找到一行沒有其他行聲稱它是原點的行;你不需要版本號。

因此,您可以將「我是否擁有最高版本號」的問題更改爲「是否沒有以我的ID爲原點的其他行」。如果沒有其他行,那麼這是你最新的一行,你可以返回你的結果。你可以用類似下面的查詢做到這一點:

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

唯一排在結果加入表,其中descendant.id將是空的是最新的人。請注意,父代和後代都是來自同一個表的別名。這就是被稱爲「自聯接」,是方便,當你存儲在一個表中的分層數據(如您的版本控制機制)做。

值得注意的是,雖然,這隻能找到最新版本爲您服務。如果你想知道哪個版本是,那麼你肯定會從版本專欄中受益。否則,你最終不得不做一個遞歸查詢,因爲你不會事先知道你的版本列表的深度。沒有人喜歡寫這些。

希望這會有所幫助。

相關問題