Перейти к основному содержанию
Перейти к основному содержанию

Enum

Перечисляемый тип, состоящий из именованных значений.

Именованные значения могут быть объявлены как пары '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 = TinyLog
CREATE TABLE t_enum
(
    x Enum8('hello' = -129, 'world')
)
ENGINE = TinyLog
Исключение на сервере:
Код: 69. DB::Exception: Значение -129 для элемента 'hello' выходит за пределы диапазона Enum8.

Столбец x может хранить только значения, перечисленные в определении типа: 'hello' или 'world'. Если вы попытаетесь сохранить любое другое значение, ClickHouse выдаст исключение. Размер 8 бит для этого типа Enum выбирается автоматически.

INSERT INTO t_enum VALUES ('hello'), ('world'), ('hello')
Ok.
INSERT INTO t_enum VALUES('a')
Исключение на клиенте:
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.