2012-01-14 37 views
155

Tengo una tabla llamada provider. Tengo tres columnas llamadas person, place, thing. Puede haber personas duplicadas, lugares duplicados y cosas duplicadas, pero nunca puede haber una combinación dupla persona-lugar-cosa.ALTER TABLE para agregar una clave primaria compuesta

¿Cómo ALTER TABLE agregaría una clave primaria compuesta para esta tabla en MySQL con estas tres columnas?

Respuesta

340
ALTER TABLE provider ADD PRIMARY KEY(person,place,thing); 

Si una clave principal ya existe, entonces usted quiere hacer esto

ALTER TABLE provider DROP PRIMARY KEY, ADD PRIMARY KEY(person, place, thing); 
+2

Esto añade tres PKS únicos, o de uno pk compuesto. – David542

+13

@ David542 No, no; solo puede tener 1 clave principal. –

+28

@David: es una clave principal única compuesta de múltiples campos, también conocida como clave compuesta. –

14

Usted puede simplemente querer una restricción única. Especialmente si ya tiene una clave sustituta. (ejemplo: un AUTO_INCREMENT) la respuesta de

ALTER TABLE `MyDatabase`.`Provider` 
    ADD CONSTRAINT CK_Per_Place_Thing_Unique UNIQUE (person,place,thing) 
; 
+0

Gracias, una restricción es lo que quería, no sabía qué pedir en esta publicación inicial. Gracias por agregar esto al hilo. – ZaneDarken

+0

Normalmente utilizo una clave sustituta ... luego agrego una restricción única. De esta manera ... si la "singularidad" cambia en el futuro, no es demasiado difícil modificar la restricción, en lugar de jugar con la clave principal. Y si tiene tablas secundarias que la clave externa hace referencia a esta tabla, solo tiene que FK la clave sustituta, no las 3 columnas. - – granadaCoder

3
alter table table_name add primary key (col_name1, col_name2); 
0

ALTER TABLE table_name DROP PRIMARY KEY,ADD PRIMARY KEY (col_name1, col_name2);

16

@Adrian Cornish es correcta. Sin embargo, hay otra advertencia para descartar una clave principal existente. Si esa otra clave se utiliza como una clave externa en otra tabla, se producirá un error al intentar soltarla. En algunas versiones de MySQL el mensaje de error no había mal formado (a partir del 5.5.17, este mensaje de error sigue siendo

alter table parent drop column id; 
ERROR 1025 (HY000): Error on rename of 
'./test/#sql-a04_b' to './test/parent' (errno: 150). 

Si desea eliminar una clave primaria que está siendo referenciado por otra tabla, tendrá que caer la clave externa en primer lugar que la otra mesa. usted puede recrear esa clave externa si todavía quiere que después de volver a crear la clave principal.

Además, al utilizar claves compuestas, el orden es importante. Estos

1) ALTER TABLE provider ADD PRIMARY KEY(person,place,thing); 
and 
2) ALTER TABLE provider ADD PRIMARY KEY(person,thing,place); 

no son el la misma cosa. Ambos hacen cumplir la singularidad en ese conjunto de tres campos, sin embargo desde el punto de vista de la indexación existe una diferencia. Los campos están indexados de izquierda a derecha. Por ejemplo, considere las siguientes consultas:

A) SELECT person, place, thing FROM provider WHERE person = 'foo' AND thing = 'bar'; 
B) SELECT person, place, thing FROM provider WHERE person = 'foo' AND place = 'baz'; 
C) SELECT person, place, thing FROM provider WHERE person = 'foo' AND place = 'baz' AND thing = 'bar'; 
D) SELECT person, place, thing FROM provider WHERE place = 'baz' AND thing = 'bar'; 

B puede utilizar el índice de clave principal en ALTER declaración 1
A puede utilizar el índice de clave principal de instrucción ALTER 2
C puede utilizar cualquiera índice
D no se puede usar ninguno de los índices

A utiliza los dos primeros campos del índice 2 como índice parcial. A no puede usar el índice 1 porque no conoce la porción del lugar intermedio del índice. Sin embargo, aún podría ser capaz de usar un índice parcial solo en persona.

D no puede usar ninguno de los índices porque no conoce a nadie.

Consulte los documentos de mysql here para obtener más información.

1

`s definitivamente mejor utilizar COMPUESTO clave única, como el que ofrece @GranadaCoder, un poco difícil sin embargo ejemplo:

ALTER IGNORE TABLE table_name ADD UNIQUES INDEX idx_name(some_id, another_id, one_more_id);

Cuestiones relacionadas