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

CREATE TABLE

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

По умолчанию таблицы создаются только на текущем сервере. Распределенные DDL-запросы реализуются как клаузула ON CLUSTER, которая описана отдельно.

Синтаксические формы

С Явной Схемой

Создает таблицу с именем table_name в базе данных db или в текущей базе данных, если db не задан, со структурой, указанной в скобках, и движком engine. Структура таблицы представляет собой список описаний колонок, вторичных индексов и ограничений. Если поддерживается первичный ключ движком, он будет обозначен как параметр для движка таблицы.

Описание колонки — это name type в самом простом случае. Пример: RegionID UInt32.

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

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

Комментарии могут быть добавлены для колонок и для таблицы.

С Схемой, Подобной Другой Таблице

Создает таблицу с той же структурой, что и у другой таблицы. Вы можете указать другой движок для таблицы. Если движок не указан, будет использован тот же движок, что и для таблицы db2.name2.

Со Схемой и Данной, Клонированной из Другой Таблицы

Создает таблицу с тем же строением, что и у другой таблицы. Вы можете указать другой движок для таблицы. Если движок не указан, будет использован тот же движок, что и для таблицы db2.name2. После создания новой таблицы все партиции из db2.name2 будут прикреплены к ней. Другими словами, данные из db2.name2 клонируются в db.table_name при создании. Этот запрос эквивалентен следующему:

Из Табличной Функции

Создает таблицу с тем же результатом, что и у указанной табличной функции. Созданная таблица будет работать так же, как и соответствующая таблица функция, которая была указана.

Из Запроса SELECT

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

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

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

подсказка

В ClickHouse Cloud, пожалуйста, разбейте это на два шага:

  1. Создайте структуру таблицы
  1. Заполните таблицу

Пример

Запрос:

Результат:

Модификаторы NULL Или NOT NULL

Модификаторы NULL и NOT NULL после типа данных в определении колонки позволяют или не позволяют быть Nullable.

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

Смотрите также настройку data_type_default_nullable.

Значения по Умолчанию

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

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

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

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

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

DEFAULT

DEFAULT expr

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

Пример:

MATERIALIZED

MATERIALIZED expr

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

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

Пример:

EPHEMERAL

EPHEMERAL [expr]

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

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

Пример:

ALIAS

ALIAS expr

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

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

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

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

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

Первичный Ключ

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

  • Внутри списка колонок
  • Снаружи списка колонок
подсказка

Вы не можете сочетать оба способа в одном запросе.

Ограничения

Вместе с описаниями колонок могут быть указаны ограничения:

CONSTRAINT

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

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

ASSUME

Клауза ASSUME используется для определения CONSTRAINT, который предполагается как истинный. Это ограничение затем может быть использовано оптимизатором для повышения производительности SQL-запросов.

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

Здесь 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 только если вы уверены, что ограничение истинно.

Выражение TTL

Определяет время хранения значений. Может быть указано только для таблиц семейства MergeTree. Для подробного описания смотрите TTL для колонок и таблиц.

Кодеки Сжатия Колонок

По умолчанию ClickHouse применяет сжатие lz4 в версии с самоуправлением и zstd в ClickHouse Cloud.

Для семейства движков MergeTree вы можете изменить метод сжатия по умолчанию в разделе compression конфигурации сервера.

Вы также можете определить метод сжатия для каждой отдельной колонки в запросе CREATE TABLE.

Кодек Default может быть указан для ссылки на сжатие по умолчанию, которое может зависеть от различных настроек (и свойств данных) во время выполнения. Пример: value UInt64 CODEC(Default) - то же самое, что и отсутствие спецификации кодека.

Вы также можете удалить текущий CODEC из колонки и использовать сжатие по умолчанию из config.xml:

Кодеки могут комбинироваться в пайплайне, например, CODEC(Delta, Default).

подсказка

Вы не можете декомпрессировать файлы базы данных ClickHouse с помощью внешних утилит, таких как lz4. Вместо этого используйте специальную утилиту clickhouse-compressor.

