2

我有一個數據庫,一切都與外鍵鏈接,所以Postgres完全知道數據庫是如何佈局的。可能會壓縮主鍵/序列號?

好吧,讓我說我有Table1和Table2。

表1有3個字段。 RID,table2_rid,數據

所以table1.table2_rid引用table2.RID,這是用外鍵表示的。在這兩個RID字段是主鍵,並且是一個串行類型。

我想知道的是如何「凝結」主鍵?好比說你加5次的記錄和刪除的記錄數3.你的主鍵看起來像

1 
2 
4 
5 

嘛,我怎麼到處更新,使主鍵(以及相應的外鍵)可以濃縮成

1 
2 
3 
4 
+0

是重要的保留一切凝結?如果您的數據庫中有1000條記錄,並且您刪除了記錄1,則至少有兩個額外的更新需要運行。 – thetaiko 2010-02-19 19:08:09

+0

我正在談論更多關於你在桌面上做的事情,每天有很多插入/刪除操作,並像做每月維護任務一樣進行操作。 – Earlz 2010-02-19 19:09:03

回答

2

最好如果主鍵永不改變:重新編號它們是PITA。

如果您需要一個人類身份證,一個沒有空白的身份證,A. Elein Mustain顯示how to create a gapless sequence

+0

嗯,我在提前思考,因爲我們有一個或兩個非常常見的事務回滾(由於'serial'工作原理,主鍵的值增加了),並且有很多插入和更新,我只想知道如果在一兩年內我們開始面臨32位的翻滾問題,如果有辦法打擊這個問題的話。 – Earlz 2010-02-19 19:20:06

+2

2^31是* 68年*每秒插入一次。但是,如果32位可能不夠用,那麼使用serial8/bigserial而不是普通的serial,你就可以在0.1 terrayears中每秒鐘進行1000次插入。 – 2010-02-19 20:06:27

1

調查on update cascadeon delete cascade

create table table_1 (
    id integer 
     primary key, 
    name char(30) 
); 
create table table_2 (
    id integer 
     primary key, 
    table_1_id integer 
     references table_1 
     on update cascade 
     on delete cascade, 
    detail char(30) 
); 
1

除非常罕見的情況,PK序列中的缺口恰到好處,意圖擺脫它們是一個壞主意。

1

您可能不希望這樣做,因爲gapless sequences are problematic for performance

如果您想稍後將其作爲清理步驟,則可以使用rank()窗口函數來實現所需的效果。

CREATE TABLE table1 (id integer primary key); 
INSERT INTO table1 values (1),(2),(4),(5); 

CREATE TABLE table2 (
    id serial primary key, 
    rid integer references table1(id) ON UPDATE CASCADE 
); 

insert into table2 (rid) values (1),(1),(4),(4),(4),(5); 



UPDATE table1 
    SET id = gapless_id 
FROM (
    SELECT *, row_number() OVER() FROM table1 
) AS x(old_id, gapless_id) 
WHERE id = x.old_id; 

結果:

regress=# select * from table1 ; 
id 
---- 
    1 
    2 
    3 
    4 
(4 rows) 

如果您的FK的不ON UPDATE CASCADE可以ALTER TABLE,使他們如此。這將會很慢,特別是如果外鍵沒有索引。更快的方法是做的修改在兩個通道:

  • 開始事務
  • LOCK TABLE table1;
  • 添加NEW_ID列於表1和使用row_number()新的ID填充它如上圖所示
  • 降外鍵約束參照表1(ID)
  • 更新所有外鍵參考值new_id
  • 下降id在TABL E1
  • 表1的new_id列重命名爲id
  • 重新創建外鍵約束
  • 提交