假设我有以下表,这些表实现了部件和对象之间的多对多关系,其中链接表具有唯一的密钥对(object_id,part_id),因此没有重复的行:
部分表:
part_id | part_name | part_zone --------+-----------+---------- 0 | part1.0 | top 1 | part2 | bottom 2 | part1.1 | top 3 | part3 | top
对象表:
object_id | object_name ---- ----+----------- 0 | object1 1 | object2 2 | object3 3 | object4
链接表:
object_id | part_id ------ --+--------- 0 | 0 0 | 1 1 | 1 1 | 2
还有一个限制因素是对象中每个part_zone应该只有一个。因此,如果要将part_zone列移动到链接表并将键更改为唯一对(object_id,part_zone),那么这将得到满足。我不想这样做,因为part_zone应该在part表中。在我的脑海中,我希望保持表格不变,但使用(object_id,part_zone)唯一键,其中part_zone通过part_id上的连接从部分表中提取。
希望我的意图很明确,但我不太确定这是最好的实施方式,或者我正在使用正确的术语来表达我所追求的目标。
提前感谢能够提供任何见解的任何人。
答案 0 :(得分:0)
您可以将part_zone
添加到Link
,并在(part_zone, part_id)
表中引用Part
的级联复合外键约束;这样,您可以按照建议在UNIQUE
上定义(object_id, part_zone)
约束,同时仍然可以从part_zone
表维护Part
:
ALTER TABLE Link ADD part_zone varchar(10); -- should be same size as in Part
ALTER TABLE Part ADD INDEX (part_zone, part_id);
UPDATE Link JOIN Part USING (part_id) SET Link.part_zone = Part.part_zone;
ALTER TABLE Link
ADD FOREIGN KEY (part_zone, part_id) REFERENCES Part (part_zone, part_id)
ON UPDATE CASCADE,
ADD UNIQUE INDEX (object_id, part_zone)
;
您甚至可以在INSERT
和UPDATE
上定义触发器,以填充Link
中的值,以便您无需手动执行:
CREATE TRIGGER link_insert BEFORE INSERT ON Link FOR EACH ROW
SET NEW.part_zone = (SELECT part_zone FROM Part WHERE part_id = NEW.part_id);
CREATE TRIGGER link_update BEFORE UPDATE ON Link FOR EACH ROW
SET NEW.part_zone = (SELECT part_zone FROM Part WHERE part_id = NEW.part_id);