Ошибка MySQL Auto-Inc? - PullRequest
       8

Ошибка MySQL Auto-Inc?

2 голосов
/ 16 ноября 2011

В моей таблице MySQL я создал столбец идентификаторов, который я надеюсь автоматически увеличить, чтобы он стал первичным ключом.

Я создал свою таблицу:

CREATE TABLE `test` (
        `id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
        `name` VARCHAR( 50 ) NOT NULL ,
        `date_modified` DATETIME NOT NULL ,
    UNIQUE (
        `name`
    )
) TYPE = INNODB;

затем вставил мои записи:

INSERT INTO `test` ( `id` , `name` , `date_modified` ) 
VALUES (
    NULL , 'TIM', '2011-11-16 12:36:30'
), (
    NULL , 'FRED', '2011-11-16 12:36:30'
);

Я ожидаю, что мои идентификаторы для вышеупомянутых 1 и 2 (соответственно).И пока это правда.Однако, когда я делаю что-то вроде этого:

insert into test (name) values ('FRED') 
on duplicate key update date_modified=now();

, затем вставляю новую запись, я ожидаю, что это будет 3, однако теперь мне показывают ID 4;пропуская место для 3.

Обычно это не было бы проблемой, но я использую миллионы записей, которые имеют тысячи обновлений каждый день ... и я действительно не хочу даже думатьоб исчерпании идентификаторов просто потому, что я пропускаю тонну цифр ..

Anyclue, почему это происходит?

Версия MySQL: 5.1.44

Спасибо

Ответы [ 3 ]

4 голосов
/ 16 ноября 2011

Я предполагаю, что сама INSERT запускает код, который генерирует следующий идентификационный номер.Когда дублирующий ключ обнаружен, и выполняется ON DUPLICATE KEY UPDATE, идентификационный номер отменяется.(Никакие SQL dbms не гарантируют, что автоматические последовательности будут без пробелов, AFAIK.)

Документы MySQL скажем

В общем, вам следует избегать использованияПредложение ON DUPLICATE KEY UPDATE для таблиц с несколькими уникальными индексами.

На этой странице также указано

Если таблица содержит столбец AUTO_INCREMENT и INSERT ... ON DUPLICATE KEY UPDATEвставляет или обновляет строку, функция LAST_INSERT_ID () возвращает значение AUTO_INCREMENT.

, которое далеко не полностью описывает внутреннее поведение, о котором я догадывался выше.

Не могу здесь проверить;попробую позже.

3 голосов
/ 16 ноября 2011

Можно ли изменить ключ на unsigned bigint - 18,446,744,073,709,551,615 - это много записей - таким образом, задержка исчерпания идентификаторов

Обнаружено в руководстве по mysql http://dev.mysql.com/doc/refman/5.1/en/example-auto-increment.html

Use a large enough integer data type for the AUTO_INCREMENT column to hold the
maximum sequence value you will need. When the column reaches the upper limit of
the data type, the next attempt to generate a sequence number fails. For example,
if you use TINYINT, the maximum permissible sequence number is 127. 
For TINYINT UNSIGNED, the maximum is 255.

Подробнее читайте здесь http://dev.mysql.com/doc/refman/5.6/en/information-functions.html#function_last-insert-id можно сделать вывод, что вставка в транзакционную таблицу является откатом, поэтому в руководстве сказано, что "LAST_INSERT_ID () не восстанавливается до операции до транзакции"

Как насчет длявозможное решение использовать таблицу для генерации идентификаторов, а затем вставить в основную таблицу в качестве PK с помощью LAST_INSERT_ID ();

Из руководства:

Create a table to hold the sequence counter and initialize it:

mysql> CREATE TABLE sequence (id INT NOT NULL);
mysql> INSERT INTO sequence VALUES (0);

Use the table to generate sequence numbers like this:

mysql> UPDATE sequence SET id=LAST_INSERT_ID(id+1);
mysql> SELECT LAST_INSERT_ID();

The UPDATE statement increments the sequence counter and causes the next call to
LAST_INSERT_ID() to return the updated value. The SELECT statement retrieves that
value. The mysql_insert_id() C API function can also be used to get the value. 
See Section 20.9.3.37, “mysql_insert_id()”.
0 голосов
/ 16 ноября 2011

Это действительно ошибка, как вы можете видеть здесь: http://bugs.mysql.com/bug.php?id=26316 Но, по-видимому, они исправили ее на 5.1.47 , и она была объявлена ​​проблемой плагина INNODB.Дубликат, но та же проблема, вы также можете увидеть здесь: http://bugs.mysql.com/bug.php?id=53791 ссылка на первую страницу, упомянутую здесь в этом ответе.

...