Cómo crear correctamente claves primarias compuestas - MYSQL

182

Aquí hay una simplificación excesiva de una configuración intensa con la que estoy trabajando. table_1y table_2ambos tienen claves primarias sustitutas de incremento automático como ID. infoes una tabla que contiene información sobre ambos table_1y table_2.

table_1 (id, field)  
table_2 (id, field, field)
info ( ???, field)

Estoy tratando de decidir si debo hacer la clave principal de infoun compuesto de las ID de table_1y table_2. Si tuviera que hacer esto, ¿cuál de estos tiene más sentido?
(en este ejemplo, estoy combinando ID 11209 con ID 437)

INT(9)11209437 (me imagino por qué esto es malo)
VARCHAR (10) 11209-437
DECIMAL (10,4)11209.437

¿O algo mas?

¿Estaría bien usar esto como la Clave primaria en un MYSQL MYISAM DB?

filip
fuente
Posible duplicado de la clave principal
dotancohen

Respuestas:

343

Usaría una clave compuesta (varias columnas).

CREATE TABLE INFO (
    t1ID INT,
    t2ID INT,
    PRIMARY KEY (t1ID, t2ID)
) 

De esta manera, también puede tener t1ID y t2ID como claves externas que apuntan a sus tablas respectivas.

AlexCuse
fuente
2
Oh wow, ¡así es como se hace una clave compuesta! Parece que he entendido mal el concepto. ¡¡Gracias!! Entonces, algo como esto es para fines de indexación, ¿correcto? Como no podría hacer referencia a un registro utilizando este compuesto, todavía tendría que hacerlo UPDATE info ... WHERE t1ID=11209 AND t2ID=437.
filip
2
correcto. Aunque dado que ambas columnas deberían ser únicas, donde t1ID = 11209 probablemente sería suficiente.
AlexCuse
39
@AlexCuse la combinación de ambas columnas es única, pero para t1ID = 11209 puede haber cualquier número de t2ID.
e18r
21

No haría que la clave primaria de la tabla "info" sea un compuesto de los dos valores de otras tablas.

Otros pueden expresar mejor las razones, pero se siente mal tener una columna que realmente esté compuesta de dos datos. ¿Qué sucede si desea ordenar el ID de la segunda tabla por alguna razón? ¿Qué sucede si desea contar la cantidad de veces que un valor de cualquiera de las tablas está presente?

Siempre los mantendría como dos columnas distintas. Podría usar una clave primaria de dos columnas en mysql ... PRIMARY KEY (id_a, id_b) ... pero prefiero usar un índice único de dos columnas y tener un campo de clave primaria de incremento automático.

wmorse
fuente
1
Tiene toda la razón sobre mantener columnas distintas. No sabía que podría tener un índice único de dos columnas y creo que en realidad puede ser una buena opción para mí. Sin embargo, ¿puedo preguntar por qué preferiría mantener la clave primaria como incremento automático?
filip
3
No tengo razones realmente convincentes, y reconozco que este es un punto de discusión entre mí y algunos de mis colegas, porque es más económico tener menos columnas. Me resulta más fácil escribir combinaciones en una sola clave externa. A veces, la importancia de estas tablas "Asignaciones entre dos tablas" se vuelve tan importante como las tablas originales, y su clave principal se convierte en una columna de clave externa en otras tablas.
wmorse
gracias. Creo que lo que dice tiene mucho sentido y lo intentaré como un índice único de dos columnas + clave principal de incremento automático
filip
1
Supongo que una razón desde mi cabeza es que quieres crear una tabla de relaciones. tiene tres tablas, por ejemplo, mercado, moneda y proveedor, un proveedor SOLO puede existir en un mercado UNA VEZ, por lo que su tabla de relaciones solo puede proporcionar una moneda única, por lo que compondría (id_market, id_provider) lo que significa que solo puede hacer esa conexión una vez, al intentar agregar nuevamente el mismo mercado y proveedor, fallará, lo que significa que son únicos, entonces tendría una segunda columna, digamos id_currency, lo que significa que la moneda es singular en toda la tabla, ¿tiene sentido?
Christopher Thomas el
1
Para cualquiera que vea este hilo más tarde, tenga en cuenta que la razón por la que es una mala práctica es porque viola un principio muy básico del diseño de la base de datos. 1st Normal Form requiere que cada pieza de información tenga su propia columna. Prácticamente no hay razón para violar esto y múltiples beneficios para normalizar la estructura de su base de datos.
smcjones
15

