> ## Documentation Index
> Fetch the complete documentation index at: https://clickhouse.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> Документация по таблице

# CREATE TABLE

Создаёт новую таблицу. По умолчанию таблицы создаются только на текущем сервере.
Распределённые DDL-запросы реализованы в виде предложения `ON CLUSTER`, которое [описано отдельно](/docs/ru/reference/statements/distributed-ddl).

<div id="syntax-forms">
  ## Синтаксические формы
</div>

Этот запрос может иметь различные синтаксические формы в зависимости от сценария использования.

<div id="with-explicit-schema">
  ### Создание таблицы с явной схемой
</div>

```sql theme={null}
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
    name1 [type1] [NULL|NOT NULL] [DEFAULT|MATERIALIZED|EPHEMERAL|ALIAS expr1] [COMMENT 'comment for column'] [compression_codec] [TTL expr1],
    name2 [type2] [NULL|NOT NULL] [DEFAULT|MATERIALIZED|EPHEMERAL|ALIAS expr2] [COMMENT 'comment for column'] [compression_codec] [TTL expr2],
    ...
) ENGINE = engine
  [COMMENT 'comment for table']
```

Создаёт таблицу с именем `table_name` в базе данных `db` или в текущей базе данных, если `db` не задана, со структурой, указанной в скобках, и движком `engine`.
Структура таблицы представляет собой список описаний столбцов, вторичных индексов, проекций и ограничений. Если [первичный ключ](#primary-key) поддерживается движком, он указывается как параметр движка таблицы.

В простейшем случае описание столбца имеет вид `name type`. Пример: `RegionID UInt32`.

Модификаторы, следующие за типом, — `COMMENT`, `compression_codec`, `STATISTICS`, `TTL`, `COLLATE`, `PRIMARY KEY` и `SETTINGS` для каждого столбца — можно записывать в любом порядке, причём каждый из них не более одного раза. Например, `RegionID UInt32 CODEC(ZSTD) COMMENT 'comment for column'` и `RegionID UInt32 COMMENT 'comment for column' CODEC(ZSTD)` равнозначны. Обратите внимание, что `SHOW CREATE TABLE` нормализует объявление столбца: оставшиеся в нём модификаторы всегда выводятся в каноническом порядке `COMMENT`, `CODEC`, `STATISTICS`, `TTL`, `COLLATE`, `SETTINGS`, а `PRIMARY KEY` для отдельного столбца перемещается из объявления столбца в предложение `PRIMARY KEY` на уровне таблицы.

Для значений по умолчанию также можно задавать выражения (см. ниже).

При необходимости можно указать первичный ключ с одним или несколькими ключевыми выражениями.

Для столбцов и таблицы можно добавлять комментарии.

<div id="with-a-schema-similar-to-other-table">
  ### Создать таблицу со схемой существующей таблицы
</div>

```sql theme={null}
CREATE TABLE [IF NOT EXISTS] [db2.]table_clone AS [db.]table [ENGINE = engine]
```

ClickHouse позволяет копировать схему и данные существующей таблицы.

Чтобы скопировать схему существующей таблицы:

Это создает таблицу с такой же структурой, как у другой таблицы.

<div id="with-a-schema-and-data-cloned-from-another-table">
  ### Создать таблицу со схемой и данными существующей таблицы
</div>

Чтобы реплицировать схему и данные существующей таблицы:

```sql theme={null}
CREATE TABLE [IF NOT EXISTS] [db2.]table_clone CLONE AS [db.]table [ENGINE = engine]
```

Это создаёт таблицу с той же схемой и теми же данными, что и существующая таблица. После создания новой таблицы к ней присоединяются все партиции из `db.table`. Иными словами, при создании данные из `db.table` клонируются в `db2.table_clone`. Этот запрос эквивалентен следующему:

```sql theme={null}
CREATE TABLE [IF NOT EXISTS] [db2.]table_clone AS [db.]table [ENGINE = engine];
ALTER TABLE [db2.]table_clone ATTACH PARTITION ALL FROM [db.]table;
```

Для обеих возможностей можно указать для таблицы другой движок. Если движок не указан, будет использоваться тот же движок, что и у исходной таблицы (`db.table`).

<div id="from-a-table-function">
  ### Создание таблицы с помощью табличной функции
</div>

```sql theme={null}
CREATE TABLE [IF NOT EXISTS] [db.]table_name AS table_function()
```

Создаёт таблицу с тем же результатом, что и указанная [табличная функция](/docs/ru/reference/functions/table-functions/index). Созданная таблица также будет работать так же, как соответствующая табличная функция.

<div id="from-select-query">
  ### Создание таблицы с помощью SELECT-запроса
</div>

```sql theme={null}
CREATE TABLE [IF NOT EXISTS] [db.]table_name[(name1 [type1], name2 [type2], ...)] ENGINE = engine AS SELECT ...
```

Создаёт таблицу со структурой, аналогичной результату запроса `SELECT`, с движком `engine` и заполняет её данными из `SELECT`. Также можно явно указать описание столбцов.

Если таблица уже существует и указано `IF NOT EXISTS`, запрос не выполнит никаких действий.

В запросе после предложения `ENGINE` могут следовать и другие предложения. Подробную документацию о том, как создавать таблицы, см. в описаниях [движков таблиц](/docs/ru/reference/engines/table-engines/index).

**Пример**

```sql title="Query" theme={null}
CREATE TABLE t1 (x String) ENGINE = Memory AS SELECT 1;
SELECT x, toTypeName(x) FROM t1;
```

```text title="Response" theme={null}
┌─x─┬─toTypeName(x)─┐
│ 1 │ String        │
└───┴───────────────┘
```

<div id="default_values">
  ## Указание значений по умолчанию
</div>

Описание столбца может задавать выражение значения по умолчанию в форме `DEFAULT expr`, `MATERIALIZED expr` или `ALIAS expr`. Пример: `URLDomain String DEFAULT domain(URL)`.

Выражение `expr` необязательно. Если оно опущено, тип столбца должен быть указан явно, а значением по умолчанию будет `0` для числовых столбцов, `''` (пустая строка) для строковых столбцов, `[]` (пустой массив) для столбцов типа Array, `1970-01-01` для столбцов с типом Date или `NULL` для столбцов с типом Nullable.

Тип столбца со значением по умолчанию можно не указывать — в этом случае он выводится из типа `expr`. Например, тип столбца `EventDate DEFAULT toDate(EventTime)` будет Date.

Если указаны и тип данных, и выражение значения по умолчанию, неявно добавляется функция приведения типов, которая преобразует выражение к указанному типу. Пример: `Hits UInt32 DEFAULT 0` внутри представляется как `Hits UInt32 DEFAULT toUInt32(0)`.

Выражение значения по умолчанию `expr` может ссылаться на произвольные столбцы таблицы и константы. ClickHouse проверяет, что изменения структуры таблицы не приводят к появлению циклов при вычислении выражений. Для INSERT также проверяется, что выражения могут быть вычислены, то есть что переданы все столбцы, на основе которых их можно вычислить.

<div id="default">
  ### DEFAULT
</div>

`DEFAULT expr`

Обычное значение по умолчанию. Если значение такого столбца не указано в запросе `INSERT`, оно вычисляется на основе `expr`.

Пример:

```sql theme={null}
CREATE OR REPLACE TABLE test
(
    id UInt64,
    updated_at DateTime DEFAULT now(),
    updated_at_date Date DEFAULT toDate(updated_at)
)
ENGINE = MergeTree
ORDER BY id;

INSERT INTO test (id) VALUES (1);

SELECT * FROM test;
┌─id─┬──────────updated_at─┬─updated_at_date─┐
│  1 │ 2023-02-24 17:06:46 │      2023-02-24 │
└────┴─────────────────────┴─────────────────┘
```

<div id="materialized">
  ### MATERIALIZED
</div>

`MATERIALIZED expr`

Материализованное выражение. Значения таких столбцов автоматически вычисляются в соответствии с указанным материализованным выражением при вставке строк. Эти значения нельзя явно задавать в `INSERT`.

Кроме того, такие столбцы со значением по умолчанию не включаются в результат `SELECT *`. Это сделано для сохранения инварианта, согласно которому результат `SELECT *` всегда можно вставить обратно в таблицу с помощью `INSERT`. Это поведение можно отключить с помощью настройки `asterisk_include_materialized_columns`.

Пример:

```sql theme={null}
CREATE OR REPLACE TABLE test
(
    id UInt64,
    updated_at DateTime MATERIALIZED now(),
    updated_at_date Date MATERIALIZED toDate(updated_at)
)
ENGINE = MergeTree
ORDER BY id;

INSERT INTO test VALUES (1);

SELECT * FROM test;
┌─id─┐
│  1 │
└────┘

SELECT id, updated_at, updated_at_date FROM test;
┌─id─┬──────────updated_at─┬─updated_at_date─┐
│  1 │ 2023-02-24 17:08:08 │      2023-02-24 │
└────┴─────────────────────┴─────────────────┘

SELECT * FROM test SETTINGS asterisk_include_materialized_columns=1;
┌─id─┬──────────updated_at─┬─updated_at_date─┐
│  1 │ 2023-02-24 17:08:08 │      2023-02-24 │
└────┴─────────────────────┴─────────────────┘
```

<div id="ephemeral">
  ### EPHEMERAL
</div>

`EPHEMERAL [expr]`

Эфемерный столбец. Столбцы этого типа не хранятся в таблице, и их нельзя использовать в `SELECT`. Единственное назначение эфемерных столбцов — формировать на их основе выражения значений по умолчанию для других столбцов.

При вставке без явно указанных столбцов столбцы этого типа будут пропущены. Это нужно, чтобы сохранить инвариант: результат `SELECT *` всегда можно вставить обратно в таблицу с помощью `INSERT`.

Пример:

```sql theme={null}
CREATE OR REPLACE TABLE test
(
    id UInt64,
    unhexed String EPHEMERAL,
    hexed FixedString(4) DEFAULT unhex(unhexed)
)
ENGINE = MergeTree
ORDER BY id;

INSERT INTO test (id, unhexed) VALUES (1, '5a90b714');

SELECT
    id,
    hexed,
    hex(hexed)
FROM test
FORMAT Vertical;

Row 1:
──────
id:         1
hexed:      Z��
hex(hexed): 5A90B714
```

<div id="alias">
  ### ALIAS
</div>

`ALIAS expr`

Вычисляемые столбцы (синоним). Столбцы этого типа не хранятся в таблице, и в них нельзя вставлять значения.

Когда запросы SELECT явно обращаются к столбцам этого типа, значение вычисляется во время выполнения запроса из `expr`. По умолчанию `SELECT *` исключает столбцы ALIAS. Это поведение можно отключить с помощью настройки `asterisk_include_alias_columns`.

При использовании запроса ALTER для добавления новых столбцов старые данные для этих столбцов не записываются. Вместо этого при чтении старых данных, в которых нет значений для новых столбцов, выражения по умолчанию вычисляются на лету. Однако если для вычисления выражений требуются другие столбцы, не указанные в запросе, эти столбцы также будут прочитаны, но только для тех блоков данных, где это необходимо.

Если вы добавите новый столбец в таблицу, а затем измените его выражение по умолчанию, значения, используемые для старых данных, изменятся (для данных, значения которых не были сохранены на диске). Обратите внимание, что при выполнении фоновых слияний данные для столбцов, отсутствующих в одной из сливающихся частей, записываются в слитую часть.

Невозможно задать значения по умолчанию для элементов во вложенных структурах данных.

```sql theme={null}
CREATE OR REPLACE TABLE test
(
    id UInt64,
    size_bytes Int64,
    size String ALIAS formatReadableSize(size_bytes)
)
ENGINE = MergeTree
ORDER BY id;

INSERT INTO test VALUES (1, 4678899);

SELECT id, size_bytes, size FROM test;
┌─id─┬─size_bytes─┬─size─────┐
│  1 │    4678899 │ 4.46 MiB │
└────┴────────────┴──────────┘

SELECT * FROM test SETTINGS asterisk_include_alias_columns=1;
┌─id─┬─size_bytes─┬─size─────┐
│  1 │    4678899 │ 4.46 MiB │
└────┴────────────┴──────────┘
```

<div id="null-or-not-null-modifiers">
  ## Модификаторы `NULL` и `NOT NULL`
</div>

Модификаторы `NULL` и `NOT NULL`, указанные после типа данных в определении столбца, соответственно разрешают или запрещают делать его [Nullable](/docs/ru/reference/data-types/nullable).

Если тип не `Nullable` и указан `NULL`, он будет трактоваться как `Nullable`; если указан `NOT NULL`, то нет. Например, `INT NULL` — то же самое, что `Nullable(INT)`. Если тип — `Nullable` и указаны модификаторы `NULL` или `NOT NULL`, будет сгенерировано исключение.

См. также настройку [data\_type\_default\_nullable](/docs/ru/reference/settings/session-settings/other#data_type_default_nullable).

<div id="primary-key">
  ## Первичный ключ
</div>

При создании таблицы можно определить [первичный ключ](/docs/ru/reference/engines/table-engines/mergetree-family/mergetree#primary-keys-and-indexes-in-queries). Первичный ключ можно задать двумя способами:

<Columns cols={2}>
  <div>
    **В списке столбцов**

    ```sql theme={null}
    CREATE TABLE [db.]table_name
    (
        name1 type1, name2 type2, ...,
        PRIMARY KEY(expr1[, expr2,...])
    )
    ENGINE = engine;
    ```
  </div>

  <div>
    **Вне списка столбцов**

    ```sql theme={null}
    CREATE TABLE [db.]table_name
    (
        name1 type1, name2 type2, ...
    )
    ENGINE = engine
    PRIMARY KEY(expr1[, expr2,...]);
    ```
  </div>
</Columns>

<Tip>
  Нельзя использовать оба способа в одном запросе.
</Tip>

<div id="constraints">
  ## Задание ограничений таблицы
</div>

Наряду с описанием столбцов можно также задавать ограничения:

<div id="constraint">
  ### CONSTRAINT
</div>

```sql theme={null}
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
    name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1] [compression_codec] [TTL expr1],
    ...
    CONSTRAINT constraint_name_1 CHECK boolean_expr_1,
    ...
) ENGINE = engine
```

`boolean_expr_1` может быть любым логическим выражением. Если для таблицы заданы ограничения, каждое из них будет проверяться для каждой строки в запросе `INSERT`. Если какое-либо ограничение нарушено, сервер сгенерирует исключение с именем ограничения и выражением проверки.

Добавление большого количества ограничений может негативно сказаться на производительности крупных запросов `INSERT`.

Существующие ограничения для всех таблиц можно просмотреть в таблице [`system.constraints`](/docs/ru/reference/system-tables/constraints).

<div id="assume">
  ### ASSUME
</div>

Предложение `ASSUME` используется для задания `CONSTRAINT` для таблицы, которое считается истинным. Затем это ограничение может использоваться оптимизатором для повышения производительности SQL-запросов.

Рассмотрим пример, в котором `ASSUME CONSTRAINT` используется при создании таблицы `users_a`:

```sql theme={null}
CREATE TABLE users_a (
    uid Int16, 
    name String, 
    age Int16, 
    name_len UInt8 MATERIALIZED length(name), 
    CONSTRAINT c1 ASSUME length(name) = name_len
) 
ENGINE=MergeTree 
ORDER BY (name_len, name);
```

Здесь `ASSUME CONSTRAINT` используется, чтобы указать, что функция `length(name)` всегда равна значению столбца `name_len`. Это означает, что всякий раз, когда в запросе вызывается `length(name)`, ClickHouse может заменить её на `name_len`, что должно работать быстрее, поскольку не требует вызова функции `length()`.

Затем, при выполнении запроса `SELECT name FROM users_a WHERE length(name) < 5;`, ClickHouse может оптимизировать его до `SELECT name FROM users_a WHERE name_len < 5`; благодаря `ASSUME CONSTRAINT`. Это может ускорить выполнение запроса, поскольку не нужно вычислять длину `name` для каждой строки.

`ASSUME CONSTRAINT` **не обеспечивает соблюдение ограничения**, а лишь сообщает оптимизатору, что ограничение выполняется. Если ограничение на самом деле не выполняется, результаты запросов могут быть некорректными. Поэтому использовать `ASSUME CONSTRAINT` следует только в том случае, если вы уверены, что ограничение действительно выполняется.

<div id="ttl-expression">
  ## Укажите срок хранения с TTL
</div>

Определяет срок хранения значений. Может быть указано только для таблиц семейства MergeTree. Подробное описание см. в разделе [TTL для столбцов и таблиц](/docs/ru/reference/engines/table-engines/mergetree-family/mergetree#table_engine-mergetree-ttl).

<div id="column_compression_codec">
  ## Выбор кодеков сжатия для столбцов
</div>

<a id="general-purpose-codecs" />

<a id="none" />

<a id="lz4" />

<a id="lz4hc" />

<a id="zstd" />

<a id="zxc" />

<a id="zstd_qat" />

<a id="deflate_qpl" />

<a id="specialized-codecs" />

<a id="delta" />

<a id="doubledelta" />

<a id="gcd" />

<a id="gorilla" />

<a id="alp" />

<a id="fpc" />

<a id="sz3" />

<a id="t64" />

<a id="quantized" />

<a id="encryption-codecs" />

<a id="aes_128_gcm_siv" />

<a id="aes-256-gcm-siv" />

<a id="adaptive-codec-selection" />

По умолчанию в самоуправляемой версии ClickHouse используется сжатие `lz4`, а в ClickHouse Cloud — `zstd`. Также можно задать метод сжатия для каждого отдельного столбца в запросе `CREATE TABLE`:

```sql theme={null}
CREATE TABLE codec_example
(
    dt Date CODEC(ZSTD),
    ts DateTime CODEC(LZ4HC),
    float_value Float32 CODEC(NONE),
    double_value Float64 CODEC(LZ4HC(9)),
    value Float32 CODEC(Delta, ZSTD)
)
ENGINE = <Engine>
...
```

Сведения о доступных универсальных, специализированных кодеках и кодеках шифрования см. в разделе [Кодеки сжатия столбцов](/docs/ru/reference/statements/create/table/codec).

<div id="temporary-tables">
  ## Создание временных таблиц
</div>

ClickHouse поддерживает временные таблицы, которые удаляются после завершения сеанса. Подробнее см. [CREATE TEMPORARY TABLE](/docs/ru/reference/statements/create/table/temporary-table).

<div id="replace-table">
  ## Атомарное обновление таблицы с помощью REPLACE TABLE
</div>

<a id="syntax" />

<a id="examples" />

Оператор `REPLACE` позволяет атомарно обновить таблицу [атомарно](/docs/ru/concepts/core-concepts/glossary#atomicity). Подробнее см. в разделе [REPLACE TABLE](/docs/ru/reference/statements/create/table/replace-table).

<div id="comment-clause">
  ## Добавление комментария к таблице
</div>

Комментарий к таблице можно добавить при её создании.

**Синтаксис**

```sql theme={null}
CREATE TABLE [db.]table_name
(
    name1 type1, name2 type2, ...
)
ENGINE = engine
COMMENT 'Comment'
```

<Note>
  Предложение `COMMENT` должно быть указано **после** всех предложений, относящихся к хранилищу, таких как `PARTITION BY`, `ORDER BY` и `SETTINGS`, специфичных для хранилища.

  После предложения `COMMENT` будут разбираться только `SETTINGS`, относящиеся к запросу (например, `max_threads` и т. д.), а не настройки, связанные с хранилищем.

  Это означает, что правильный порядок предложений такой:

  * `ENGINE`
  * предложения хранилища
  * `COMMENT`
  * настройки запроса (если есть)
</Note>

**Пример**

```sql title="Query" theme={null}
CREATE TABLE t1 (x String) ENGINE = Memory COMMENT 'The temporary table';
SELECT name, comment FROM system.tables WHERE name = 't1';
```

```text title="Response" theme={null}
┌─name─┬─comment─────────────┐
│ t1   │ The temporary table │
└──────┴─────────────────────┘
```

<div id="related-content">
  ## Материалы по теме
</div>

* Блог: [Оптимизация ClickHouse с помощью схем и кодеков](https://clickhouse.com/blog/optimize-clickhouse-codecs-compression-schema)
* Блог: [Работа с временными рядами в ClickHouse](https://clickhouse.com/blog/working-with-time-series-data-and-functions-ClickHouse)
