mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-10-20 07:21:02 +00:00
113 lines
7.4 KiB
Markdown
113 lines
7.4 KiB
Markdown
<a name="data_type-enum"></a>
|
||
|
||
# Enum8, Enum16
|
||
|
||
Включает в себя типы `Enum8` и `Enum16`. `Enum` сохраняет конечный набор пар `'строка' = целое число`. Все операции с данными типа `Enum` ClickHouse выполняет как с числами, однако пользователь при этом работает со строковыми константами. Это более эффективно с точки зрения производительности, чем работа с типом данных `String`.
|
||
|
||
- `Enum8` описывается парами `'String' = Int8`.
|
||
- `Enum16` описывается парами `'String' = Int16`.
|
||
|
||
## Примеры применения
|
||
|
||
Создадим таблицу со столбцом типа `Enum8('hello' = 1, 'world' = 2)`.
|
||
|
||
```
|
||
CREATE TABLE t_enum
|
||
(
|
||
x Enum8('hello' = 1, 'world' = 2)
|
||
)
|
||
ENGINE = TinyLog
|
||
```
|
||
|
||
В столбец `x` можно сохранять только значения, перечисленные при определении типа, т.е. `'hello'` или `'world'`. Если попытаться сохранить другое значение, ClickHouse сгенерирует исключение.
|
||
|
||
```
|
||
:) INSERT INTO t_enum Values('hello'),('world'),('hello')
|
||
|
||
INSERT INTO t_enum VALUES
|
||
|
||
Ok.
|
||
|
||
3 rows in set. Elapsed: 0.002 sec.
|
||
|
||
:) insert into t_enum values('a')
|
||
|
||
INSERT INTO t_enum VALUES
|
||
|
||
|
||
Exception on client:
|
||
Code: 49. DB::Exception: Unknown element 'a' for type Enum8('hello' = 1, 'world' = 2)
|
||
```
|
||
|
||
При запросе данных из таблицы ClickHouse выдаст строковые значения из `Enum`.
|
||
|
||
```
|
||
SELECT * FROM t_enum
|
||
|
||
┌─x─────┐
|
||
│ hello │
|
||
│ world │
|
||
│ hello │
|
||
└───────┘
|
||
```
|
||
Если необходимо увидеть цифровые эквиваленты строкам, то необходимо привести тип.
|
||
|
||
```
|
||
SELECT CAST(x, 'Int8') FROM t_enum
|
||
|
||
┌─CAST(x, 'Int8')─┐
|
||
│ 1 │
|
||
│ 2 │
|
||
│ 1 │
|
||
└─────────────────┘
|
||
```
|
||
|
||
Чтобы создать значение типа Enum в запросе, также необходима функция `CAST`.
|
||
|
||
```
|
||
SELECT toTypeName(CAST('a', 'Enum8(\'a\' = 1, \'b\' = 2)'))
|
||
|
||
┌─toTypeName(CAST('a', 'Enum8(\'a\' = 1, \'b\' = 2)'))─┐
|
||
│ Enum8('a' = 1, 'b' = 2) │
|
||
└──────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
## Общие правила и особенности использования
|
||
|
||
Для каждого из значений прописывается число в диапазоне `-128 .. 127` для `Enum8` или в диапазоне `-32768 .. 32767` для `Enum16`. Все строки должны быть разными, числа - тоже. Разрешена пустая строка. При указании такого типа (в определении таблицы), числа могут идти не подряд и в произвольном порядке. При этом, порядок не имеет значения.
|
||
|
||
Ни строка, ни цифровое значение в `Enum` не могут быть [NULL](../query_language/syntax.md#null-literal).
|
||
|
||
`Enum` может быть передан в тип [Nullable](nullable.md#data_type-nullable). Таким образом, если создать таблицу запросом
|
||
|
||
```
|
||
CREATE TABLE t_enum_nullable
|
||
(
|
||
x Nullable( Enum8('hello' = 1, 'world' = 2) )
|
||
)
|
||
ENGINE = TinyLog
|
||
```
|
||
|
||
, то в ней можно будет хранить не только `'hello'` и `'world'`, но и `NULL`.
|
||
|
||
```
|
||
INSERT INTO t_enum_null Values('hello'),('world'),(NULL)
|
||
```
|
||
|
||
В оперативке столбец типа `Enum` представлен так же, как `Int8` или `Int16` соответствующими числовыми значениями.
|
||
При чтении в текстовом виде, парсит значение как строку и ищет соответствующую строку из множества значений Enum-а. Если не находит - кидается исключение.
|
||
При записи в текстовом виде, записывает значение как соответствующую строку. Если в данных столбца есть мусор - числа не из допустимого множества, то кидается исключение. При чтении и записи в бинарном виде, оно осуществляется так же, как для типов данных Int8, Int16.
|
||
Неявное значение по умолчанию - это значение с минимальным номером.
|
||
|
||
При `ORDER BY`, `GROUP BY`, `IN`, `DISTINCT` и т. п., Enum-ы ведут себя так же, как соответствующие числа. Например, при ORDER BY они сортируются по числовым значениям. Функции сравнения на равенство и сравнения на отношение порядка двух Enum-ов работают с Enum-ами так же, как с числами.
|
||
|
||
Сравнивать Enum с числом нельзя. Можно сравнивать Enum с константной строкой - при этом, для строки ищется соответствующее значение Enum-а; если не находится - кидается исключение. Поддерживается оператор IN, где слева стоит Enum, а справа - множество строк. В этом случае, строки рассматриваются как значения соответствующего Enum-а.
|
||
|
||
Большинство операций с числами и со строками не имеет смысла и не работают для Enum-ов: например, к Enum-у нельзя прибавить число.
|
||
Для Enum-а естественным образом определяется функция `toString`, которая возвращает его строковое значение.
|
||
|
||
Также для Enum-а определяются функции `toT`, где T - числовой тип. При совпадении T с типом столбца Enum-а, преобразование работает бесплатно.
|
||
При ALTER, есть возможность бесплатно изменить тип Enum-а, если меняется только множество значений. При этом, можно добавлять новые значения; можно удалять старые значения (это безопасно только если они ни разу не использовались, так как это не проверяется). В качестве "защиты от дурака", нельзя менять числовые значения у имеющихся строк - в этом случае, кидается исключение.
|
||
|
||
При ALTER, есть возможность поменять Enum8 на Enum16 и обратно - так же, как можно поменять Int8 на Int16.
|