Сжатие поддерживается для следующих движков таблиц:

  • MergeTree семья. Поддерживает кодеки сжатия колонок и выбор метода сжатия по умолчанию с помощью настроек compression.
  • Log семья. По умолчанию использует метод сжатия lz4 и поддерживает кодеки сжатия колонок.
  • Set. Поддерживает только сжатие по умолчанию.
  • Join. Поддерживает только сжатие по умолчанию.

ClickHouse поддерживает кодеки общего назначения и специализированные кодеки.

Кодеки Общего Назначения

NONE

NONE — Без сжатия.

LZ4

LZ4 — Безопасный алгоритм сжатия данных, используемый по умолчанию. Применяет быстрое сжатие LZ4.

LZ4HC

LZ4HC[(level)] — алгоритм LZ4 HC (высокое сжатие) с настраиваемым уровнем. Уровень по умолчанию: 9. Установка level <= 0 применяет уровень по умолчанию. Возможные уровни: [1, 12]. Рекомендуемый диапазон уровней: [4, 9].

ZSTD

ZSTD[(level)]алгоритм сжатия ZSTD с настраиваемым level. Возможные уровни: [1, 22]. Уровень по умолчанию: 1.

Высокие уровни сжатия полезны для асимметричных сценариев, таких как сжать один раз, декомпрессировать повторно. Более высокие уровни означают лучшее сжатие и большее использование CPU.

ZSTD_QAT

Not supported in ClickHouse Cloud

ZSTD_QAT[(level)]алгоритм сжатия ZSTD с настраиваемым уровнем, реализованный с помощью Intel® QATlib и Intel® QAT ZSTD Plugin. Возможные уровни: [1, 12]. Уровень по умолчанию: 1. Рекомендуемый диапазон уровней: [6, 12]. Применяются некоторые ограничения:

  • ZSTD_QAT отключен по умолчанию и может быть использован только после включения настройки конфигурации enable_zstd_qat_codec.
  • Для сжатия ZSTD_QAT пытается использовать устройство разгрузки Intel® QAT (QuickAssist Technology). Если такое устройство не найдено, будет использовано программное сжатие ZSTD.
  • Декомпрессия всегда выполняется в программном обеспечении.

DEFLATE_QPL

Not supported in ClickHouse Cloud

DEFLATE_QPLалгоритм сжатия Deflate, реализованный библиотекой Intel® Query Processing Library. Применяются некоторые ограничения:

  • DEFLATE_QPL отключен по умолчанию и может быть использован только после включения настройки конфигурации enable_deflate_qpl_codec.
  • DEFLATE_QPL требует, чтобы сборка ClickHouse была скомпилирована с инструкциями SSE 4.2 (по умолчанию это так). Смотрите Сборка Clickhouse с DEFLATE_QPL для получения подробной информации.
  • DEFLATE_QPL работает лучше, если система имеет устройство разгрузки Intel® IAA (In-Memory Analytics Accelerator). Смотрите Конфигурация ускорителя и Тестирование с DEFLATE_QPL для получения подробной информации.
  • Данные, сжатые с помощью DEFLATE_QPL, могут передаваться только между узлами ClickHouse, скомпилированными с включенным SSE 4.2.

Специализированные Кодеки

Эти кодеки предназначены для повышения эффективности сжатия, используя специфические особенности данных. Некоторые из этих кодеков не сжимают данные сами по себе, а предварительно обрабатывают данные так, чтобы второй этап сжатия с использованием кодека общего назначения мог достичь более высокого коэффициента сжатия данных.

Delta

Delta(delta_bytes) — Подход к сжатию, при котором сырые значения заменяются на разность двух соседних значений, кроме первого значения, которое остается неизменным. До delta_bytes используются для хранения дельта-значений, поэтому delta_bytes — это максимальный размер сырых значений. Возможные значения delta_bytes: 1, 2, 4, 8. Значение по умолчанию для delta_bytessizeof(type), если оно равно 1, 2, 4 или 8. Во всех остальных случаях оно равно 1. Delta — это кодек подготовительных данных, т.е. его нельзя использовать отдельно.

