2012-08-29 70 views
25

我在MySQL版本如下表5.5.24MySQL的1062 - 重复录入“0”键“PRIMARY”

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; 

它有大量的数据与其他两个表多到一个关系与ondelete=restrictonupdate=restrict

现在,我需要改变结构并在表中引入单独的主键,同时仍然保留现有的关系和数据。对于这一点,我执行以下查询:

ALTER TABLE `momento_distribution` ADD `id` INT(11) NOT NULL FIRST; 
ALTER TABLE `momento_distribution` DROP PRIMARY KEY , ADD PRIMARY KEY ( `id`); 

不幸的是,我的第二个查询失败,出现以下错误:

1062 - Duplicate entry '0' for key 'PRIMARY'

是否有人可以指出的问题?我猜这个问题是现有的关系,但我不想丢失现有的关系或数据,有几千行。有没有办法做到这一点,而不会丢失数据?

编辑: 通过查看数据,我得到新创建的列中的值为'0'。可能由于重复记录(在新的主键中),这不允许更改主键

我有超过8000行,所以我无法手动更改它。有没有办法将rowid分配给新的主键?

回答

13

在mysql控制台中运行以下查询:

SHOW CREATE TABLE momento_distribution 

检查线路,看起来像

CONSTRAINT `momento_distribution_FK_1` FOREIGN KEY (`momento_id`) REFERENCES `momento` (`id`) 

这可能是不同的,我只是把一个猜测,可能是什么。如果'momento_id'&'momento_idmember'上有foreign key,则会得到两个外键名称。下一步是删除外键。运行以下查询:

ALTER TABLE momento_distribution DROP FOREIGN KEY momento_distribution_FK_1 
ALTER TABLE momento_distribution DROP FOREIGN KEY momento_distribution_FK_2 

确保外键的名称更改为您从CREATE TABLE查询得到了什么。现在您没有任何外键,因此您可以轻松删除primary key。请尝试以下操作:

ALTER TABLE `momento_distribution` DROP PRIMARY KEY 

添加所需的列如下:

ALTER TABLE `momento_distribution` ADD `id` INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST 

此查询还增加了数字,所以你不需要依赖@rowid。现在您需要将外键添加回较早的列。为此,请先制作这些索引:

ALTER TABLE `momento_distribution` ADD INDEX ( `momento_id`) 
ALTER TABLE `momento_distribution` ADD INDEX ( `momento_idmember`) 

现在添加外键。根据需要更改参考表/列:

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 

希望有所帮助。如果您遇到任何错误,请编辑参考表&的结构以获得您的错误代码。

+0

谢谢@Youthpark,我正在尝试这些查询,并在接下来的10分钟内取回最大值。感谢帮助。我对这个问题感到非常沮丧。 –

+1

如有任何问题,请附上所有表格的结构及错误代码。 – 2012-08-30 04:34:59

+1

终于完成了。自从昨天起我被困在那里。非常感谢。 –

43

你需要指定主键自动递增

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$$ 

至于下面的评论,何谈:

ALTER TABLE `momento_distribution` 
    CHANGE COLUMN `id` `id` INT(11) NOT NULL AUTO_INCREMENT, 
    DROP PRIMARY KEY, 
    ADD PRIMARY KEY (`id`); 

主键是一个独特的指数,所以如果它包含重复,您不能将该列分配为唯一索引,因此您可能需要完全创建一个新列

+0

谢谢梅尔卡,但我给了上面的查询只是参考表结构。我没有创建新表。我已经有很多行的表,所以只有alter query是选项。目前momento_id&momento_idmember是外键和组合键。我需要将它们作为主键删除,并将新列作为主键。 –

+0

抱歉,编辑也不起作用。 'momento_id'与'momento_idmember'一起已经是主键。我需要新的列作为主键。检查我的帖子,我已经成功地添加了列的查询** ALTER TABLE'momento_distribution' ADD'id' INT(11)NOT NULL FIRST; **。现在需要把它作为主要的。 –

+0

PRIMARY KEY是一个唯一索引,所以如果它包含重复项,则不能将该列指定为唯一索引,因此您可能需要完全创建一个新列。 – Miroslav

9

如果检查与主键的字段设置为自动增量

1

这一步工作完美的我..你可以试试

  1. 添加索引
  2. 添加自动增量
  3. 添加主钥匙

希望它也适合你。祝你好运

相关问题