Перечислимый тип, состоящий из именованных значений.
Именованные значения можно объявлять как пары 'string' = integer или как имена 'string'. ClickHouse хранит только числа, но поддерживает операции со значениями по их именам.
ClickHouse поддерживает:
- 8-битный
Enum. Он может содержать до 256 значений в диапазоне[-128, 127]. - 16-битный
Enum. Он может содержать до 65536 значений в диапазоне[-32768, 32767].
ClickHouse автоматически выбирает тип Enum при вставке данных. Вы также можете использовать типы Enum8 или Enum16, чтобы явно задать размер хранилища.
Примеры использования
Здесь создаётся таблица со столбцом типа Enum8('hello' = 1, 'world' = 2):
CREATE TABLE t_enum
(
x Enum('hello' = 1, 'world' = 2)
)
ENGINE = TinyLogАналогично можно не указывать номера. ClickHouse автоматически присвоит их по порядку. По умолчанию нумерация начинается с 1.
CREATE TABLE t_enum
(
x Enum('hello', 'world')
)
ENGINE = TinyLogВы также можете указать допустимое начальное число для первого имени.
CREATE TABLE t_enum
(
x Enum('hello' = 1, 'world')
)
ENGINE = TinyLogCREATE TABLE t_enum
(
x Enum8('hello' = -129, 'world')
)
ENGINE = TinyLogException on server:
Code: 69. DB::Exception: Value -129 for element 'hello' exceeds range of Enum8.Столбец x может хранить только значения, перечисленные в определении типа: 'hello' или 'world'. Если вы попытаетесь сохранить любое другое значение, ClickHouse сгенерирует исключение. Для этого Enum размер в 8 бит выбирается автоматически.
INSERT INTO t_enum VALUES ('hello'), ('world'), ('hello')Ok.INSERT INTO t_enum VALUES('a')Exception on client:
Code: 49. DB::Exception: Unknown element 'a' for type Enum('hello' = 1, 'world' = 2)При запросе данных из таблицы ClickHouse выводит строковые значения типа Enum.
SELECT * FROM t_enum┌─x─────┐
│ hello │
│ world │
│ hello │
└───────┘Если вам нужно увидеть числовые значения, соответствующие строкам, необходимо привести значение Enum к целочисленному типу.
SELECT CAST(x, 'Int8') FROM t_enum┌─CAST(x, 'Int8')─┐
│ 1 │
│ 2 │
│ 1 │
└─────────────────┘Чтобы создать значение Enum в запросе, также нужно использовать CAST.
SELECT toTypeName(CAST('a', 'Enum(\'a\' = 1, \'b\' = 2)'))┌─toTypeName(CAST('a', 'Enum(\'a\' = 1, \'b\' = 2)'))─┐
│ Enum8('a' = 1, 'b' = 2) │
└─────────────────────────────────────────────────────┘Общие правила и использование
Каждому значению присваивается число в диапазоне -128 ... 127 для Enum8 или в диапазоне -32768 ... 32767 для Enum16. Все строки и числа должны быть разными. Пустая строка допустима. Если этот тип указан (в определении таблицы), числа могут идти в произвольном порядке. Однако этот порядок не имеет значения.
Ни строка, ни числовое значение в Enum не могут быть NULL.
Enum может входить в тип Nullable. Поэтому, если вы создаёте таблицу с помощью запроса
CREATE TABLE t_enum_nullable
(
x Nullable(Enum8('hello' = 1, 'world' = 2))
)
ENGINE = TinyLogон может хранить не только 'hello' и 'world', но и NULL.
INSERT INTO t_enum_nullable VALUES('hello'),('world'),(NULL)В оперативной памяти столбец Enum хранится так же, как Int8 или Int16 с соответствующими числовыми значениями.
При чтении в текстовом виде ClickHouse разбирает значение как строку и ищет её среди значений Enum. Если строка не найдена, генерируется исключение. При чтении в текстовом формате считывается строка, после чего для неё определяется соответствующее числовое значение. Если оно не найдено, будет сгенерировано исключение. При записи в текстовом виде значение записывается как соответствующая строка. Если данные столбца содержат некорректные значения (числа, отсутствующие в допустимом наборе), генерируется исключение. При чтении и записи в бинарном виде всё работает так же, как для типов данных Int8 и Int16. Неявное значение по умолчанию — значение с наименьшим номером.
При ORDER BY, GROUP BY, IN, DISTINCT и так далее Enum ведут себя так же, как соответствующие числа. Например, ORDER BY сортирует их численно. Операторы равенства и сравнения работают с Enum так же, как и с базовыми числовыми значениями.
Значения Enum нельзя сравнивать с числами. Enum можно сравнивать с константной строкой. Если строка, с которой выполняется сравнение, не является допустимым значением для Enum, будет сгенерировано исключение. Оператор IN поддерживается, если слева стоит Enum, а справа — набор строк. Эти строки являются значениями соответствующего Enum.
Для значений Enum не определено большинство числовых и строковых операций, например сложение числа с Enum или конкатенация строки с Enum.
Однако у Enum есть естественная функция toString, которая возвращает его строковое значение.
Значения Enum также можно преобразовывать в числовые типы с помощью функции toT, где T — числовой тип. Когда T соответствует базовому числовому типу enum, такое преобразование не требует дополнительных затрат.
Тип Enum можно без дополнительных затрат изменить с помощью ALTER, если меняется только набор значений. С помощью ALTER можно как добавлять, так и удалять элементы Enum (удаление безопасно только в том случае, если удалённое значение никогда не использовалось в таблице). В качестве меры предосторожности изменение числового значения ранее определённого элемента Enum приведёт к генерации исключения.
С помощью ALTER можно изменить Enum8 на Enum16 или наоборот, так же как Int8 меняется на Int16.
ДОБАВЛЕНИЕ ЗНАЧЕНИЙ ENUM
Для добавления новых значений в enum предусмотрен сокращённый синтаксис: ALTER MODIFY COLUMN ADD ENUM VALUES
CREATE TABLE enum
(
x Enum('One' = 1, 'Two', 'Three')
) ENGINE = Memory;
ALTER TABLE enum MODIFY COLUMN x ADD ENUM VALUES ('Zero' = 0, 'Four' = 4);
SHOW CREATE TABLE enum;┌─statement────────────────────────────────────────────────────────────────┐
│CREATE TABLE default.enum │
│( │
│ `x` Enum8('Zero' = 0, 'One' = 1, 'Two' = 2, 'Three' = 3, 'Four' = 4) │
│) │
│ENGINE = Memory │
└──────────────────────────────────────────────────────────────────────────┘