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 год и 🕸️ Изучите веб-разработку с полным стеком .