MySQL INSERT … ON DUPLICATE UPDATE – добавляет один к автоинкременту

Я отслеживаю все http_user_agents, которые посещают меня, с простым счетчиком. Ниже вставьте http_user_agent в БД, это поле нечувствительно к регистру и является уникальным. Поэтому, когда мы пытаемся вставить его, и он находит DUPLICATE KEY, он добавляет 1 к полю хитов.

Проблема в том, что мое поле Auto Increment все еще увеличивается, хотя мы не вставляем поле. как я могу это предотвратить?

$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; 

Related of "MySQL INSERT … ON DUPLICATE UPDATE – добавляет один к автоинкременту"

INSERT ... ON DUPLICATE KEY UPDATE описывается как «вставка смешанного режима» для обработки AUTO_INCREMENT от InnoDB. Вставки смешанного режима – это в основном те, в которых известно максимальное количество требуемых значений AUTO_INCREMENT , но количество, которое на самом деле будет необходимо , не является.

Вставки смешанного режима обрабатываются специально по умолчанию, как описано в документах MySQL :

… для «вставки смешанного режима» … InnoDB будет выделять больше значений автоинкремента, чем количество вставленных строк. Тем не менее, все автоматически назначенные значения последовательно генерируются (и, следовательно, превышают) значение автоинкремента, генерируемое последней выполненной предыдущей операцией. «Избыточные» номера теряются.

Если вы используете InnoDB, ваши альтернативы:

  1. Избегайте INSERT ... ON DUPLICATE KEY UPDATE .
  2. Установите параметр innodb_autoinc_lock_mode 0 для «традиционного» режима блокировки автоинкремента, который гарантирует, что все операторы INSERT будут назначать последовательные значения для AUTO_INCREMENT . Тем не менее, это достигается путем блокировки во время инструкции, поэтому есть потеря производительности, связанная с этим параметром.
  3. (Рекомендуется) Игнорировать пробелы в столбце AUTO_INCREMENT .

Примечание. Обработка AUTO_INCREMENT полностью отличается от MyISAM, которая не проявляет такого поведения.

Механизм хранения должен увеличивать значение AUTO_INCREMENT перед вставкой строки. Он не знает, не встанет ли вставка в этот момент. Он не может просто отменить приращение, потому что одновременно могут быть другие вставки на других соединениях. Это нормальное поведение, а не то, что вы должны (или можете) изменить. Цель AUTO_INCREMENT – предоставить уникальные идентификаторы, а не непрерывную последовательность чисел.

К сожалению, решение находится на уровне приложения, если вы не хотите влиять на идентификаторы автоматического увеличения. Сначала SELECT и подсчитайте строки результатов. Если 0 результатов, INSERT данные. Если больше 0, UPDATE эту строку.