Я отслеживаю все 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;
INSERT ... ON DUPLICATE KEY UPDATE
описывается как «вставка смешанного режима» для обработки AUTO_INCREMENT
от InnoDB. Вставки смешанного режима – это в основном те, в которых известно максимальное количество требуемых значений AUTO_INCREMENT
, но количество, которое на самом деле будет необходимо , не является.
Вставки смешанного режима обрабатываются специально по умолчанию, как описано в документах MySQL :
… для «вставки смешанного режима» … InnoDB будет выделять больше значений автоинкремента, чем количество вставленных строк. Тем не менее, все автоматически назначенные значения последовательно генерируются (и, следовательно, превышают) значение автоинкремента, генерируемое последней выполненной предыдущей операцией. «Избыточные» номера теряются.
Если вы используете InnoDB, ваши альтернативы:
INSERT ... ON DUPLICATE KEY UPDATE
. innodb_autoinc_lock_mode
0
для «традиционного» режима блокировки автоинкремента, который гарантирует, что все операторы INSERT
будут назначать последовательные значения для AUTO_INCREMENT
. Тем не менее, это достигается путем блокировки во время инструкции, поэтому есть потеря производительности, связанная с этим параметром. AUTO_INCREMENT
. Примечание. Обработка AUTO_INCREMENT
полностью отличается от MyISAM, которая не проявляет такого поведения.
Механизм хранения должен увеличивать значение AUTO_INCREMENT
перед вставкой строки. Он не знает, не встанет ли вставка в этот момент. Он не может просто отменить приращение, потому что одновременно могут быть другие вставки на других соединениях. Это нормальное поведение, а не то, что вы должны (или можете) изменить. Цель AUTO_INCREMENT
– предоставить уникальные идентификаторы, а не непрерывную последовательность чисел.
К сожалению, решение находится на уровне приложения, если вы не хотите влиять на идентификаторы автоматического увеличения. Сначала SELECT
и подсчитайте строки результатов. Если 0 результатов, INSERT
данные. Если больше 0, UPDATE
эту строку.