2009-06-04 7 views
40

J'ai une table qui a une clé primaire composée de deux colonnes (id_produit, attribut_id). J'ai une autre table qui doit faire référence à cette table. Comment puis-je créer une clé étrangère dans l'autre table pour la lier à une ligne de la table avec deux clés primaires?Clé étrangère à plusieurs colonnes dans MySQL?

Répondre

67

Quelque chose comme cela devrait le faire:

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 requiert des clés étrangères à indexer, d'où l'index sur les colonnes faisant référence
  • Utilisation de la syntaxe de contrainte permet de nommer une contrainte , ce qui rend plus facile de modifier et de laisser tomber plus tard si nécessaire.
  • InnoDB applique les clés étrangères, contrairement à MyISAM. (La syntaxe est analysée mais ignorée)
+1

FWIW, MyISAM analyse et ignore la syntaxe des clés étrangères. Et vous n'avez pas besoin de déclarer l'index de manière redondante depuis MySQL 4.1.2. –

+0

Assurez-vous également que les deux tables sont InnoDB puisque, comme Bill le fait remarquer, MyISAM ne supporte pas les clés étrangères. – Abinadi

+7

J'ai été rejeté deux fois en raison de l'index explicite? Dur. J'ai fait remarquer que InnoDB était nécessaire. – PatrikAkerstrand

3

Il ne peut y avoir qu'une seule clé primaire sur une table. Le fait en peut se composer de plus d'un champ n'augmente pas le nombre de clés primaires, il y en a toujours un.

Étant donné qu'une partie de la paire PK n'est pas unique, vous devez évidemment créer une clé étrangère qui fait également référence à deux champs: REFERENCES t1 (f1, f2).

1

Si nous voulons une logique de clé étrangère certains comme cette

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

Exemple:

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

CHOISIT:

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) 
Questions connexes