DoubleDelta

DoubleDelta(bytes_size) — Вычисляет дельту дельт и записывает ее в компактной двоичной форме. Возможные значения bytes_size: 1, 2, 4, 8, значение по умолчанию — sizeof(type), если оно равно 1, 2, 4 или 8. Во всех остальных случаях оно равно 1. Оптимальные коэффициенты сжатия достигаются для монотонных последовательностей с постоянным шагом, таких как данные временных рядов. Может использоваться с любым типом фиксированной ширины. Реализует алгоритм, используемый в Gorilla TSDB, расширяя его для поддержки 64-битных типов. Использует 1 дополнительный бит для 32-битных дельт: 5-битные префиксы вместо 4-битных префиксов. Для получения дополнительной информации см. "Сжатие временных меток" в Gorilla: Быстрая, Масштабируемая, Внутренняя База Данных Временных Рядов. DoubleDelta — это кодек подготовительных данных, т.е. его нельзя использовать отдельно.

GCD

GCD() - Вычисляет наибольший общий делитель (НОД) значений в колонке, затем делит каждое значение на НОД. Может использоваться с целочисленными, десятичными и колонками даты/времени. Кодек хорошо подходит для колонок с изменяющимися (увеличивающимися или уменьшающимися) значениями, кратными НОД, например 24, 28, 16, 24, 8, 24 (НОД = 4). GCD — это кодек подготовительных данных, т.е. его нельзя использовать отдельно.

Gorilla

Gorilla(bytes_size) — Рассчитывает XOR между текущим и предыдущим значением с плавающей точкой и записывает его в компактной двоичной форме. Чем меньше разница между последовательными значениями, т.е. чем медленнее меняются значения серии, тем лучше коэффициент сжатия. Реализует алгоритм, используемый в Gorilla TSDB, расширяя его для поддержки 64-битных типов. Возможные значения bytes_size: 1, 2, 4, 8, значение по умолчанию — sizeof(type), если оно равно 1, 2, 4 или 8. Во всех остальных случаях оно равно 1. Для получения дополнительной информации см. раздел 4.1 в Gorilla: Быстрая, Масштабируемая, Внутренняя База Данных Временных Рядов.

FPC

FPC(level, float_size) - Многократно предсказывает следующее значение с плавающей точкой в последовательности, используя лучший из двух предсказателей, затем XOR-ит фактическое значение и предсказанное значение, и сжимает результат с помощью сжатия лидирующих нулей. Подобно Gorilla, это эффективно при хранении последовательности значений с плавающей точкой, которые медленно изменяются. Для 64-битных значений (двойные) FPC быстрее, чем Gorilla, для 32-битных значений ваши результаты могут варьироваться. Возможные значения level: 1-28, значение по умолчанию — 12. Возможные значения float_size: 4, 8, значение по умолчанию — sizeof(type), если тип — Float. Во всех остальных случаях оно равно 4. Для получения подробного описания алгоритма см. Высокопроизводительное сжатие данных с плавающей точкой двойной точности.

T64

T64 — Метод сжатия, который обрезает неиспользуемые старшие биты значений в целочисленных типах данных (включая Enum, Date и DateTime). На каждом шаге своего алгоритма кодек берет блок из 64 значений, помещает их в матрицу 64x64 бит, транспонирует, обрезает неиспользуемые биты значений и возвращает остальную часть в виде последовательности. Неиспользуемые биты — это биты, которые не отличаются между максимальными и минимальными значениями во всей части данных, для которой применяется сжатие.

Кодеки DoubleDelta и Gorilla используются в Gorilla TSDB в качестве компонентов его алгоритма сжатия. Подход Gorilla эффективен в сценариях, когда существует последовательность медленно изменяющихся значений с их временными метками. Временные метки эффективно сжимаются кодеком DoubleDelta, а значения эффективно сжимаются кодеком Gorilla. Например, чтобы получить эффективно хранимую таблицу, вы можете создать ее в следующей конфигурации:

