【发布时间】:2011-11-30 00:49:03
【问题描述】:
我在表 A 上有一个自然主键。
在表 B 中,我想要一个 A 的外键引用数组。
是否可以在数组元素上指定 ON UPDATE CASCADE,这样当表 A 中的主键值发生变化时,B 中的数组也会被修改。 还是我应该将数组规范化到一个单独的表中?
【问题讨论】:
标签: arrays postgresql database-design foreign-keys
我在表 A 上有一个自然主键。
在表 B 中,我想要一个 A 的外键引用数组。
是否可以在数组元素上指定 ON UPDATE CASCADE,这样当表 A 中的主键值发生变化时,B 中的数组也会被修改。 还是我应该将数组规范化到一个单独的表中?
【问题讨论】:
标签: arrays postgresql database-design foreign-keys
规范化这将允许您在外键约束中使用标准ON UPDATE CASCADE。它会快得多,因为系统可以为此使用简单的索引。这应该会给你 3 个表格。需要更多的磁盘空间。但值得每一点:
否则,您将不得不编写一个触发函数来查找 B 中的所有引用并将其替换为主 A 的值。
【讨论】:
是否可以在元素上指定 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更新半个值。
【讨论】: