我正在运行SQL查询,看起来有点像这样
INSERT INTO people (Name, Role)
VALUES('{$Name}', '{$Occupation')
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id)
'人民' table有一个代理ID密钥作为主密钥,由MySQLs Autoindex设置。
'名称'和'角色'被组合成一个复合的唯一键。
问题是,当我运行此查询并命中具有相同名称和角色的人并获取其各自的ID时,自动索引仍会增加。
是否可以轻松地防止这种情况,或者我是否需要运行2个单独的查询来检查是否已存在然后插入?
答案 0 :(得分:2)
首先,如果自动增量增加,您不必担心。不可否认,这在美学上是丑陋的,但序列中的差距并不重要。而且,差距可能出于其他原因。
但是,如果这很重要,您可以通过查询查询来降低发生这种情况的可能性:
INSERT INTO people (Name, Role)
SELECT name, role
FROM (SELECT '{$Name}' as name, '{$Occupation}' as role) x
WHERE NOT EXISTS (SELECT 1 FROM people p WHERE p.name = x.name)
ON DUPLICATE KEY UPDATE name = VALUES(name); -- no op;
你仍然可以获得可能出现差距的竞争条件,但这样做的可能性要小得多。
答案 1 :(得分:1)
正如insert ... on duplicate key update上的mysql文档所说:
例如,如果列a声明为UNIQUE并包含该值 1,以下两个陈述具有类似的效果:
INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1; UPDATE table SET c=c+1 WHERE a=1;
(效果不一样 一个InnoDB表,其中a是一个自动增量列。与 自动递增列,INSERT语句增加 自动递增值,但UPDATE不会。)
因此,对于innodb表,这是预期的行为。您可以为表选择不同的表引擎,或者如果您不希望在更新时增加自动增量字段,则不能使用on duplicate key update
子句。注意:auto_increment id的序列中有间隙没有错。如果业务要求是连续递增的序列号,那么您不应该使用自动增量。
更新
如果你担心很快就会耗尽bigint范围,那么使用uuid()
mysql函数或类似的东西来为你生成唯一的id。但是无符号bigint的最大范围非常大......