У меня странное поведение в одной из таблиц, с которыми я работаю, я не уверен, что именно мой 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
Как вы думаете, почему это не синхронизировано? У Тойоты Джона еще есть идентификатор 3
и его вольво 1
,
Как вы получаете свои результаты? Ты просто SELECT
в ваш cars
, право? Поведение в порядке, потому что нет необходимости упорядочивать данные по идентификатору без каких-либо ORDER BY
заявление.
Вы должны запросить с SELECT id, name, cars FROM cars ORDER BY id ASC
,
С mysql совершенно нормально, что возвращается неупорядоченный список. «Неупорядоченный» является просто результатом некоторой внутренней оптимизации.
Две вещи.
Во-первых, автоинкремент обычно так или иначе будет «не синхронизирован». Взгляни на MySQL AUTO_INCREMENT не ROLLBACK очень хороший пример того, почему вы не можете ожидать, что идентификаторы первичного ключа с автоинкрементом будут «синхронизированы» с вашими данными. Идентификатор уникален, и он увеличивается. Это действительно все, что вы можете сказать об автоинкременте.
Что приводит ко второму пункту. Вы, конечно, не можете сказать, что поле автоинкремента не будет иметь пробелов или будет возвращено вам в отсортированном порядке, если вы не настаиваете на том, что так оно и есть (на что @omeinusch и Mark Baker указали выше, и оба они правы). Здесь я хотел бы отметить, что ваше автоинкремент ведет себя точно так, как ожидалось. Вставьте другой ряд. У него будет идентификатор четыре. Начните транзакцию вставки, откатите ее, затем вставьте другую строку. У него будет идентификатор шесть. Это специально. Вставьте 100 строк, сверните их назад, затем вставьте еще 100. Эта партия из 100 будет иметь идентификаторы автоинкремента> 100. И они не будут возвращены вам в отсортированном порядке, если вы не добавите ORDER BY id в свой запрос. Это намеренно. И в этом нет ничего «несинхронного».