11.3.5 Тип ENUM
Объект ENUM — это строковый объект со значением, выбранным из списка разрешенных значений, перечисленных явно в спецификации столбца во время создания таблицы.
Смотрите раздел 11.3.1 «Синтаксис типа данных String» для ENUM синтаксиса типа и ограничений на длину.
Тип ENUM имеет следующие преимущества:
Компактное хранение данных в ситуациях, когда столбец имеет ограниченный набор возможных значений. Строки, указанные вами как входные значения, автоматически кодируются как числа. Смотрите раздел 11.7 «Требования к хранению типов данных» для требований к хранению для типа
ENUM.Читабельные запросы и вывод. Числа преобразуются обратно в соответствующие строки в результатах запросов.
и эти потенциальные проблемы, которые следует учитывать:
Если вы создаете значения перечисления, которые похожи на числа, легко перепутать буквальные значения с их внутренними индексными номерами, как объяснено в Ограничениях перечисления.
Использование столбцов
ENUMвORDER BY-запросах требует дополнительной осторожности, как объяснено в Сортировке перечисления.
Создание и использование столбцов ENUM
Значение перечисления должно быть строковым литералом в кавычках. Например, вы можете создать таблицу со столбцом ENUM следующим образом:
CREATE TABLE shirts (
name VARCHAR(40),
size ENUM('x-small', 'small', 'medium', 'large', 'x-large')
);
INSERT INTO shirts (name, size) VALUES ('dress shirt','large'), ('t-shirt','medium'),
('polo shirt','small');
SELECT name, size FROM shirts WHERE size = 'medium';
+---------+--------+
| name | size |
+---------+--------+
| t-shirt | medium |
+---------+--------+
UPDATE shirts SET size = 'small' WHERE size = 'large';
COMMIT;
Вставка 1 миллиона строк в эту таблицу со значением 'medium' потребовала бы 1 миллион байт памяти, в отличие от 6 миллионов байт, если бы вы хранили фактическую строку 'medium' в столбце VARCHAR.
Значения индексов для литералов перечисления
Каждое значение перечисления имеет индекс:
Элементы, указанные в спецификации столбца, получают индексные номера, начиная с 1.
-
Значение индекса пустого значения ошибки строки равно 0. Это означает, что вы можете использовать следующую
SELECTинструкцию для поиска строк, в которые были назначены недопустимыеENUMзначения:mysql>
SELECT * FROMtbl_nameWHEREenum_col=0; Индекс значения
NULLравенNULL.Термин “индекс” здесь относится к позиции в списке значений перечисления. Он не имеет никакого отношения к индексам таблиц.
Например, столбец, указанный как ENUM('Mercury',
'Venus', 'Earth'), может иметь любые значения, показанные здесь. Также показан индекс каждого значения.
| Значение | Индекс |
|---|---|
NULL | NULL |
'' | 0 |
'Mercury' | 1 |
'Venus' | 2 |
'Earth' | 3 |
Столбец ENUM может содержать не более 65 535 различных элементов. (Практическое ограничение меньше 3000.) Таблица может содержать не более 255 уникальных определений списков элементов среди ее столбцов ENUM и SET, рассматриваемых вместе. Более подробную информацию об этих ограничениях см. в Ограничения, накладываемые структурой файла .frm.
Если вы извлекаете значение ENUM в числовом контексте, возвращается индекс значения столбца. Например, вы можете извлечь числовые значения из столбца ENUM так:
mysql> SELECT enum_col+0 FROM tbl_name;
Функции, такие как SUM() или AVG(), которые ожидают числовой аргумент, при необходимости преобразуют аргумент в число. Для значений ENUM в расчётах используется индексное число.
Обработка литералов перечисления
При создании таблицы из значений ENUM членов таблицы автоматически удаляются хвостовые пробелы.
При извлечении значения, сохраненные в столбце ENUM, отображаются с использованием регистра, который использовался при определении столбца. Обратите внимание, что столбцам ENUM можно назначить набор символов и сортировку. Для двоичных или чувствительных к регистру сортировок при назначении значений столбцу учитывается регистр символов.
Если вы сохраняете число в столбце ENUM, число обрабатывается как индекс в возможных значениях, и хранящимся значением является член перечисления с этим индексом. (Однако это не работает с LOAD DATA, который обрабатывает все входные данные как строки.) Если числовое значение находится в кавычках, оно всё равно интерпретируется как индекс, если нет соответствующей строки в списке значений перечисления. По этим причинам не рекомендуется определять столбец ENUM со значениями перечисления, которые выглядят как числа, потому что это может легко привести к путанице. Например, у следующего столбца есть члены перечисления со строковыми значениями '0', '1' и '2', но числовыми значениями индекса 1, 2 и 3:
numbers ENUM('0','1','2')
Если вы сохраняете 2, оно интерпретируется как индексное значение и становится '1' (значение с индексом 2). Если вы сохраняете '2', это соответствует значению перечисления, поэтому оно сохраняется как '2'. Если вы сохраняете '3', оно не соответствует никакому значению перечисления, поэтому обрабатывается как индекс и становится '2' (значение с индексом 3).
mysql> INSERT INTO t (numbers) VALUES(2),('2'),('3');
mysql> SELECT * FROM t;
+---------+
| numbers |
+---------+
| 1 |
| 2 |
| 2 |
+---------+
Чтобы определить все возможные значения для столбца ENUM, используйте SHOW COLUMNS
FROM и проанализируйте определение tbl_name LIKE
'enum_col'ENUM в столбце Type вывода.
В API на C значения ENUM возвращаются в виде строк. Информацию об использовании метаданных набора результатов для их различения от других строк см. в .
Пустые или NULL значения перечисления
Значение перечисления также может быть пустой строкой ('') или NULL в определенных обстоятельствах:
-
Если вы вставляете некорректное значение в столбец
ENUM(то есть строку, отсутствующую в списке разрешенных значений), вместо этого вставляется пустая строка как специальное значение ошибки. Эту строку можно отличить от «обычной» пустой строки по тому, что эта строка имеет числовое значение 0. Подробности о числовых индексах для значений перечисления см. в Значения индексов для литералов перечисления.Если включён строгий режим SQL, попытки вставить некорректные значения
ENUMприведут к ошибке. Если столбец
ENUMобъявлен как допускающийNULL, то значениеNULLявляется допустимым значением для столбца, а значение по умолчанию —NULL. Если столбецENUMобъявлен какNOT NULL, его значение по умолчанию — первый элемент в списке разрешенных значений.
Сортировка перечислений
Значения перечислений сортируются по их индексам, которые зависят от порядка, в котором члены перечисления были перечислены в спецификации столбца. Например, 'b' сортируется перед 'a' для ENUM('b', 'a'). Пустая строка сортируется перед непустыми строками, а значения NULL сортируются перед всеми другими значениями перечисления.
Чтобы предотвратить непредсказуемые результаты при использовании условия ORDER
BY для столбца ENUM, используйте один из этих методов:
Укажите список
ENUMв алфавитном порядке.Убедитесь, что столбец сортируется лексически, а не по индексу, закодировав
ORDER BY CAST(илиcolAS CHAR)ORDER BY CONCAT(.col)
Ограничения перечислений
Значение перечисления не может быть выражением, даже если оно вычисляется в строковое значение.
Например, это CREATE TABLE утверждение не работает, потому что функция CONCAT не может использоваться для построения значения перечисления:
CREATE TABLE sizes (
size ENUM('small', CONCAT('med','ium'), 'large')
);
Вы также не можете использовать пользовательскую переменную в качестве значения перечисления. Эта пара операторов не работает:
SET @mysize = 'medium';
CREATE TABLE sizes (
size ENUM('small', @mysize, 'large')
);
Мы настоятельно рекомендуем не использовать числа в качестве значений перечислений, поскольку это не экономит места по сравнению с соответствующим типом TINYINT или SMALLINT, и легко можно перепутать строки и значения чисел (которые могут не совпадать), если вы неправильно укажете ENUM значения в кавычках. Если кавычки опущены, число рассматривается как индекс. См. Обработка литералов перечисления, чтобы увидеть, как даже число в кавычках может быть ошибочно использовано как числовой индекс.
Дублирование значений в определении приводит к предупреждению или ошибке, если включен строгий режим SQL.
© 2025 Oracle
Licensed under the GPLv2 License.