Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MySQL INSERT ....ON DUPLICATE UPDATE - Adds one to the autoincrement

Tags:

php

mysql

innodb

I keep track of all the http_user_agents that visit me, with a simple hit counter. The below insert the http_user_agent in the DB, this field is Case Insensitive and is Unique. So when we try to insert it and it finds a DUPLICATE KEY, it adds 1 to the hits field.

The problem is my Auto Increment field still increases even though we did not insert a field. how can i prevent this?

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

Here is the Table stucture:

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;
like image 424
M. of CA Avatar asked Aug 17 '11 04:08

M. of CA


People also ask

How does on duplicate key update work?

ON DUPLICATE KEY UPDATE is a MariaDB/MySQL extension to the INSERT statement that, if it finds a duplicate unique or primary key, will instead perform an UPDATE. The row/s affected value is reported as 1 if a row is inserted, and 2 if a row is updated, unless the API's CLIENT_FOUND_ROWS flag is set.

How can I get auto-increment value after insert?

To obtain the value immediately after an INSERT , use a SELECT query with the LAST_INSERT_ID() function. For example, using Connector/ODBC you would execute two separate statements, the INSERT statement and the SELECT query to obtain the auto-increment value.

What will happen if the below insert statement is executed twice where ID is the primary key?

When we try to insert a duplicate record into a table with a primary key column, it produces an error message. However, if we use the INSERT IGNORE statement to add duplicate rows into a table with a primary key column, MySQL does not produce any error.

What does Autoincrement do in MySQL?

Auto-increment allows a unique number to be generated automatically when a new record is inserted into a table. Often this is the primary key field that we would like to be created automatically every time a new record is inserted.


1 Answers

INSERT ... ON DUPLICATE KEY UPDATE is described as a "mixed-mode insert" for the purposes of InnoDB's AUTO_INCREMENT handling. Mixed-mode inserts are basically ones where the maximum number of required AUTO_INCREMENT values is known, but the amount that will actually be needed is not.

Mixed-mode inserts get handled specially by default, as described in the 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.

If you're using InnoDB, your alternatives are:

  1. Avoid INSERT ... ON DUPLICATE KEY UPDATE.
  2. Set the innodb_autoinc_lock_mode parameter to 0, for "traditional" autoincrement lock mode, which guarantees that all INSERT statements will assign consecutive values for AUTO_INCREMENT columns. However, this is accomplished by locking during the statement, so there's a performance loss associated with this setting.
  3. (Recommended) Ignore the gaps in the AUTO_INCREMENT column.

Note: AUTO_INCREMENT handling is totally different under MyISAM, which does not exhibit this behavior.

like image 162
John Flatness Avatar answered Oct 08 '22 13:10

John Flatness