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

СОЗДАТЬ ТАБЛИЦУ

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

По умолчанию таблицы создаются только на текущем сервере. Распределенные 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 для колонок с возможностью хранения NULL.

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

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

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

DEFAULT

DEFAULT expr

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

Пример:

MATERIALIZED

MATERIALIZED expr

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

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

Пример:

EPHEMERAL

EPHEMERAL [expr]

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

Вставка без явного указания колонок пропустит колонки этого типа. Это сделано для сохранения свойства того, что результат 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 в версии self-managed и 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_bytes равно sizeof(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: Быстрая, масштабируемая in-memory база данных временных рядов. 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: Быстрая, масштабируемая in-memory база данных временных рядов.

FPC

FPC(level, float_size) - Многократно прогнозирует следующее значение с плавающей запятой в последовательности с использованием лучшего из двух предсказателей, затем выполняет XOR между реальным и предсказанным значением и сжимает результат с помощью сжатия ведущими нулями. Похоже на Gorilla, это эффективно при хранении серии значений с плавающей запятой, которые медленно меняются. Для значений 64-битных (double) 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 в режиме RFC 8452 GCM-SIV.

AES-256-GCM-SIV

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

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

примечание

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

примечание

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

Пример

примечание

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

Пример

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

примечание

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

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

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

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

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

Существуют таблицы с ENGINE = Memory, которые могут использоваться вместо временных таблиц.

ЗАМЕНИТЬ ТАБЛИЦУ

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

примечание

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

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

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

Синтаксис

примечание

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

Примеры:

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

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

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

Клаузула COMMENT

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

Синтаксис

Пример

Запрос:

Результат: