234 votes

ALTER TABLE pour ajouter une clé primaire composite

J'ai une table appelée provider . J'ai trois colonnes appelées person , place , thing . Il peut y avoir des personnes dupliquées, des lieux dupliqués et des choses dupliquées, mais il ne peut jamais y avoir une combinaison personne-lieu-chose dupliquée.

Comment puis-je ALTER TABLE pour ajouter une clé primaire composite pour cette table dans MySQL avec ces trois colonnes ?

496voto

Adrian Cornish Points 8651
ALTER TABLE provider ADD PRIMARY KEY(person,place,thing);

Si une clé primaire existe déjà, il faut faire ceci

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

17 votes

@David542 Non, vous ne pouvez avoir qu'une seule clé primaire.

43 votes

@David : c'est une clé primaire unique composée de plusieurs champs, alias une clé composite.

3 votes

@David542 Bien sûr que vous pouvez - il s'agit d'une clé primaire composite composée de 3 champs. La combinaison des 3 champs doit être unique.

30voto

kzarns Points 472

La réponse de @Adrian Cornish est correcte. Cependant, il y a une autre réserve à l'abandon d'une clé primaire existante. Si cette clé primaire est utilisée comme clé étrangère par une autre table, vous obtiendrez une erreur en essayant de la supprimer. Dans certaines versions de mysql, le message d'erreur était mal formé (à partir de la version 5.5.17, ce message d'erreur est encore

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

Si vous voulez supprimer une clé primaire qui est référencée par une autre table, vous devez d'abord supprimer la clé étrangère dans cette autre table. Vous pouvez recréer cette clé étrangère si vous la voulez toujours après avoir recréé la clé primaire.

De même, lorsque vous utilisez des clés composites, l'ordre est important. Ces

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

ne sont pas la même chose. Ils imposent tous deux l'unicité de cet ensemble de trois champs, mais du point de vue de l'indexation, il y a une différence. Les champs sont indexés de gauche à droite. Par exemple, considérons les requêtes suivantes :

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 peut utiliser l'index de la clé primaire dans la déclaration ALTER 1
A peut utiliser l'index de la clé primaire dans la déclaration ALTER 2
C peut utiliser l'un ou l'autre des indices
D ne peut utiliser aucun des deux indices

A utilise les deux premiers champs de l'index 2 comme index partiel. A ne peut pas utiliser l'index 1 car il ne connaît pas la partie de l'index relative au lieu intermédiaire. Il peut cependant utiliser un index partiel sur une seule personne.

D ne peut utiliser aucun des deux index car il ne connaît pas de personne.

Voir la documentation mysql ici pour plus d'informations.

0 votes

Pourriez-vous nous communiquer l'équivalent de JPA pour la même chose ?

25voto

granadaCoder Points 6390

Vous pouvez simplement vouloir un CONSTRAINT UNIQUE. Surtout si vous avez déjà une clé de substitution. (un exemple de clé de substitution déjà existante serait une colonne unique qui est un AUTO_INCREMENT )

Voici le code sql pour une contrainte unique

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

0 votes

Merci, une contrainte est ce que je voulais, je ne savais pas quoi demander dans ce post initial. Merci de l'avoir ajouté au fil de discussion.

1 votes

J'utilise généralement une clé de substitution...... puis j'ajoute une contrainte d'unicité. De cette façon.... si l'"unicité" change en cours de route, il n'est pas très compliqué de modifier la contrainte, plutôt que de s'occuper de la clé primaire. Et si vous avez des tables enfant qui font référence à cette table avec une clé étrangère, vous n'avez qu'à FK la clé de substitution, pas les 3 colonnes. -

4voto

Naveen Points 4316
alter table table_name add primary key (col_name1, col_name2);

1voto

Lucky Points 748

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X