2012-11-19 37 views
2

假設我有以下表格,它們實現了部分和對象之間的多對多關係,其中鏈接表具有唯一的密鑰對(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應該放在零件表中。在我的腦海中,我希望保持表格的原樣,但使用(object_id,part_zone)唯一鍵,其中part_zone通過part_id上的連接從part表中拉出。

希望我的意圖是清楚的,但我不太確定這是必然的最佳實現,或者我正在使用正確的術語來表達我所追求的。

在此先感謝任何能夠提供任何見解的人。

回答

0

您可以將part_zone添加到Link中,級聯化合物外鍵約束在Part表中引用(part_zone, part_id);這樣一來,就可以在(object_id, part_zone)定義UNIQUE約束的建議,同時還能夠從Part表保持part_zone

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) 
; 

你甚至可以定義在INSERTUPDATE觸發器來填充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); 
+0

非常感謝,這很好。無可否認,我並不完全理解所使用的更新和修改命令,因此爲什麼需要觸發器,但我會做更多的背景閱讀來圍繞它。乾杯。 – user764217