$q = $db->prepare('INSERT IGNORE INTO Cities (Name,Stamp) VALUES (?,?)');
$q->execute(array($city,$stamp));
我正在运行此代码以在Cities表中插入新城市。我只是注意到每个查询都会增加id字段,这不是我想要的。这并不像我依赖于无间隙的id值,但每次运行代码时都会增加它是荒谬的。
那么,我可以运行什么样的智能SQL查询来为我提供相同的功能而无需执行两个查询(首先是SELECT,然后是INSERT)而不是auto_increment?
表格描述:
Field Type Null Key Default Extra
id int(11) NO PRI NULL auto_increment
Name varchar(100) YES UNI NULL
countryid int(11) YES NULL
Stamp int(11) YES NULL
uid int(11) YES NULL
代码:
INSERT INTO Cities (Name,Stamp) VALUES (?,?) ON DUPLICATE KEY UPDATE Name = Name
增加我桌子上的值。 MySQL版本是5.5.9。数据库引擎是innoDB。
可能是这个错误:http://bugs.mysql.com/bug.php?id=28781 如果你向下滚动到底部,你可以看到它仍然是一个问题,三年后......
答案 0 :(得分:3)
请参阅Bug #42497: V5.1 AUTO_INCREMENT gaps with InnoDB when using INSERT IGNORE(这实际上不是错误)。
您需要配置innodb_autoinc_lock_mode=0
或更改语句。有关详细信息,请参阅相关的AUTO_INCREMENT Handling in InnoDB文档。
这是您所看到的行为的摘要。在MySQL 5.1.22中引入了在InnoDB中分配自动增量值的新方法:
对于要插入的行数已知的INSERT语句 在处理语句之初,InnoDB快速分配 没有锁定所需的自动增量值数, 但只有在没有并发会话的情况下才会持有 表级AUTO-INC锁(因为其他语句将是 在进行时逐个分配自动增量值)。更多 确切地说,这样的INSERT语句获得自动增量值 在未被保持的互斥锁(轻量级锁)的控制下 直到声明完成,但仅限于声明的持续时间 分配过程。
简而言之,MySQL能够确定您的语句将插入多少行,并预先分配自动增量值。这可以防止多个并发语句交错自动增量值。但是,一旦分配了该号码,就不能再使用它。这引入了自动增量值中存在间隙的可能性。
以下语句适用于我,不增加自动增量值,并使用innodb_autoinc_lock_mode = 1
(默认设置):
INSERT INTO Cities (Name, Stamp)
SELECT $Name, $Stamp
FROM Cities
WHERE NOT EXISTS (
SELECT NULL
FROM Cities
WHERE Name = $Name
);
答案 1 :(得分:0)
姓名或邮票是否唯一?
否则,值会增加,因为插入了相同的行。但我想你应该注意到你的桌子上有那么多行吗?
答案 2 :(得分:-1)
$q = $db->prepare('INSERT INTO Cities (Name,Stamp) VALUES (?,?) ON DUPLICATE KEY UPDATE Name = Name');
$q->execute(array($city,$stamp));