AUTO_INCREMENT. Без особой заботы мы достигаем этого атрибута в MySQL. Быстрее любой змеи мы помещаем ее в столбец PRIMARY KEY в команде CREATE TABLE. Или установите флажок в phpMyAdmin и продолжайте, как никто другой. Что делает AUTO_INCREMENT? Для чего это используется? Всегда ли его значение является следующим инкрементным числом? Можем ли мы захватывать, манипулировать и использовать его для выполнения наших приказов? Это все отличные вопросы, которые я хотел бы знать сам. Давайте разберемся…

ОС и БД используются:

  • Xubuntu Linux 16.04.5 LTS (Xenial Xerus)
  • MySQL 5.7.23

Одно из наиболее распространенных применений (мне известно) атрибута AUTO_INCREMENT - создание уникального идентификатора для записи в таблице. Поэтому мы обычно используем его как таблицы »PRIMARY KEY. Честно говоря, на этом этапе моей карьеры в области изучения / разработки SQL это все, для чего я когда-либо его использовал.

Давайте создадим простую таблицу и выполним с ней несколько «элементарных» INSERT ', а также почувствуем атрибут AUTO_INCREMENT.

mysql> CREATE TABLE demo(id INTEGER AUTO_INCREMENT PRIMARY KEY,
    -> name VARCHAR(25));
 Query OK, 0 rows affected (0.29 sec)

Позаботившись об этом, я INSERT несколько значений, но отмечу разницу между одним INSERT и несколькими INSERT.
Я напишу один INSERT со следующим утверждением:

mysql> INSERT INTO demo(name) VALUES(‘Apples’);
 Query OK, 1 row affected (0.02 sec)
mysql> SELECT * FROM demo;
 + — — + — — — — +
 | id  | name    |
 + — — + — — — — +
 | 1   | Apples  |
 + — — + — — — — +
 1 row in set (0.00 sec)

Результаты запроса с помощью оператора SELECT отражают, что значение столбца id равно 1.
Не предоставляя значение для столбца id, MySQL автоматически присвоил ему 1. (AUTO_INCREMENT начинается с 1.)

Прежде чем продолжить с несколькими VALUES INSERT, я упомяну удобную функцию, которую вы можете использовать с AUTO_INCREMENT. LAST_INSERT_ID(). Я добавлю сюда точную формулировку документации для краткого изложения.

Без аргументов LAST_INSERT_ID () возвращает BIGINT UNSIGNED (64-битное) значение, представляющее первое автоматически сгенерированное значение, успешно вставленное для столбца AUTO_INCREMENT в результате последнего выполненного оператора INSERT. Значение LAST_INSERT_ID () остается неизменным, если строки не вставлены успешно.

Посмотрим, как работает LAST_INSERT_ID():

mysql> SELECT LAST_INSERT_ID();
 + — — — — — — — — — +
 | LAST_INSERT_ID()  |
 + — — — — — — — — — +
 | 1                 |
 + — — — — — — — — — +
 1 row in set (0.00 sec)

В этом есть смысл. На данный момент выпущено только одно INSERT заявление.

Я расскажу о нескольких VALUES INSERT следующим утверждением:

mysql> INSERT INTO demo(name)
    -> VALUES(‘Mark’),(‘Ham-n-cheese’),(’57 Chevy’);
 Query OK, 3 rows affected (0.05 sec)
 Records: 3 Duplicates: 0 Warnings: 0

Итак, значение LAST_INSERT_ID() равно 4, верно? Я только что вставил еще 3 записи, которые должны поставить значение столбца id на 4.

mysql> SELECT LAST_INSERT_ID();
 + — — — — — — — — — +
 | LAST_INSERT_ID()  |
 + — — — — — — — — — +
 | 2                 |
 + — — — — — — — — — +
 1 row in set (0.00 sec)

Хм… Интересно. И неожиданно.

Рассуждая, хотя 3 строки действительно были вставлены, значение id, автоматически присвоенное первой из них («Отметка»), равно 2.

И это значение, возвращаемое в этом вызове LAST_INSERT_ID().

Давай попробуем что-нибудь. У меня есть .sql исходный файл со следующими операторами SQL:

BEGIN;
INSERT INTO demo(name)
VALUES(‘Little River’);
INSERT INTO demo(name)
VALUES(‘Happy Time’);
COMMIT;

Я загружу этот файл в терминал (не показан), а затем проверю LAST_INSERT_ID() после запроса всех записей:

mysql> SELECT * FROM demo;
 + — — + — — — — — — — +
 | id  | name          |
 + — — + — — — — — — — +
 | 1   | Apples        |
 | 2   | Mark          |
 | 3   | Ham-n-cheese  |
 | 4   | 57 Chevy      |
 | 5   | Little River  |
 | 6   | Happy Time    |
 + — — + — — — — — — — +
 6 rows in set (0.00 sec)
mysql> SELECT LAST_INSERT_ID();
 + — — — — — — — — — +
 | LAST_INSERT_ID()  |
 + — — — — — — — — — +
 | 6                 |
 + — — — — — — — — — +
 1 row in set (0.00 sec)

Давайте попробуем еще раз, но на этот раз я запишу ошибку, чтобы мы могли увидеть, как атрибут AUTO_INCREMENT обрабатывает ее. Вот ошибка INSERT:

BEGIN;
INSERT INTO demo(name)
VALUES(‘B-52’’s’);
INSERT INTO dema(name)
VALUES(‘Happy Days’);
COMMIT;

После запуска этого исходного файла мы получаем:

mysql> SELECT * FROM demo;
 + — — + — — — — — — — +
 | id  | name          |
 + — — + — — — — — — — +
 | 1   | Apples        |
 | 2   | Mark          |
 | 3   | Ham-n-cheese  |
 | 4   | 57 Chevy      |
 | 5   | Little River  |
 | 6   | Happy Time    |
 | 7   | B-52‘s        | 
 + — — + — — — — — — — + 
 7 rows in set (0.00 sec)
mysql> SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
|                7 |
+------------------+
1 row in set (0.00 sec)

Первый INSERT завершился без проблем, но следующий оператор не прошел. Это id было бы 8. И снова у LAST_INSERT_ID() нет проблем с текущим значением.

Если вы хотите явно перечислить имена столбцов таблицы в своем операторе INSERT, вы можете быть уверены, что следующее автоматически сгенерированное значение будет вставлено для столбца AUTO_INCREMENT.
Доступны 2 варианта, вы можете предоставить список VALUES для AUTO_INCREMENT столбец.

mysql> INSERT INTO demo(id, name)
    -> VALUES (0, ‘Peanut Butter’);
 Query OK, 1 row affected (0.04 sec)
mysql> SELECT * FROM demo;
+----+---------------+
| id | name          |
+----+---------------+
|  1 | Apples        |
|  2 | Mark          |
|  3 | Ham-n-cheese  |
|  4 | 57 Chevy      |
|  5 | Little River  |
|  6 | Happy Time    |
|  7 | B-52's        |
|  8 | Peanut Butter |
+----+---------------+
8 rows in set (0.00 sec)

При вставке 0 автоматически создается и становится доступным следующее доступное значение для столбца id.
(Примечание: если включен NO_AUTO_VALUE_ON_ZERO SQL mode, это не сработает.)

mysql> INSERT INTO demo(id, name)
    -> VALUES(NULL, ‘Moon Dance’);
 Query OK, 1 row affected (0.04 sec)
mysql> SELECT * FROM demo;
+ — — + — — — — — — — -+
| id  | name           |
+ — — + — — — — — — — -+
| 1   | Apples         |
| 2   | Mark           |
| 3   | Ham-n-cheese   |
| 4   | 57 Chevy       |
| 5   | Little River   |
| 6   | Happy Time     |
| 7   | B-52’s         |
| 8   | Peanut Butter  |
| 9   | Moon Dance     |
+ — — + — — — — — — — -+
9 rows in set (0.00 sec)

В этом примере указание NULL вместо значения для перечисленного столбца id обеспечивает следующее доступное значение (9 в этом примере), которое нужно вставить.
Я обращусь к документации MySQL CREATE TABLE для точного объяснения .

«Целочисленный столбец или столбец с плавающей запятой может иметь дополнительный атрибут AUTO_INCREMENT. Когда вы вставляете значение NULL (рекомендуется) или 0 в индексированный столбец AUTO_INCREMENT, для этого столбца устанавливается следующее значение последовательности. Обычно это значение + 1, где значение - это наибольшее значение для столбца, находящегося в данный момент в таблице. Последовательности AUTO_INCREMENT начинаются с 1. ”

