web-dev-qa-db-fra.com

Ajout d'autocrampe à l'ID faisant déjà partie de la clé étrangère

Je voudrais ajouter la propriété autoincrement pour toute ma table columns nommé id dans un schema. Cependant, la plupart d'entre eux font partie d'une contrainte foreign key. Y a-t-il une autre façon de le faire sans dropping la contrainte de clé étrangère pour tous, adding the autoincrement propriété et re-creating les contraintes foreign key?

Merci beaucoup!

2
SummerCode

Essayez des clés étrangères désactivées temporaires (assurez-vous que personne ne permettait de mettre à jour la DB pendant laquelle):

create table t1 (id int not null primary key) engine = innodb;
create table t2 (id int not null primary key
                ,t1_id int not null
                ,    constraint abc foreign key (t1_id) 
                                    references t1 (id) 
) engine = innodb;

set foreign_key_checks = 0;
alter table t1 change column id id int auto_increment;
set foreign_key_checks = 1;

Notez que set foreign_key_checks = 1; ne valide pas les clés étrangères, donc si une personne parvient à ajouter des valeurs non valides tandis que les touches étrangères sont désactivées, vous vous retrouvez avec une DB incohérente:

insert into t1 (id) values (1);
set foreign_key_checks = 0;
insert into t2 (id, t1_id) values (1,1);
insert into t2 (id, t1_id) values (2,2); -- invalid
set foreign_key_checks = 1; -- does not validate foreign keys

Je me souviens vaguement que c'était également le cas lors de l'ajout de clés étrangères, mais ce bogue semble avoir été réparé depuis:

select @@version;
+-----------------+
| @@version       |
+-----------------+
| 10.2.14-MariaDB |
+-----------------+
1 row in set (0.00 sec)

alter table t2 drop foreign key abc;
alter table t2 add constraint abc foreign key (t1_id)                                      references t1 (id);
ERROR 1452 (23000): Cannot add or update a child row: 
a foreign key constraint fails ("test"."#sql-5fa_a", 
CONSTRAINT "abc" FOREIGN KEY ("t1_id")
REFERENCES "t1" ("id"))
8
Lennart