2009-06-04 81 views
40

我有一个主键由两列组成的表(product_id,attribute_id)。我有另一个表需要引用此表。如何在另一个表中使外键将其链接到表中具有两个主键的行上?MySQL中的多列外键?

回答

67

像这样的东西应该做到这一点:

CREATE TABLE MyReferencingTable AS (
    [COLUMN DEFINITIONS] 
    refcol1 INT NOT NULL, 
    rofcol2 INT NOT NULL, 
    CONSTRAINT fk_mrt_ot FOREIGN KEY (refcol1, refcol2) 
         REFERENCES OtherTable(col1, col2) 
) ENGINE=InnoDB; 
  • MySQL的需要外键进行索引,因此在引用列的索引
  • 使用约束语法可以命名约束,如果需要,可以在稍后的时间更容易地进行修改和删除。
  • InnoDB强制外键,MyISAM不强制。 (语法分析,但是忽略)
+1

FWIW, MyISAM解析并忽略外键语法。自从MySQL 4.1.2以后,您无需重复声明索引。 – 2009-06-04 22:11:42

+0

还要确保这两个表都是InnoDB,因为Bill指出,MyISAM不支持外键。 – Abinadi 2009-06-05 03:28:42

+7

由于显式索引,我被拒绝了两次?苛刻。我确实指出InnoDB是必要的。 – PatrikAkerstrand 2009-06-05 05:50:32

3

表中只能有一个主键。可以由多个字段组成的事实不会增加主键的数量,但仍然有一个。

由于PK对的一部分不是唯一的,所以显然必须创建引用两个字段的外键:REFERENCES t1(f1,f2)。

1

如果我们想的逻辑外键一些这样

FOREIGN KEY COmments(issue_id) 
REFERENCES Bugs(issue_id) OR FeatureRequests(issue_id) 

例子:

CREATE TABLE Issues (
issue_id int PRIMARY KEY, 
status VARCHAR(20) 

); 




CREATE TABLE Comments (
comment_id int PRIMARY KEY, 
issue_type VARCHAR(20), -- "Bugs" or "FeatureRequests" 
issue_id BIGINT UNSIGNED NOT NULL, 
comment TEXT 
); 



CREATE TABLE Bugs (
issue_id int PRIMARY KEY, 
severity VARCHAR(20), 
FOREIGN KEY (issue_id) REFERENCES Issues(issue_id) 
); 
CREATE TABLE FeatureRequests (
issue_id int PRIMARY KEY, 
sponsor VARCHAR(50), 
FOREIGN KEY (issue_id) REFERENCES Issues(issue_id) 
); 





INSERT INTO Issues VALUES(1,'ON'),(2,'ON'),(3,'OFF'),(6,'OFF'),(8,'ON'); 

INSERT INTO Comments VALUES(1,'Bugs',1,'A'),(2,'Bugs',3,'B'),(3,'Bugs',1,'C'),(4,'Bugs',3,'D'),(5 ,'FeatureRequests',8,'L'), 
(6,'FeatureRequests',6,'W'),(7,'FeatureRequests',1,'ZX'); 



INSERT INTO Bugs VALUES(1,'severity_1'),(3,'severity_for_3'); 


INSERT INTO FeatureRequests VALUES(2,'sponsor_2_'),(8,'sponsor_for_8'),(1,'sponsor_for_1') 

选信号:

MariaDB [test]> SELECT * FROM Comments JOIN FeatureRequests ON Comments.issue_i 
d = FeatureRequests.issue_id AND Comments.issue_type= 'FeatureRequests'; 


MariaDB [test]> SELECT * FROM Comments JOIN Bugs ON Comments.issue_id = Bugs.is 
sue_id AND Comments.issue_type= 'Bugs'; 
+------------+------------+----------+---------+----------+----------------+ 
| comment_id | issue_type | issue_id | comment | issue_id | severity  | 
+------------+------------+----------+---------+----------+----------------+ 
|   1 | Bugs  |  1 | A  |  1 | severity_1  | 
|   2 | Bugs  |  3 | B  |  3 | severity_for_3 | 
|   3 | Bugs  |  1 | C  |  1 | severity_1  | 
|   4 | Bugs  |  3 | D  |  3 | severity_for_3 | 
+------------+------------+----------+---------+----------+----------------+ 
4 rows in set (0.00 sec)