Что, если вы хотите полностью контролировать значение столбца AUTO_INCREMENT? Ты можешь съесть свой торт и тоже его съесть?

mysql> INSERT INTO demo(id, name)
    -> VALUES (15, 'Demo Table');
Query OK, 1 row affected (0.03 sec)
mysql> SELECT * FROM demo;
+----+---------------+
| id | name          |
+----+---------------+
|  1 | Apples        |
|  2 | Mark          |
|  3 | Ham-n-cheese  |
|  4 | 57 Chevy      |
|  5 | Little River  |
|  6 | Happy Time    |
|  7 | B-52's        |
|  8 | Peanut Butter |
|  9 | Moon Dance    |
| 15 | Demo Table    |
+----+---------------+
10 rows in set (0.00 sec)

Хорошо, мы видим, что можно явно указать желаемое значение.
Но продолжает ли AUTO_INCREMENT переход к следующему доступному значению из указанного пользовательского значения? Или из предыдущего INSERT?

mysql> INSERT INTO demo(name)
    -> VALUES ('Max Ammount');
Query OK, 1 row affected (0.02 sec)
mysql> SELECT * FROM demo;
+----+---------------+
| id | name          |
+----+---------------+
|  1 | Apples        |
|  2 | Mark          |
|  3 | Ham-n-cheese  |
|  4 | 57 Chevy      |
|  5 | Little River  |
|  6 | Happy Time    |
|  7 | B-52's        |
|  8 | Peanut Butter |
|  9 | Moon Dance    |
| 15 | Demo Table    |
| 16 | Max Ammount   |
+----+---------------+
11 rows in set (0.00 sec)

Приведенные выше результаты запроса отражают приращения значения от явно заданного значения.

Рекомендуемая литература и ресурсы:

В этом сообщении в блоге я планирую выделить и продемонстрировать базовое использование AUTO_INCREMENT. В следующем сообщении в блоге я подробнее рассмотрю функцию LAST_INSERT_ID(). Он обеспечивает фантастическое использование в определенных ситуациях в MySQL TRIGGER и хранимых процедурах. Пожалуйста, оставляйте любые исправления, комментарии и предложения в комментариях ниже. Как всегда, спасибо за чтение!

Изучите официальное Онлайн-руководство по MySQL 5.7 для получения дополнительной информации.

Призыв к действию!

Спасибо, что нашли время прочитать этот пост. Я искренне надеюсь, что вы открыли для себя что-то интересное и поучительное. Пожалуйста, поделитесь своими выводами здесь с кем-нибудь, кого вы знаете, кто тоже получит от этого такую ​​же ценность.

Посетите страницу Портфолио-проекты, чтобы увидеть сообщения в блоге / технические статьи, которые я написал для клиентов.

Я уже упоминал, как я люблю чашку кофе?!?!

Чтобы получать уведомления по электронной почте (Никогда не спамить) от этого блога (Проза Цифровой Совы) о последних публикациях в блоге по мере их публикации, пожалуйста, подпишитесь (по собственному желанию), нажав кнопку Нажмите, чтобы подписаться! На странице боковая панель на главной странице! (Не стесняйтесь в любое время просмотреть страницу политики конфиденциальности Digital Owl's Prose по любым вопросам, которые могут у вас возникнуть: обновления по электронной почте, подписка, отказ, контактные формы и т. Д.)

Обязательно посетите страницу Best Of, где собраны мои лучшие сообщения в блоге.

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

Отказ от ответственности: примеры, представленные в этом посте, представляют собой гипотетические идеи о том, как достичь аналогичных результатов. Это не самое лучшее решение. Большинство, если не все, из представленных примеров выполняются в среде рабочей станции для личного развития / обучения и не должны считаться производственными или готовыми к использованию. Ваши конкретные цели и потребности могут отличаться. Используйте те методы, которые лучше всего подходят для ваших нужд и целей. Мнения мои собственные.

Первоначально опубликовано на joshuaotwell.com 29 августа 2018 г.

✉️ Подпишитесь на рассылку еженедельно Email Blast от CodeBurst 🐦 Подпишитесь на CodeBurst на Twitter , просмотрите 🗺️ Дорожная карта веб-разработчиков на 2018 год и 🕸️ Изучите веб-разработку с полным стеком .