好的,我有下表:
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
==============================
如何防止这种情况?
答案 0 :(得分:2)
你无法真正阻止这一点,你不应该担心它。自动增加的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%修复 - 子查询可能有重复项,或者其他进程可以在运行时更新表。但是,它通常会避免在不应插入记录时插入记录。
答案 1 :(得分:1)
结帐innodb_autoinc_lock_mode。它目前设定的是什么?设置innodb_autoinc_lock_mode = 0
可能会为您提供所需内容,但默认为1
。
除此之外,您的密钥tag_id
(tag_id
)是多余的,因为这已经是您的主要密钥。