我有一个名为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_REWARDS
和MAILER_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'
主键是type
和last_run_on
列的组合。
如果删除第一个作业的条目,则插入成功,即单独要求timestamp
是唯一的。
然而,同一timestamp
的冲突只发生在这两个作业之间。还有其他作业被插入同一个timestamp
。
关于可能出现什么问题的任何想法?
答案 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
更改为text
或bigint
然后重做插入。这解决了这个问题。
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.
}
}