好的,我有下表:
CREATE TABLE `Tags` (
`tag_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`tag` varchar(100) DEFAULT NULL,
PRIMARY KEY (`tag_id`),
UNIQUE KEY `tag` (`tag`),
KEY `tag_id` (`tag_id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
SET FOREIGN_KEY_CHECKS=1;
当我运行以下查询时,它似乎在增加主键,即使它找到了重复项(即使它没有添加重复项)。
INSERT INTO Tags (tag) VALUES ('book'),('cats'),('dogs') ON DUPLICATE KEY UPDATE tag = tag
你得到...
tag_id | tag
==============================
1 | book
2 | robots
3 | doodles
5 | cats
6 | dogs
==============================
我该如何防止这种情况发生?
你无法真正阻止这种情况,你也不应该为此担心。自动递增的 ID 中的间隙几乎从来不是问题。
发生的事情是 MySQL 正在尝试插入该行。为了插入该行,它必须构造它——因此自动递增的列被递增。当已经找到该行时,插入失败,但自动增量已经增加。
如果您想尽量减少问题,您可以尝试在尝试插入之前找到重复项:
INSERT INTO Tags (tag)
SELECT t.tag
FROM (SELECT 'book' as tag UNION ALL
SELECT 'cats' as tag UNION ALL
SELECT 'dogs' as tag
) t
WHERE NOT EXISTS (SELECT 1 FROM Tags t2 WHERE t2.tag = t.tag)
ON DUPLICATE KEY UPDATE tag = VALUES(tag);
这不是 100% 的修复——子查询可能有重复项,或者另一个进程可能会在它运行时更新表。但是,它通常会避免插入不应插入的记录。
我是一名优秀的程序员,十分优秀!