2012-08-22 54 views
8

我有一个表tbl_jobs,它存储了在应用程序中运行的一些后台作业的元数据。该模式是这样的:mysql中键“PRIMARY”的重复项

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命令

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' 

主键是type和的组合10列。

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

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

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

+1

你能出现'show create table tbl_jobs' – jcho360

+0

只是一个评论,我会建议使用代理键。您可能每秒钟发生多个条目。 – Kermit

+1

由于主键必须是唯一的,您应该删除脚本的'UNIQUE KEY'行。 – sp00m

回答

4

你在索引中使用整个“type”字段吗?还是只有第一个字符?由于密钥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  |   |    | 

.. 。

,我怀疑它会显示而不是“1”的主索引的列Sub_part:

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

...

BTW,主键始终是唯一的,因此第二个索引index2声明有多余。

+0

我正在使用整个类型键。无法弄清楚M在那里做什么。 – mickeymoon

+0

@mickeymoon,PRIMARY报告的错误与结果不一致。定义有问题,我相信SHOW INDEXES会有帮助(检查“sub_part”列)。 – LSerni

+0

@Iserni:正如您所指出的那样,'sub_part'实际上是** 1 **的'type'列。但它有什么影响?以及如何解决它? – mickeymoon

0

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

+0

主键 - 在这种情况下 - 是字母数字,所以'AUTO_INCREMENT'设置不能应用。 – fusion3k

0

我看到这个错误,如果我有系统关机或网络问题。你真的没有在你的数据库重复。这是一个MySQL分贝错误。所有你需要做的是:如果你做了插入,并且它不是true,只需要更改要插入的表格中的一列(从varchartextbigint),然后重新插入。解决了这个问题。

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.  

} 


} 
相关问题