【问题标题】:Duplicate entry for key 'PRIMARY' in mysqlmysql中键'PRIMARY'的重复条目
【发布时间】:2012-08-18 00:19:37
【问题描述】:

我有一个名为tbl_jobs 的表,它存储应用程序中运行的一些后台作业的元数据。架构是这样的:

CREATE TABLE `tbl_jobs` (
  `type` varchar(30) NOT NULL DEFAULT '',
  `last_run_on` datetime NOT NULL,
  `records_updated` text,
  PRIMARY KEY (`type`,`last_run_on`),
  UNIQUE KEY `index2` (`type`,`last_run_on`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1$$

每当作业运行时,它都会在表中创建一个条目,其中包含 type,这是不同作业的唯一标识符,run timerecords updated 在该运行中。

有两个不同的作业同时运行,类型为:MAILER_UNLOCKED_REWARDSMAILER_ALMOST_UNLOCKED

当这些作业尝试插入具有相同时间戳的条目时,只有其中一个会被插入,而另一个会引发 Duplicate Entry for key 错误。

例如,这两个作业运行如下:

INSERT INTO tbl_jobs
            (type,
             last_run_on,
             records_updated)
VALUES     ('MAILER_ALMOST_UNLOCKED',
            '2012-08-22 19:10:00',
            'f8a35230fb214989ac75bf11c085aa28:b591426df4f340ecbce5a63c2a5a0174')

成功运行,但是当第二个作业运行插入命令时

INSERT INTO tbl_jobs
            (type,
             last_run_on,
             records_updated)
VALUES     ('MAILER_UNLOCKED_REWARDS',
            '2012-08-22 19:10:00',
            '8a003e8934c07f040134c30959c40009:59bcc21b33a0466e8e5dc50443beb945')

它抛出了错误

Duplicate entry 'M-2012-08-22 19:10:00' for key 'PRIMARY'

主键是typelast_run_on 列的组合。

如果我删除第一个作业的条目,则插入成功,即它要求 timestamp 单独是唯一的。

但是,相同timestamp 的冲突仅发生在这两个作业之间。还有其他作业会为相同的timestamp 插入。

关于可能是什么问题的任何想法?

【问题讨论】:

  • 你能显示show create table tbl_jobs
  • 只是一个评论,我建议使用代理键。每秒可能出现多个条目。
  • 由于主键必须是唯一的,您应该删除脚本的UNIQUE KEY 行。
  • 另外,如果您使用DEFAULT '' 定义您的type 列,您可能会遇到问题。如果您希望列中包含某些内容,则不应将其默认为空。

标签: mysql primary-key duplicates


【解决方案1】:

如果我遇到系统关闭或网络问题,我会看到此错误。您的数据库中确实没有重复项。那是一个 MySQL 数据库错误。您需要做的就是:如果您进行插入而不是true,只需将您要插入的表中的一列从varchar 更改为textbigint,然后重做插入。这样就解决了问题。

If(!$insert)
{    
$alter=Mysql_query("alter table     

`table_name` change `table_name` 

`table_name` bigint(255) not null");    

If($alter){

//you then redo your insertion.     

} 


}

【讨论】:

    【解决方案2】:

    第一件事:您必须确保您的 PRIMARY KEY 已设置为 AUTO_INCREMENT。 第二件事:您只需启用自动增量: ALTER TABLE [表名] AUTO_INCREMENT = 1 第三件事:当你执行插入命令时,你必须跳过这个键。

    【讨论】:

    • 主键 - 在这种情况下 - 是字母数字,因此无法应用 AUTO_INCREMENT 设置。
    【解决方案3】:

    您是否在索引中使用了整个“类型”字段?还是只有第一个字符?因为 MySQL 抱怨的关键是

    M-2012-08-22 19:10:00
    

    而不是 MAILER_...

    尝试运行:

     SHOW INDEXES FROM tbl_jobs;
    

    它应该给出如下内容:

    +----------+------------+----------+--------------+-------------+-----------+-------------+    ----------+--------+------+------------+---------+---------------+
    | Table    | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
    +----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    | tbl_jobs |          0 | PRIMARY  |            1 | type        | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
    | tbl_jobs |          0 | PRIMARY  |            2 | last_run_on | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
    

    ...

    我怀疑它会在 PRIMARY 索引的 Sub_part 列中显示“1”:

    +----------+------------+----------+--------------+-------------+-----------+-------------+    ----------+--------+------+------------+---------+---------------+
    | Table    | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
    +----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    | tbl_jobs |          0 | PRIMARY  |            1 | type        | A         |           0 |        1 | NULL   |      | BTREE      |         |               |
    | tbl_jobs |          0 | PRIMARY  |            2 | last_run_on | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
    

    ...

    顺便说一句,主键始终是唯一的,因此您声明的第二个索引index2 是多余的。

    【讨论】:

    • 我正在使用整个类型键。无法弄清楚 M- 在那里做什么。
    • @mickeymoon,PRIMARY报错与结果不一致。定义有问题,我相信 SHOW INDEXES 会有所帮助(检查“sub_part”列)。
    • @Iserni:正如您所指出的,sub_part 实际上是 type 列的 1。但它有什么含义?以及如何解决它?
    猜你喜欢
    • 2015-09-13
    • 1970-01-01
    • 2012-08-24
    • 2017-02-17
    • 2016-04-16
    • 1970-01-01
    • 2012-07-23
    • 2013-09-30
    相关资源
    最近更新 更多