la sintaxis es CONSTRAINT constraint_name PRIMARY KEY(col1,col2,col3)por ejemplo ::

CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)

el ejemplo anterior funcionará si lo está escribiendo mientras crea la tabla, por ejemplo:

CREATE TABLE person (
   P_Id int ,
   ............,
   ............,
   CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)
);

Para agregar esta restricción a una tabla existente, debe seguir la siguiente sintaxis

ALTER TABLE table_name ADD CONSTRAINT constraint_name PRIMARY KEY (P_Id,LastName)
Ritabrata Gautam
fuente
8

Supongamos que ya ha creado una tabla, ahora puede usar esta consulta para hacer una clave primaria compuesta

alter table employee add primary key(emp_id,emp_name);
Usman Yaqoob
fuente
5

Además de las preferencias de diseño personal, hay casos en los que uno quiere hacer uso de claves primarias compuestas. Las tablas pueden tener dos o más campos que proporcionan una combinación única, y no necesariamente por medio de claves externas.

Como ejemplo, cada estado de EE. UU. Tiene un conjunto de distritos del Congreso únicos. Si bien muchos estados pueden tener individualmente un CD-5, nunca habrá más de un CD-5 en ninguno de los 50 estados, y viceversa. Por lo tanto, crear un campo de numeración automática para Massachusetts CD-5 sería redundante.

Si la base de datos maneja una página web dinámica, escribir código para consultar en una combinación de dos campos podría ser mucho más simple que extraer / volver a enviar una clave numerada automáticamente.

Entonces, aunque no estoy respondiendo la pregunta original, ciertamente aprecio la respuesta directa de Adam.

KiloVoltaire
fuente
4

Las claves primarias compuestas son lo que desea donde desea crear una relación de muchos a muchos con una tabla de hechos. Por ejemplo, es posible que tenga un paquete de alquiler de vacaciones que incluya varias propiedades. Por otro lado, la propiedad también podría estar disponible como parte de una serie de paquetes de alquiler, ya sea solo o con otras propiedades. En este escenario, establece la relación entre la propiedad y el paquete de alquiler con una tabla de hechos de propiedad / paquete. La asociación entre una propiedad y un paquete será única, solo se unirá usando property_id con la tabla de propiedades y / o package_id con la tabla de paquetes. Cada relación es única y una clave auto_increment es redundante, ya que no aparecerá en ninguna otra tabla. Por lo tanto, definir la clave compuesta es la respuesta.

Adam Penny
fuente
1
CREATE  TABLE `mom`.`sec_subsection` (

  `idsec_sub` INT(11) NOT NULL ,

  `idSubSections` INT(11) NOT NULL ,

  PRIMARY KEY (`idsec_sub`, `idSubSections`) 

);
Mente maestra
fuente
1

@AlexCuse Quería agregar esto como comentario a su respuesta, pero me di por vencido después de hacer varios intentos fallidos para agregar nuevas líneas en los comentarios.

Dicho esto, t1ID es único en la tabla_1, pero eso no lo hace único en la tabla INFO también.

Por ejemplo:

La Tabla_1 tiene:
Id Campo
1 A
2 B

Table_2 tiene:
Id Campo
1 X
2 Y

INFO puede tener:
t1ID t2ID campo
1 1 algunos
1 2 datos
2 1 en cada uno
fila 2 2

Entonces, en la tabla INFO para identificar de forma exclusiva una fila, necesita t1ID y t2ID

sactiw
fuente
se llama clave compuesta
Pavel P
1
@PavelP mi respuesta es wrt comentario de Alex "Aunque dado que ambas columnas deberían ser únicas, donde t1ID = 11209 probablemente sería suficiente". ... Estoy de acuerdo en que el uso de la clave compuesta es correcto, pero para identificar la coincidencia exacta necesitará t1ID y t2ID ... Espero que esté claro ahora.
Sactiw