2011-10-03 35 views
0

UPDATE CASCADE我已經表A.自然主鍵PostgreSQL的:裏面陣列

表B,我想有外鍵引用的數組A.

是否有可能在數組元素上指定ON UPDATE CASCADE,這樣當表A中的主鍵值發生變化時,B中的數組就會被修改。 或者我應該將數組標準化爲單獨的表格嗎?

回答

2

規範化這將允許您在外鍵約束中使用標準ON UPDATE CASCADE。這將是更快,因爲系統可以使用簡單的索引。這應該會給你表。需要更多的磁盤空間。但值得每一個位:

  • 表B
  • 表A_B - 實現多對多關係

否則你將不得不寫一個觸發功能來查找和替換在B中的所有引用都表示爲主A的值。

+0

同意 - 你一定要這樣做。你不想陷入混亂,緩慢的觸發器。多一點的磁盤空間爲您節省了大量的麻煩和查詢時間。 –

+0

嗯,雖然我沒有提到它,但我正在從現有的a_b表中去規範化。因爲我在a中有複合/自然主鍵,在這種情況下,額外的少量磁盤空間使磁盤空間使用量增加了一倍以上,並且非常重要。 – EoghanM

+0

@EoghanM:在這種情況下,我會訴諸代理主鍵。添加一個串行列作爲主鍵(或唯一鍵)。 –

0

是否可以在 數組的元素上指定ON UPDATE CASCADE,例如當表A中主鍵的值發生變化時,B中的 數組會被修改。

只有

  • 引用列和參考列都是相同類型的數組和
  • 的值具有相同數目的元素。

如果你想在一個表中插入數組元素的有效值,而在另一個表中存儲這些有效值的數組,它將不起作用。

OTOH,這確實工作,但只是部分。

create table a (
    str varchar[2] primary key 
); 

create table b (
    -- Room for two values from table a . . . 
    str varchar[4] primary key references a (str) on update cascade 
); 

insert into a values 
('{''A'', ''B''}'), 
('{''C'', ''D''}'), 
('{''E'', ''F''}'); 

insert into b values 
('{''A'', ''B''}'); 

update a set str = '{''A'',''C''}' 
where str = '{''A'',''B''}'; 

select * from b; 
{'A','C'} 

這很多的作品。但是如果你嘗試在表b中存儲兩個數組,你會得到一個錯誤。

insert into b values 
('{{"C", "D"}, {"E", "F"}}'); 
ERROR: insert or update on table "b" violates foreign key constraint "b_str_fkey" 
DETAIL: Key (str)=({{C,D},{E,F}}) is not present in table "a". 

而且,當你眯着眼睛,把你的頭向右傾斜時,這是有道理的。在關係模型中,每行和每列的交集只包含一個值。所以你應該不能通過ON UPDATE CASCADE來更新一半的價值。