MODIFICAR TABLA para agregar una clave primaria compuesta


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 de persona-lugar-cosa duplicada.

¿Cómo ALTERARÍA la TABLA para agregar una clave primaria compuesta para esta tabla en MySQL con estas tres columnas?

Author: LihO, 2012-01-14

6 answers

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

Si ya existe una clave primaria, entonces desea hacer esto

ALTER TABLE provider DROP PRIMARY KEY, ADD PRIMARY KEY(person, place, thing);
 362
Author: Adrian Cornish,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-14 01:24:58

La respuesta de@Adrian Cornish es correcta. Sin embargo, hay otra advertencia para eliminar una clave primaria existente. Si esa clave primaria está siendo utilizada como clave foránea por otra tabla, se producirá un error al intentar eliminarla. En algunas versiones de mysql el mensaje de error no estaba mal formado (a partir de 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 a la que se hace referencia en otra tabla, primero tendrá que eliminar la clave externa en esa otra tabla. Puede recrear esa clave foránea si aún la desea después de recrear la clave primaria.

También, cuando se usan 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 lo mismo. Ambos imponen la singularidad en ese conjunto de tres campos, sin embargo, desde un punto de vista de indexación, hay una diferencia. Los campos se indexan 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
Puede utilice el índice de clave primaria en la instrucción ALTER 2
C puede utilizar cualquiera de los índices
D no puede usar ninguno de los índices

A utiliza los dos primeros campos del índice 2 como un índice parcial. A no puede usar el índice 1 porque no conoce la porción de lugar intermedio del índice. Sin embargo, es posible que aún pueda usar un índice parcial en just person.

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

Vea los documentos de mysql aquí para más información.

 17
Author: cs_alumnus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-24 15:10:37

Es posible que simplemente desee una RESTRICCIÓN ÚNICA. Especialmente si ya tienes una llave sustituta. (ejemplo: un AUTO_INCREMENT )

ALTER TABLE `MyDatabase`.`Provider`
    ADD CONSTRAINT CK_Per_Place_Thing_Unique UNIQUE (person,place,thing)
;
 14
Author: granadaCoder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-16 00:27:55
alter table table_name add primary key (col_name1, col_name2);
 3
Author: Naveen Kumar Alonekar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-16 07:52:35

Definitivamente es mejor usar la CLAVE ÚNICA COMPUESTA, como ofreció @GranadaCoder, aunque un ejemplo un poco complicado:

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

 1
Author: Arthur Kushman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-23 20:02:58

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

 0
Author: Lucky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-08 12:26:19