Arrays postgresql:关于数组内部的更新级联

Arrays postgresql:关于数组内部的更新级联,arrays,postgresql,database-design,foreign-keys,Arrays,Postgresql,Database Design,Foreign Keys,我在表a上有一个自然主键 在表B中,我想要一个对A的外键引用数组 是否可以在数组的元素上指定ON-UPDATE-CASCADE,这样当表a中主键的值更改时,B中的数组就会被修改。 或者我应该将数组归一化到一个单独的表中吗?归一化这将允许您在外键约束中使用标准。这将大大加快速度,因为系统可以使用简单的索引。这将为您提供3张表。需要更多的磁盘空间。但每一点都值得: 表a 表b 表a_b——实现n:m关系 否则,您必须编写一个触发器函数来查找B中的所有引用,并将其替换为主a的值 是否可以在 数组,

我在表a上有一个自然主键

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

是否可以在数组的元素上指定ON-UPDATE-CASCADE,这样当表a中主键的值更改时,B中的数组就会被修改。
或者我应该将数组归一化到一个单独的表中吗?

归一化这将允许您在外键约束中使用标准。这将大大加快速度,因为系统可以使用简单的索引。这将为您提供3张表。需要更多的磁盘空间。但每一点都值得:

  • 表a
  • 表b
  • 表a_b——实现n:m关系
否则,您必须编写一个触发器函数来查找B中的所有引用,并将其替换为主a的值

是否可以在 数组,这样当表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".

而且,当你眯起眼睛,把头向右倾斜时,这是有道理的。在关系模型中,每一行和每一列的交集只包含一个值。因此,您不应该通过更新级联上的
更新半个值

同意-您肯定希望这样做。你不想陷入混乱,缓慢的触发。一点额外的磁盘空间可以为您节省大量的麻烦和查询时间。嗯,虽然我没有提到这一点,但我正在对现有的A_b表进行非规范化处理。因为我在a中有复合/自然主键,所以在本例中,少量额外的磁盘空间使磁盘空间使用量增加了一倍以上,这是非常重要的。@EoghanM:在本例中,我将使用代理主键。添加一个串行列作为主键(或唯一键)。@Erwin,实际上没有想到这一点-将作为一个解决方案进行研究,谢谢!