php - MySQL INSERT ....ON DUPLICATE UPDATE - 添加一个到自动增量

标签 php mysql innodb

我用一个简单的计数器跟踪所有访问我的 http_user_agents。 下面在数据库中插入 http_user_agent,该字段不区分大小写并且是唯一的。因此,当我们尝试插入它并找到一个 DUPLICATE KEY 时,它会将 hits 字段加 1。

问题是即使我们没有插入字段,我的自动增量字段仍然会增加。我怎样才能防止这种情况发生?

$sql = "INSERT INTO `db_agency_cloud`.`tblRefHttpUsersAgent` SET `http_users_agent` = :UsersAgent, `created_ts` = NOW() ON DUPLICATE KEY UPDATE `hits` = `hits` + 1";

这是表格结构:

CREATE TABLE `tblRefHttpUsersAgent`
(
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`http_users_agent` varchar(255) NOT NULL,
`hits` int(20) unsigned NOT NULL DEFAULT '1',
`created_ts` datetime NOT NULL,
`activity_ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `http_users_agent` (`http_users_agent`)
)
ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;

最佳答案

INSERT ... ON DUPLICATE KEY UPDATE 被描述为“混合模式插入”,用于 InnoDB 的 AUTO_INCREMENT 处理。混合模式插入基本上是已知 最大 个所需的 AUTO_INCREMENT 值,但 实际需要的数量 是未知的。

默认情况下,混合模式插入会得到特殊处理,如 MySQL docs 中所述。 :

...for “mixed-mode inserts”... InnoDB will allocate more auto-increment values than the number of rows to be inserted. However, all values automatically assigned are consecutively generated (and thus higher than) the auto-increment value generated by the most recently executed previous statement. “Excess” numbers are lost.

如果您使用 InnoDB,您的替代方案是:

  1. 避免INSERT ... ON DUPLICATE KEY UPDATE
  2. 设置innodb_autoinc_lock_mode 0 的参数,用于“传统”自动增量锁定模式,它保证所有 INSERT 语句将为 AUTO_INCREMENT 列分配连续值。但是,这是通过在语句期间锁定来实现的,因此会降低与此设置相关的性能。
  3. (推荐)忽略 AUTO_INCREMENT 列中的空白。

注意:AUTO_INCREMENT 处理在 MyISAM 下完全不同,不会出现这种行为。

关于php - MySQL INSERT ....ON DUPLICATE UPDATE - 添加一个到自动增量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7087869/

相关文章:

mysql - 如何将mysql中的静态数据透视表转换为动态数据透视表?

mysql - 为共享相同列值的每个表条目选择最小整数值(非唯一)

php - 使用下拉值查询 mySQL 数据库

mysql - 如何使这两个同时发生的事务始终成功,而不会导致唯一性冲突?

mysql - 我无法在表中创建外键 - #1005

javascript - 如何在 Bootstrap 模式中从 MySQL 打开图像?

php - MySql 临时表 VS View VS php 数组

php - 不带 limit() 传递数据库表的所有值

php mysql错误,提示插入语句

mysql - 在 InnoDB 表上使用可变长度列会减慢选择速度吗?