Кодеки Шифрования

Эти кодеки фактически не сжимают данные, а вместо этого шифруют данные на диске. Эти кодеки доступны только при указании ключа шифрования в настройках encryption. Обратите внимание, что шифрование имеет смысл только в конце пайплайнов кодеков, потому что зашифрованные данные обычно не могут быть сжаты каким-либо разумным образом.

Кодеки шифрования:

AES_128_GCM_SIV

CODEC('AES-128-GCM-SIV') — Шифрует данные с помощью AES-128 в режиме GCM-SIV RFC 8452.

AES-256-GCM-SIV

CODEC('AES-256-GCM-SIV') — Шифрует данные с помощью AES-256 в режиме GCM-SIV.

Эти кодеки используют фиксированный nonce, и шифрование, следовательно, детерминировано. Это делает его совместимым с движками дедупликации, такими как ReplicatedMergeTree, но имеет слабость: когда один и тот же блок данных шифруется дважды, полученный шифротекст будет точно таким же, поэтому злоумышленник, который может читать диск, может видеть это равенство (хотя только равенство, не получая его содержимое).

примечание

Большинство движков, включая семью "*MergeTree", создают файлы индексов на диске, не применяя кодеки. Это означает, что открытый текст появится на диске, если зашифрованная колонка индексируется.

примечание

Если вы выполните запрос SELECT с упоминанием конкретного значения в зашифрованной колонке (например, в его клаузе WHERE), значение может появиться в system.query_log. Вы можете отключить ведение журнала.

Пример

примечание

Если требуется применить сжатие, это должно быть явно указано. В противном случае только шифрование будет применено к данным.

Пример

Временные Таблицы

примечание

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

ClickHouse поддерживает временные таблицы, которые имеют следующие характеристики:

  • Временные таблицы исчезают, когда сессия заканчивается, включая, если соединение потеряно.
  • Временная таблица использует движок таблицы Memory, когда движок не указан, и может использовать любой движок таблицы, за исключением реплицированных и движков KeeperMap.
  • БД не может быть указана для временной таблицы. Она создается вне баз данных.
  • Невозможно создать временную таблицу с распределенным DDL запросом на всех серверах кластера (используя ON CLUSTER): эта таблица существует только в текущей сессии.
  • Если временная таблица имеет то же имя, что и другая, и запрос указывает имя таблицы без указания БД, будет использована временная таблица.
  • Для распределенной обработки запросов временные таблицы с движком Memory, используемые в запросе, передаются на удаленные серверы.

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

В большинстве случаев временные таблицы не создаются вручную, а создаются при использовании внешних данных для запроса или для распределенного (GLOBAL) IN. Для получения дополнительной информации смотрите соответствующие разделы.

Можно использовать таблицы с ENGINE = Memory вместо временных таблиц.

REPLACE TABLE

Запрос REPLACE позволяет вам обновить таблицу атомарно.

примечание

Этот оператор поддерживается для движков баз данных Atomic и Replicated, которые являются движками баз данных по умолчанию для ClickHouse и ClickHouse Cloud соответственно.

Обычно, если вам нужно удалить некоторые данные из таблицы, вы можете создать новую таблицу и заполнить её запросом SELECT, который не извлекает нежелательные данные, затем удалить старую таблицу и переименовать новую. Этот подход демонстрируется в приведенном ниже примере:

Вместо приведенного выше подхода также можно использовать REPLACE (если вы используете движки баз данных по умолчанию), чтобы добиться того же результата:

Синтаксис

примечание

Все синтаксические формы для оператора CREATE также работают для этого оператора. Вызов REPLACE для несуществующей таблицы приведет к ошибке.

Примеры:

Рассмотрим следующую таблицу:

Мы можем использовать оператор REPLACE для очистки всех данных:

Или мы можем использовать оператор REPLACE, чтобы изменить структуру таблицы:

Клаузула COMMENT

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

Синтаксис

Пример

Запрос:

Результат: