Aquí tienes un caso de dos tablas primarias con PK y una tabla secundaria con las 2 PK como PK y FK:
Código sql:
Ver originalCREATE TABLE `bases` (
`BASE_ID` INT(11) NOT NULL,
`BASE_NOMBRE` VARCHAR(50) DEFAULT NULL,
PRIMARY KEY (`BASE_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `movil_identity` (
`PATENTE` VARCHAR(12) NOT NULL,
`INTERNO` VARCHAR(50) NOT NULL,
`MODELO` VARCHAR(30) NOT NULL,
`MARCA` VARCHAR(50) NOT NULL,
`FECHA_INI` DATE NOT NULL,
`FECHA_BAJA` DATE NOT NULL,
`ESTADO` VARCHAR(50) NOT NULL,
`PAIS` VARCHAR(50) NOT NULL,
`ULTIMO_VIAJE` INT(11) NOT NULL,
PRIMARY KEY (`PATENTE`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `bases_moviles` (
`BASE_ID` INT(11) NOT NULL,
`PATENTE` VARCHAR(50) NOT NULL,
PRIMARY KEY (`BASE_ID`,`PATENTE`),
KEY `BASE_ID` (`BASE_ID`),
KEY `PATENTE` (`PATENTE`),
CONSTRAINT `FK_Bases_Moviles_Movil_Identity` FOREIGN KEY (`PATENTE`) REFERENCES `movil_identity` (`PATENTE`),
CONSTRAINT `FK_Bases_Moviles_Bases` FOREIGN KEY (`BASE_ID`) REFERENCES `bases` (`BASE_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
El script está generado con MySQL Query Browser.
En este caso, la tercera tabla (que obviamente debe ser creada después de las otras dos, contiene solamente PK, nada más, porque precisamente esa es la función, controlar que cada par de PK solamente pueda aparecer una vez. Si puede darse que haya un par repetido, entonces, el sentido de esa tabla es incluir uno o más atributos que lo hacen distintivo. En ese caso ese tercer atributo o uno de ellos es una parte de la PK de esa tabla y tampoco puede repetirse la combinación de los tres.
Ese es el fundamento dado por el creador del modelo relacional para las relaciones N:N.