mysql中键'PRIMARY'的重复条目

时间:2012-08-22 14:32:42

标签: mysql primary-key duplicates

我有一个名为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 time和该行中的records updated

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

当这些作业尝试使用相同的时间戳插入条目时,只会插入其中一个,另一个会抛出重复条目错误。

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

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

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

3 个答案:

答案 0 :(得分:4)

您是否在索引中使用整个“类型”字段?还是只有第一个角色?因为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是多余的。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

如果系统关闭或出现网络问题,我已经看到此错误。你的数据库真的没有重复。这是一个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.     

} 


}