postgresql:在数组内部ON UPDATE CASCADE

时间:2011-10-03 15:36:19

标签: arrays postgresql database-design foreign-keys

我在表A上有一个自然的主键。

在表B中,我想要一个对A的外键引用数组。

是否可以在数组的元素上指定ON UPDATE CASCADE,这样当表A中的主键值发生更改时,B中的数组将被修改。 或者我应该将数组规范化为一个单独的表吗?

2 个答案:

答案 0 :(得分:2)

规范化这将允许您在外键约束中使用标准ON UPDATE CASCADE。它会更快,因为系统可以使用简单的索引。这应该会给你 3 表。需要更多的磁盘空间。但值得一提:

  • 表a
  • table b
  • 表a_b - 实现n:m relationship

否则,你必须编写一个触发函数来查找并将B中的所有参考替换为主A的值。

答案 1 :(得分: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更新一半的值。