mysql - ON DUPLICATE KEY 添加行

标签 mysql insert duplicates unique

好的,我有下表:

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% 的修复——子查询可能有重复项,或者另一个进程可能会在它运行时更新表。但是,它通常会避免插入不应插入的记录。

关于mysql - ON DUPLICATE KEY 添加行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45600263/

相关文章:

mysql - 为什么在MySQL中添加外键而不绘制关系

mysql - 无法从动态 SQL 中将数据检索到变量中

php - 插入Mysql并获取唯一id

mysql - 连接具有共同重复键的字段并删除那些重复的字段,留下一个

MySQL::Edge Case::混合类型外键::可能还是做梦?

PHPMyAdmin 两次插入数据

sql - ORA-01756 : quoted string not properly terminated when I try to execute my code

loops - 在Teradata中捕获插入错误

php - 防止重复的条目sql php

linq - 比较两个列表并返回不同的值和差异