J'ai le tableau suivant dans MySQL version 5.5.24
DROP TABLE IF EXISTS `momento_distribution`;
CREATE TABLE IF NOT EXISTS `momento_distribution`
(
`momento_id` INT(11) NOT NULL,
`momento_idmember` INT(11) NOT NULL,
`created_at` DATETIME DEFAULT NULL,
`updated_at` DATETIME DEFAULT NULL,
`unread` TINYINT(1) DEFAULT '1',
`accepted` VARCHAR(10) NOT NULL DEFAULT 'pending',
`ext_member` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`momento_id`, `momento_idmember`),
KEY `momento_distribution_FI_2` (`momento_idmember`),
KEY `accepted` (`accepted`, `ext_member`)
)
ENGINE=InnoDB
DEFAULT CHARSET=latin1;
Il contient beaucoup de données avec des relations plusieurs à un avec deux autres tables avec ondelete=restrict
et onupdate=restrict
.
Maintenant, je dois changer la structure et introduire une clé primaire distincte dans la table, tout en conservant les relations et les données existantes. Pour cela, j'ai exécuté la requête suivante:
ALTER TABLE `momento_distribution` ADD `id` INT( 11 ) NOT NULL FIRST;
ALTER TABLE `momento_distribution` DROP PRIMARY KEY , ADD PRIMARY KEY ( `id` );
Malheureusement, ma deuxième requête a échoué avec l'erreur suivante:
1062 - Entrée en double '0' pour la clé 'PRIMARY'
Quelqu'un peut-il s'il vous plaît signaler le problème? Je suppose que le problème est la relation existante, mais je ne veux pas perdre la relation ou les données existantes, qui compte plusieurs milliers de lignes. Est-il possible de le faire sans perdre de données?
EDIT: En affichant les données, j'ai obtenu que la colonne nouvellement créée a la valeur '0' en elle. Cela ne permet probablement pas de changer la clé primaire à cause d'enregistrements en double (dans la nouvelle clé primaire)
J'ai plus de 8 000 lignes, je ne peux donc pas le modifier manuellement. Est-il possible d'assigner rowid
à une nouvelle clé primaire?
Exécutez la requête suivante dans la console mysql:
SHOW CREATE TABLE momento_distribution
Vérifiez la ligne qui ressemble à quelque chose comme
CONSTRAINT `momento_distribution_FK_1` FOREIGN KEY (`momento_id`) REFERENCES `momento` (`id`)
Cela peut être différent, je viens de deviner ce que cela pourrait être. Si vous avez un clé étrangère à la fois sur 'momento_id' et 'momento_idmember', vous obtiendrez deux noms de clé étrangère. L'étape suivante consiste à supprimer les clés étrangères. Exécutez les requêtes suivantes:
ALTER TABLE momento_distribution DROP FOREIGN KEY momento_distribution_FK_1
ALTER TABLE momento_distribution DROP FOREIGN KEY momento_distribution_FK_2
Assurez-vous de changer le nom de la clé étrangère en ce que vous avez obtenu du CREATE TABLE
requête. Maintenant, vous n'avez plus de clé étrangère, vous pouvez donc facilement retirer le clé primaire . Essayez ce qui suit:
ALTER TABLE `momento_distribution` DROP PRIMARY KEY
Ajoutez la colonne requise comme suit:
ALTER TABLE `momento_distribution` ADD `id` INT( 11 ) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST
Cette requête ajoute également des chiffres afin que vous n'ayez pas besoin de compter sur @rowid. Vous devez maintenant rajouter la clé étrangère aux colonnes précédentes. Pour cela, commencez par créer ces index:
ALTER TABLE `momento_distribution` ADD INDEX ( `momento_id` )
ALTER TABLE `momento_distribution` ADD INDEX ( `momento_idmember` )
Ajoutez maintenant les clés étrangères. Modifiez la table/colonne de référence selon vos besoins:
ALTER TABLE `momento_distribution` ADD FOREIGN KEY ( `momento_id`) REFERENCES `momento` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
ALTER TABLE `momento_distribution` ADD FOREIGN KEY ( `momento_idmember`) REFERENCES `member` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
J'espère que ça t'as aidé. Si vous rencontrez des erreurs, veuillez éditer la question avec la structure des tables de référence et le (s) code (s) d'erreur que vous obtenez.
Vous devez spécifier la clé primaire en incrémentation automatique.
CREATE TABLE `momento_distribution`
(
`momento_id` INT(11) NOT NULL AUTO_INCREMENT,
`momento_idmember` INT(11) NOT NULL,
`created_at` DATETIME DEFAULT NULL,
`updated_at` DATETIME DEFAULT NULL,
`unread` TINYINT(1) DEFAULT '1',
`accepted` VARCHAR(10) NOT NULL DEFAULT 'pending',
`ext_member` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`momento_id`, `momento_idmember`),
KEY `momento_distribution_FI_2` (`momento_idmember`),
KEY `accepted` (`accepted`, `ext_member`)
)
ENGINE=InnoDB
DEFAULT CHARSET=latin1$$
En ce qui concerne les commentaires ci-dessous, que diriez-vous de:
ALTER TABLE `momento_distribution`
CHANGE COLUMN `id` `id` INT(11) NOT NULL AUTO_INCREMENT,
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`);
Une clé primaire est un index unique. Par conséquent, si elle contient des doublons, vous ne pouvez pas affecter la colonne à un index unique. Vous devrez donc peut-être créer une nouvelle colonne.
vérifier si votre champ avec la clé primaire est réglé sur incrémentation automatique
cette étape fonctionne parfaitement pour moi .. vous pouvez l'essayer
espérons que cela fonctionne pour vous aussi. bonne chance
Définissez votre clé primaire comme AUTO_INCREMENT.