mysql - primary - ALTER TABLE para agregar una clave primaria compuesta
llave foranea compuesta mysql (6)
Definitivamente es mejor usar la CLAVE ÚNICA COMPUESTA, como se ofreció @GranadaCoder, un ejemplo un poco complicado:
ALTER IGNORE TABLE table_name ADD UNIQUES INDEX idx_name(some_id, another_id, one_more_id);
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.
¿Cómo cambiaría ALTER TABLE para agregar una clave primaria compuesta para esta tabla en MySQL con estas tres columnas?
La respuesta de @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 estaba mal formado (a partir de 5.5.17, este mensaje de error todavía está
alter table parent drop column id;
ERROR 1025 (HY000): Error on rename of
''./test/#sql-a04_b'' to ''./test/parent'' (errno: 150).
Si desea soltar una clave principal a la que hace referencia otra tabla, primero deberá soltar la clave externa en esa otra tabla. Puede volver a crear esa clave externa si aún la desea después de volver a crear la clave principal.
Además, cuando se usan claves compuestas, el orden es importante. Estas
1) ALTER TABLE provider ADD PRIMARY KEY(person,place,thing);
and
2) ALTER TABLE provider ADD PRIMARY KEY(person,thing,place);
no son lo mismo. 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 usar el índice de clave primaria en la instrucción ALTER 1
A puede usar el índice de clave primaria en la instrucción ALTER 2
C puede usar cualquier índice
D no puede usar ninguno de los índices
A usa los primeros dos campos en el índice 2 como un í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 la persona.
Vea los documentos de mysql here para más información.
Puede simplemente querer una RESTRICCIÓN ÚNICA. Especialmente si ya tiene una clave sustituta. (ejemplo: un AUTO_INCREMENT)
ALTER TABLE `MyDatabase`.`Provider`
ADD CONSTRAINT CK_Per_Place_Thing_Unique UNIQUE (person,place,thing)
;
ALTER TABLE table_name DROP PRIMARY KEY,ADD PRIMARY KEY (col_name1, col_name2);
ALTER TABLE provider ADD PRIMARY KEY(person,place,thing);
Si ya existe una clave principal, entonces desea hacer esto
ALTER TABLE provider DROP PRIMARY KEY, ADD PRIMARY KEY(person, place, thing);
alter table table_name add primary key (col_name1, col_name2);