Несинхронизированный автоинкремент MYSQL

У меня странное поведение в одной из таблиц, с которыми я работаю, я не уверен, что именно мой php-код или какой-то параметр в базе данных приводят к тому, что автоматически увеличивающиеся идентификаторы не синхронизируются.

Если я запускаю следующий код без каких-либо индексов по имени&автомобили я получаю:

    $cars = array("Volvo","BMW","Toyota");
$name = "John Smith";

foreach($cars as $value)
{
try
{

//insert into database with a prepared statement

$query = $db->prepare(
'INSERT INTO cars (name,cars)
VALUES (:name,:cars)
');
$query->execute(array(
':name' => $name,
':cars' => $value
));

}
//else catch the exception and show the error.
catch(PDOException $e)
{
$error[] = $e->getMessage();
}
}

///Results
id || name       || cars
1  || John Smith || Volvo
2  || John Smith || BMW
3  || John Smith || Toyota

Но если я поставлю уникальный индекс на имя&автомобили, автоматическое увеличение не синхронизировано, и я не могу понять почему, потому что я не вижу ничего плохого в моем PHP-коде?

$cars = array("Volvo","BMW","Toyota");
$name = "John Smith";

foreach($cars as $value)
{
try
{

//insert into database with a prepared statement

$query = $db->prepare(
'INSERT INTO cars (name,cars)
VALUES (:name,:cars)
');
$query->execute(array(
':name' => $name,
':cars' => $value
));

}
//else catch the exception and show the error.
catch(PDOException $e)
{
$error[] = $e->getMessage();
}
}

///Results
id || name       || cars
3  || John Smith || Toyota
1  || John Smith || Volvo
2  || John Smith || BMW

0

Решение

Как вы думаете, почему это не синхронизировано? У Тойоты Джона еще есть идентификатор 3 и его вольво 1,

Как вы получаете свои результаты? Ты просто SELECTв ваш cars, право? Поведение в порядке, потому что нет необходимости упорядочивать данные по идентификатору без каких-либо ORDER BY заявление.

Вы должны запросить с SELECT id, name, cars FROM cars ORDER BY id ASC,

С mysql совершенно нормально, что возвращается неупорядоченный список. «Неупорядоченный» является просто результатом некоторой внутренней оптимизации.

2

Другие решения

Две вещи.

Во-первых, автоинкремент обычно так или иначе будет «не синхронизирован». Взгляни на MySQL AUTO_INCREMENT не ROLLBACK очень хороший пример того, почему вы не можете ожидать, что идентификаторы первичного ключа с автоинкрементом будут «синхронизированы» с вашими данными. Идентификатор уникален, и он увеличивается. Это действительно все, что вы можете сказать об автоинкременте.

Что приводит ко второму пункту. Вы, конечно, не можете сказать, что поле автоинкремента не будет иметь пробелов или будет возвращено вам в отсортированном порядке, если вы не настаиваете на том, что так оно и есть (на что @omeinusch и Mark Baker указали выше, и оба они правы). Здесь я хотел бы отметить, что ваше автоинкремент ведет себя точно так, как ожидалось. Вставьте другой ряд. У него будет идентификатор четыре. Начните транзакцию вставки, откатите ее, затем вставьте другую строку. У него будет идентификатор шесть. Это специально. Вставьте 100 строк, сверните их назад, затем вставьте еще 100. Эта партия из 100 будет иметь идентификаторы автоинкремента> 100. И они не будут возвращены вам в отсортированном порядке, если вы не добавите ORDER BY id в свой запрос. Это намеренно. И в этом нет ничего «несинхронного».

0