2009-06-04 18 views
40

Tengo una tabla que tiene una clave principal que consta de dos columnas (product_id, attribute_id). Tengo otra tabla que necesita hacer referencia a esta tabla. ¿Cómo puedo crear una clave externa en la otra tabla para vincularla a una fila de la tabla con dos claves principales?¿Clave externa de columna múltiple en MySQL?

Respuesta

67

Algo como esto debería hacerlo:

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 requiere claves externas para ser indexados, por lo tanto, el índice en las columnas de referencia
  • El uso de la sintaxis de restricción permite asignar un nombre a una restricción , haciendo que sea más fácil de modificar y soltar en un momento posterior si es necesario.
  • InnoDB impone claves externas, MyISAM no lo hace. (La sintaxis se analiza, pero ignoró)
+1

Fwiw, MyISAM analiza y ignora la sintaxis de la clave externa. Y no necesita declarar el índice de forma redundante desde MySQL 4.1.2. –

+0

También asegúrese de que ambas tablas sean InnoDB ya que, como señala Bill, MyISAM no admite claves externas. – Abinadi

+7

¿Fui rechazado dos veces debido al índice explícito? Duro. Señalé que InnoDB era necesario. – PatrikAkerstrand

3

Solo puede haber una clave principal en una tabla. El hecho de que puede consistir en más de un campo no aumenta el número de claves primarias, todavía hay una.

Como una parte del par de PK no es única, obviamente debe crear una clave externa que también haga referencia a dos campos: REFERENCIAS t1 (f1, f2).

1

Si queremos que la lógica de clave externa a algunos les gusta esta

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

Ejemplo:

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

selecciona:

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) 
Cuestiones relacionadas