ClickHouse Go
Простой пример
Давайте начнем с простого примера. Это подключится к ClickHouse и выполнит выборку из системной базы данных. Для начала вам понадобятся ваши данные для подключения.
Данные подключения
Чтобы подключиться к ClickHouse с помощью нативного TCP, вам нужна следующая информация:
-
ХОСТ и ПОРТ: обычно, порт 9440 при использовании TLS или 9000 при отсутствии TLS.
-
ИМЯ БАЗЫ ДАННЫХ: по умолчанию есть база данных с именем
default
, используйте имя базы данных, к которой вы хотите подключиться. -
ИМЯ ПОЛЬЗОВАТЕЛЯ и ПАРОЛЬ: по умолчанию имя пользователя
default
. Используйте имя пользователя, подходящее для вашего случая.
Данные для вашей службы ClickHouse Cloud доступны в консоли ClickHouse Cloud. Выберите службу, к которой вы хотите подключиться, и нажмите Подключиться:

Выберите Native, и данные будут доступны в примере команды clickhouse-client
.

Если вы используете self-managed ClickHouse, детали подключения задаются вашим администратором ClickHouse.
Инициализация модуля
Скопируйте пример кода
Скопируйте этот код в каталог clickhouse-golang-example
как main.go
.
Выполните go mod tidy
Установите данные подключения
Ранее вы искали свои данные для подключения. Установите их в main.go
в функции connect()
:
Запустите пример
Узнать больше
Остальная часть документации в этой категории охватывает детали клиента ClickHouse Go.
Клиент ClickHouse Go
ClickHouse поддерживает два официальных клиента Go. Эти клиенты являются взаимодополняющими и намеренно поддерживают разные варианты использования.
- clickhouse-go - клиент высокого уровня, который поддерживает либо стандартный интерфейс Go базы данных/sql, либо нативный интерфейс.
- ch-go - клиент низкого уровня. Только нативный интерфейс.
clickhouse-go предоставляет интерфейс высокого уровня, позволяя пользователям выполнять запросы и вставлять данные, используя ориентированную на строки семантику и пакетирование, которые снисходительны к типам данных - значения будут преобразованы при условии, что не произойдет потери точности. В то время как ch-go предоставляет оптимизированный ориентированный по колонкам интерфейс, обеспечивающий быструю потоковую передачу блоков данных с низкой загрузкой ЦП и памяти за счет строгости типов и более сложного использования.
С версии 2.3, clickhouse-go использует ch-go для низкоуровневых функций, таких как кодирование, декодирование и сжатие. Обратите внимание, что clickhouse-go также поддерживает стандарт интерфейса database/sql
. Оба клиента используют нативный формат для своего кодирования, чтобы обеспечить оптимальную производительность и могут взаимодействовать по нативному протоколу ClickHouse. clickhouse-go также поддерживает HTTP в качестве механизма передачи для случаев, когда пользователям необходимо проксировать или распределять нагрузку.
При выборе клиентской библиотеки пользователи должны быть осведомлены о соответствующих плюсах и минусах - см. Выбор клиентской библиотеки.
Нативный формат | Нативный протокол | HTTP протокол | Ориентированный на строки API | Ориентированный по колонкам API | Гибкость типов | Сжатие | Места для запросов | |
---|---|---|---|---|---|---|---|---|
clickhouse-go | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
ch-go | ✅ | ✅ | ✅ | ✅ |
Выбор клиента
Выбор клиентской библиотеки зависит от ваших шаблонов использования и необходимости в оптимальной производительности. Для сценариев, ориентированных на вставку, где требуется миллионы вставок в секунду, мы рекомендуем использовать клиент низкого уровня ch-go. Этот клиент избегает связанных накладных расходов на преобразование данных из ориентированного на строки формата в колонки, как того требует нативный формат ClickHouse. Более того, он избегает любой рефлексии или использования типа interface{}
(any
), чтобы упростить использование.
Для рабочих нагрузок запросов, сосредоточенных на агрегатах или рабочих нагрузках с низким уровнем вставок, clickhouse-go предоставляет знакомый интерфейс database/sql
и более простую семантику строк. Пользователи также могут опционально использовать HTTP в качестве транспортного протокола и воспользоваться вспомогательными функциями для маршалинга строк в структуры и обратно.
Клиент clickhouse-go
Клиент clickhouse-go предоставляет два API интерфейса для взаимодействия с ClickHouse:
- Специфичный API клиента ClickHouse
- Стандарт
database/sql
- общий интерфейс вокруг SQL баз данных, предоставленный Golang.
Хотя database/sql
предоставляет универсальный интерфейс для баз данных, позволяя разработчикам абстрагировать свое хранилище данных, он накладывает некоторые типы и семантику запросов, которые влияют на производительность. По этой причине специфичный для клиента API следует использовать, когда производительность важна. Тем не менее, пользователи, которые хотят интегрировать ClickHouse в инструменты, которые поддерживают несколько баз данных, могут предпочесть использовать стандартный интерфейс.
Оба интерфейса кодируют данные, используя нативный формат и нативный протокол для связи. Кроме того, стандартный интерфейс поддерживает связь по HTTP.
Нативный формат | Нативный протокол | HTTP протокол | Поддержка массовой записи | Маршалинг структур | Сжатие | Места для запросов | |
---|---|---|---|---|---|---|---|
ClickHouse API | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | |
database/sql API | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Установка
v1 драйвера устарел и не будет получать обновления функций или поддержки новых типов ClickHouse. Пользователи должны перейти на v2, который предлагает лучшую производительность.
Чтобы установить версию 2.x клиента, добавьте пакет в ваш файл go.mod:
require github.com/ClickHouse/clickhouse-go/v2 main
Или клонируйте репозиторий:
Чтобы установить другую версию, соответственно измените путь или имя ветки.
Версионирование и совместимость
Клиент выпускается независимо от ClickHouse. 2.x представляет собой текущую основную версию, находящуюся в разработке. Все версии 2.x должны быть совместимы друг с другом.
Совместимость ClickHouse
Клиент поддерживает:
- Все текущие поддерживаемые версии ClickHouse, как указано здесь. Поскольку версии ClickHouse больше не поддерживаются, они также больше не активно тестируются на совместимость с выходами клиента.
- Все версии ClickHouse в течение 2 лет с даты выпуска клиента. Обратите внимание, что только версии LTS активно тестируются.
Совместимость Golang
Версия клиента | Версии Golang |
---|---|
=> 2.0 <= 2.2 | 1.17, 1.18 |
>= 2.3 | 1.18 |
API клиента ClickHouse
Все примеры кода для API клиента ClickHouse можно найти здесь.
Подключение
Следующий пример, который возвращает версию сервера, демонстрирует подключение к ClickHouse - при условии, что ClickHouse не защищен и доступен с помощью пользователя по умолчанию.
Обратите внимание, что мы используем стандартный нативный порт для подключения.
Для всех последующих примеров, если не указано иное, мы предполагаем, что используется переменная подключения ClickHouse conn
, которая была создана и доступна.
Настройки подключения
При открытии подключения можно использовать структуру Options для управления поведением клиента. Доступны следующие параметры:
Protocol
- либо Нативный, либо HTTP. HTTP в настоящее время поддерживается только для API database/sql.TLS
- параметры TLS. Не нулевое значение включает TLS. См. Использование TLS.Addr
- срез адресов, включая порт.Auth
- данные для аутентификации. См. Аутентификация.DialContext
- пользовательская функция соединения для определения того, как устанавливать соединения.Debug
- true/false для включения отладки.Debugf
- предоставляет функцию для обработки отладочного вывода. Требует, чтобыdebug
было установлено на true.Settings
- карта настроек ClickHouse. Эти настройки будут применены ко всем запросам ClickHouse. Использование контекста позволяет устанавливать настройки для каждого запроса.Compression
- включить сжатие для блоков. См. Сжатие.DialTimeout
- максимальное время для установки соединения. По умолчанию1s
.MaxOpenConns
- максимальное количество соединений для использования в любой момент времени. Большее или меньшее количество соединений может находиться в неактивном пуле, но только это количество может использоваться в любой момент времени. По умолчаниюMaxIdleConns+5
.MaxIdleConns
- количество соединений, которые необходимо поддерживать в пуле. Соединения будут повторно использоваться, если это возможно. По умолчанию5
.ConnMaxLifetime
- максимальный срок службы, на который следует оставить соединение доступным. По умолчанию 1 час. Соединения уничтожаются после этого времени, при этом новые соединения добавляются в пул по мере необходимости.ConnOpenStrategy
- определяет, как должен потребляться список адресов узлов и как должны открываться соединения. См. Подключение к нескольким узлам.BlockBufferSize
- максимальное количество блоков для декодирования в буфер за один раз. Более крупные значения увеличат параллелизацию за счет увеличения расхода памяти. Размеры блоков зависят от запроса, поэтому, хотя вы можете задать это для соединения, мы рекомендуем вам переопределить его для каждого запроса в зависимости от данных, которые он возвращает. По умолчанию2
.
Пул соединений
Клиент поддерживает пул соединений, повторно используя их по мере необходимости для запросов. В любой момент будет использоваться не более MaxOpenConns
, при этом максимальный размер пула контролируется параметром MaxIdleConns
. Клиент получит соединение из пула для выполнения каждого запроса, возвращая его обратно в пул для повторного использования. Соединение используется на протяжении выполнения пакета и освобождается при вызове Send()
.
Нет гарантии, что одно и то же соединение в пуле будет использоваться для последующих запросов, если пользователь не установит MaxOpenConns=1
. Это редко необходимо, но может потребоваться в случаях, когда пользователи используют временные таблицы.
Кроме того, обратите внимание, что ConnMaxLifetime
по умолчанию составляет 1 час. Это может привести к случаям, когда нагрузка на ClickHouse будет несбалансированной, если узлы покинут кластер. Это может произойти, когда узел становится недоступным, соединения будут балансироваться по другим узлам. Эти соединения будут сохраняться и не будут обновляться в течение 1 часа по умолчанию, даже если проблемный узел вернется в кластер. Рассмотрите возможность уменьшения этого значения в случаях с высокой нагрузкой.
Использование TLS
На низком уровне все методы подключения клиента (DSN/OpenDB/Open
) будут использовать пакет Go tls для установления защищенного соединения. Клиент знает, что следует использовать TLS, если структура Options содержит ненулевой указатель на tls.Config
.
Этот минимальный TLS.Config
обычно достаточно для подключения к защищенному нативному порту (обычно 9440) на сервере ClickHouse. Если у сервера ClickHouse нет действительного сертификата (просрочен, неправильное имя хоста, не подписан общеизвестным корневым удостоверяющим центром), InsecureSkipVerify
может быть истинным, но это настоятельно не рекомендуется.
Если необходимо установить дополнительные параметры TLS, код приложения должен настроить желаемые поля в структуре tls.Config
. Это может включать конкретные наборы шифров, принуждение определенной версии TLS (например, 1.2 или 1.3), добавление внутренней цепочки CA сертификатов, добавление клиентского сертификата (и закрытого ключа), если это требуется сервером ClickHouse, и большинству других опций, которые приходят с более специализированной настройкой безопасности.
Аутентификация
Укажите структуру Auth в деталях подключения, чтобы указать имя пользователя и пароль.
Подключение к нескольким узлам
Несколько адресов можно указать через структуру Addr
.
Доступны две стратегии подключения:
ConnOpenInOrder
(по умолчанию) - адреса используются в порядке. Позже адреса используются только в случае неудачи подключения с использованием адресов, указанных ранее в списке. Это фактически стратегия отказоустойчивости.ConnOpenRoundRobin
- Нагрузка распределяется между адресами с использованием стратегии равномерного распределения.
Это можно контролировать через параметр ConnOpenStrategy
Выполнение
Произвольные команды могут выполняться с помощью метода Exec
. Это полезно для DDL и простых операторов. Это не следует использовать для крупных вставок или итераций запросов.
Обратите внимание на возможность передать контекст в запрос. Это может быть использовано для передачи специфических настроек на уровне запроса - см. Использование контекста.
Пакетная вставка
Чтобы вставить большое количество строк, клиент обеспечивает пакетную семантику. Это требует подготовки пакета, в который могут быть добавлены строки. Этот пакет затем отправляется через метод Send()
. Пакеты будут храниться в памяти до выполнения Send.
Рекомендации для ClickHouse применимы здесь. Пакеты не должны разделяться между goroutines - конструкция отдельного пакета для каждой рутины.
Из приведенного выше примера обратите внимание на необходимость, чтобы типы переменных соответствовали типу колонки при добавлении строк. Хотя отображение обычно очевидно, этот интерфейс пытается быть гибким, и типы будут преобразованы, при условии, что не произойдет потери точности. Например, следующий код демонстрирует вставку строки в datetime64.
Для полного обзора поддерживаемых типов Go для каждого типа колонки смотрите Преобразования типов.
Запросы к строкам
Пользователи могут либо запрашивать одну строку, используя метод QueryRow
, либо получать курсор для итерации по набору результатов через Query
. В то время как первый принимает пункт назначения для данных, которые должны быть сериализованы, последний требует вызова Scan
на каждой строке.
Обратите внимание, что в обоих случаях мы обязаны передать указатели на переменные, в которые мы хотим сериализовать соответствующие значения столбцов. Они должны передаваться в порядке, указанном в операторе SELECT
- по умолчанию будет использоваться порядок объявления столбцов, если используется SELECT *
, как показано выше.
Подобно вставке, метод Scan требует, чтобы целевые переменные были подходящего типа. Это также направлено на гибкость, при этом типы преобразуются, где это возможно, при условии, что не произойдет потеря точности, например, в приведенном выше примере показано, что столбец UUID считывается в строковую переменную. Для полного списка поддерживаемых типов Go для каждого типа колонки смотрите Преобразования типов.
Наконец, обратите внимание на возможность передачи Context
в методы Query
и QueryRow
. Это может быть использовано для настроек на уровне запроса - смотрите Использование контекста для получения дополнительных деталей.
Асинхронная вставка
Асинхронные вставки поддерживаются через метод Async. Это позволяет пользователю указать, должен ли клиент ожидать завершения вставки на сервере или отвечать сразу после получения данных. Это эффективно управляет параметром wait_for_async_insert.
Вставка по колонкам
Вставки могут выполняться в колонковом формате. Это может обеспечить преимущества в производительности, если данные уже организованы в этой структуре, избегая необходимости преобразовывать строки.
Использование структур
Для пользователей структуры Golang предоставляют логическое представление строки данных в ClickHouse. Чтобы упростить это, нативный интерфейс предоставляет несколько удобных функций.
Выбор с сериализацией
Метод Select позволяет массиву ответных строк быть замаршалированным в срез структур одним вызовом.
Сканирование структур
ScanStruct
позволяет замаршалировать одну строку из запроса в структуру.
Преобразования типов
Клиент стремится быть как можно более гибким в отношении принятия переменных типов как для вставки, так и для сериализации ответов. В большинстве случаев существует эквивалентный тип Golang для типа колонки ClickHouse, например, UInt64 соответствует uint64. Эти логические отображения всегда должны поддерживаться. Пользователи могут захотеть использовать переменные типы, которые могут быть вставлены в колонки или использованы для получения ответа, если преобразование либо переменной, либо полученных данных происходит в первую очередь. Клиент нацелен на поддержку этих преобразований прозрачным образом, чтобы пользователям не нужно было точно конвертировать свои данные перед вставкой и предоставлять гибкую сериализацию во время запроса. Это прозрачное преобразование не допускает потерь точности. Например, uint32 не может быть использован для получения данных из колонки UInt64. Напротив, строка может быть вставлена в поле datetime64, при условии, что она соответствует требованиям формата.
В настоящее время поддерживаемые преобразования типов для примитивных типов зафиксированы здесь.
Эта работа продолжается и может быть разделена на вставку (Append
/AppendRow
) и время чтения (через Scan
). Если вам нужна поддержка для определенного преобразования, пожалуйста, создайте проблему.
Сложные типы
Типы Date/DateTime
Клиент ClickHouse на Go поддерживает типы дат Date
, Date32
, DateTime
и DateTime64
. Даты могут быть вставлены как строка в формате 2006-01-02
или с использованием нативного Go time.Time{}
или sql.NullTime
. Дата и время также поддерживают последние типы, но требуют, чтобы строки передавались в формате 2006-01-02 15:04:05
с необязательным смещением по времени, например, 2006-01-02 15:04:05 +08:00
. time.Time{}
и sql.NullTime
поддерживаются как во время чтения, так и любая реализация интерфейса sql.Scanner
.
Обработка информации о часовых поясах зависит от типа ClickHouse и от того, вставляется ли значение или читается:
- DateTime/DateTime64
- На этапе вставки значение передается в ClickHouse в формате UNIX timestamp. Если часовой пояс не указан, клиент будет считать локальный часовой пояс клиента.
time.Time{}
илиsql.NullTime
будут преобразованы в эпоху соответственно. - На этапе выбора часовой пояс колонки будет использоваться, если он установлен, при возврате значения
time.Time
. Если нет, будет использован часовой пояс сервера.
- На этапе вставки значение передается в ClickHouse в формате UNIX timestamp. Если часовой пояс не указан, клиент будет считать локальный часовой пояс клиента.
- Date/Date32
- На этапе вставки часовой пояс любой даты рассматривается при преобразовании даты в unix timestamp, т.е. он будет сдвинут по времени перед хранением как дата, так как типы Date в ClickHouse не имеют локали. Если это не указано в строковом значении, будет использован локальный часовой пояс.
- На этапе выбора даты сканируются в
time.Time{}
илиsql.NullTime{}
экземпляры и возвращаются без информации о часовом поясе.
Массив
Массивы должны быть вставлены как срезы. Правила типизации для элементов согласованы с правилами для примитивного типа, т.е. где это возможно, элементы будут преобразованы.
Указатель на срез должен быть предоставлен во время сканирования.
Карта
Карты должны быть вставлены как карты Golang с ключами и значениями, соответствующими правилам типизации, определенным ранее.
Кортежи
Кортежи представляют собой группу колонок произвольной длины. Колонки могут быть либо явно названы, либо только указаны типы, например:
Из этих подходов именованные кортежи предлагают большую гибкость. Хотя безымянные кортежи должны быть вставлены и прочитаны с использованием срезов, именованные кортежи также совместимы с картами.
Примечание: поддерживаются типизированные срезы и карты, при условии, что все подстолбцы в именованном кортеже одного и того же типа.
Вложенные
Вложенное поле эквивалентно массиву именованных кортежей. Использование зависит от того, установил ли пользователь flatten_nested в 1 или 0.
Установив flatten_nested в 0, вложенные колонки остаются в виде одного массива кортежей. Это позволяет пользователям использовать срезы карт для вставки и выборки и произвольные уровни вложенности. Ключ карты должен равняться имени колонки, как показано в приведенном ниже примере.
Примечание: поскольку карты представляют собой кортеж, они должны быть типа map[string]interface{}
. Значения в настоящее время не имеют строгой типизации.
Полный пример - flatten_tested=0
Если используется значение по умолчанию 1 для flatten_nested
, вложенные колонки уплощаются в отдельные массивы. Это требует использования вложенных срезов для вставки и получения. Хотя произвольные уровни вложенности могут работать, это не поддерживается официально.
Полный пример - flatten_nested=1
Примечание: Вложенные колонки должны иметь одинаковые размеры. Например, в приведенном выше примере Col_2_2
и Col_2_1
должны содержать одинаковое количество элементов.
Из-за более простого интерфейса и официальной поддержки вложенности мы рекомендуем использовать flatten_nested=0
.
Географические типы
Клиент поддерживает географические типы Point, Ring, Polygon и Multi Polygon. Эти поля представлены в Golang с использованием пакета github.com/paulmach/orb.
UUID
Тип UUID поддерживается пакетом github.com/google/uuid. Пользователи также могут отправлять и сериализовать UUID как строку или любой тип, который реализует sql.Scanner
или Stringify
.
Десятичный
Тип Decimal поддерживается пакетом github.com/shopspring/decimal.
Nullable
Значение nil в Go представляет собой NULL ClickHouse. Это можно использовать, если поле объявлено как Nullable. На этапе вставки можно передать nil как для обычной, так и для обернутой версии колонки. Для первой будет сохранено значение по умолчанию для типа, например, пустая строка для строки. Для версии Nullable в ClickHouse будет сохранено значение NULL.
На этапе сканирования пользователь должен передать указатель на тип, который поддерживает nil, например, *string, чтобы обозначить значение nil для поля Nullable. В приведенном ниже примере col1, который является Nullable(String), получает **строку. Это позволяет представить nil.
Клиент также поддерживает типы sql.Null*
, например sql.NullInt64
. Эти типы совместимы с их эквивалентными типами ClickHouse.
Большие числа - Int128, Int256, UInt128, UInt256
Числовые типы, превышающие 64 бита, представлены с использованием нативного пакета Go big.
Сжатие
Поддержка методов сжатия зависит от используемого протокола. Для нативного протокола клиент поддерживает сжатие LZ4
и ZSTD
. Это выполняется только на уровне блоков. Сжатие может быть включено, добавив конфигурацию Compression
с соединением.
Дополнительные техники сжатия доступны, если использовать стандартный интерфейс через HTTP. См. API базы данных/sql - Сжатие для получения дальнейших деталей.
Привязка параметров
Клиент поддерживает привязку параметров для методов Exec
, Query
и QueryRow
. Как показано в приведенном ниже примере, это поддерживается с использованием именованных, пронумерованных и позиционных параметров. Мы приводим примеры этих параметров ниже.
Особые случаи
По умолчанию срезы будут развернуты в запятую-разделенный список значений, если они переданы как параметр в запрос. Если пользователям требуется набор значений, который будет внедрен с оборачиванием [ ]
, следует использовать ArraySet
.
Если требуются группы/кортежи, с оборачиванием ( )
, например, для использования с операторами IN, пользователи могут использовать GroupSet
. Это особенно полезно для случаев, когда требуется несколько групп, как показано в приведенном ниже примере.
Наконец, поля DateTime64 требуют точности, чтобы гарантировать, что параметры отрисовываются соответствующим образом. Уровень точности для поля неизвестен клиенту, поэтому пользователь должен предоставить его. Чтобы облегчить это, мы предоставляем параметр DateNamed
.
Использование контекста
Контексты Go предоставляют способ передавать сроки, сигналы отмены и другие значения, специфичные для запроса, через границы API. Все методы соединения принимают контекст в качестве первого параметра. Хотя предыдущие примеры использовали context.Background(), пользователи могут использовать эту возможность для передачи настроек и сроков и для отмены запросов.
Передача контекста, созданного с помощью withDeadline
, позволяет устанавливать временные ограничения на выполнение запросов. Обратите внимание, что это абсолютное время, и срок истечения просто освободит соединение и отправит сигнал отмены в ClickHouse. В качестве альтернативы можно использовать WithCancel
, чтобы явно отменить запрос.
Помощники clickhouse.WithQueryID
и clickhouse.WithQuotaKey
позволяют указывать идентификатор запроса и ключ квоты. Идентификаторы запросов могут быть полезны для отслеживания запросов в журналах и для целей отмены. Ключ квоты можно использовать для наложения ограничений на использование ClickHouse на основе уникального значения ключа - см. Управление квотами для получения дополнительных деталей.
Пользователи также могут использовать контекст, чтобы убедиться, что настройка применяется только для конкретного запроса, а не для всего соединения, как показано в Настройках соединения.
Наконец, пользователи могут контролировать размер буфера блока через clickhouse.WithBlockSize
. Это переопределяет настройку уровня соединения BlockBufferSize
и управляет максимальным количеством блоков, которые декодируются и хранятся в памяти в любой момент времени. Более крупные значения могут означать больше параллелизации за счет памяти.
Примеры выше приведены ниже.
Информация о прогрессе/профиле/журнале
Информация о прогрессе, профиле и журнале может быть запрошена в запросах. Информация о прогрессе будет сообщать статистику по количеству строк и байтам, которые были прочитаны и обработаны в ClickHouse. Напротив, информация о профиле предоставляет сводку данных, возвращенных клиенту, включая общий объем байтов (в несжатом виде), строки и блоки. Наконец, информация журнала предоставляет статистику по потокам, например, использование памяти и скорость передачи данных.
Получение этой информации требует от пользователя использования Context, в который пользователь может передать функции обратного вызова.
Динамическое сканирование
Пользователям может потребоваться читать таблицы, для которых они не знают схему или тип возвращаемых полей. Это часто встречается в случаях, когда выполняется разовая аналитика данных или разрабатываются общие инструменты. Для достижения этого информация о типах колонок доступна в ответах на запросы. Это можно использовать с отражением Go для создания экземпляров переменных корректного типа во время выполнения, которые могут быть переданы в Scan
.
Внешние таблицы
Внешние таблицы позволяют клиенту отправлять данные в ClickHouse с помощью запроса SELECT. Эти данные помещаются во временную таблицу и могут использоваться в самом запросе для оценки.
Чтобы отправить внешние данные клиенту с помощью запроса, пользователь должен создать внешнюю таблицу посредством ext.NewTable
, прежде чем передать это через контекст.
Open Telemetry
ClickHouse позволяет передавать контекст трассировки как часть родного протокола. Клиент позволяет создать Span с помощью функции clickhouse.withSpan
и передать его через контекст для достижения этой цели.
Полные сведения о возможности трассировки можно найти в разделе Поддержка OpenTelemetry.
Database/SQL API
database/sql
или "стандартный" API позволяет пользователям использовать клиент в сценариях, где код приложения должен быть независимо от используемых баз данных, соблюдая стандартный интерфейс. Это имеет свои недостатки - дополнительные уровни абстракции и косвенности и примитивы, которые не обязательно соответствуют ClickHouse. Эти затраты, однако, как правило, приемлемы в сценариях, где инструментам необходимо подключаться к нескольким базам данных.
Кроме того, этот клиент поддерживает использование HTTP в качестве транспортного слоя - данные все равно будут кодироваться в формате, специфичном для ClickHouse, для оптимальной производительности.
Следующее намерено отразить структуру документации для API ClickHouse.
Полные примеры кода для стандартного API можно найти здесь.
Подключение
Подключение может быть выполнено либо через строку DSN формата clickhouse://<host>:<port>?<query_option>=<value>
и метод Open
, либо через метод clickhouse.OpenDB
. Последний не является частью спецификации database/sql
, но возвращает экземпляр sql.DB
. Этот метод предоставляет функциональность, такую как профилирование, для которой нет очевидных средств извлечения через спецификацию database/sql
.
Для всех последующих примеров, если не указано иное, предполагается использование переменной ClickHouse conn
, которая была создана и доступна.
Настройки подключения
Следующие параметры могут быть переданы в строке DSN:
hosts
- список отдельных адресов, разделенных запятыми, для балансировки нагрузки и отказоустойчивости - см. Подключение к нескольким узлам.username/password
- учетные данные аутентификации - см. Аутентификацияdatabase
- выберите текущую базу данных по умолчаниюdial_timeout
- строка продолжительности, представляющая собой возможно подписанную последовательность десятичных чисел, каждое с необязательной дробной частью и единичным суффиксом, таким как300ms
,1s
. Допустимые временные единицы:ms
,s
,m
.connection_open_strategy
-random/in_order
(по умолчаниюrandom
) - см. Подключение к нескольким узламround_robin
- выбирайте сервер по принципу кругового выбора из набораin_order
- выбирайте первый активный сервер в указанном порядке
debug
- включить отладочный вывод (булевое значение)compress
- укажите алгоритм сжатия -none
(по умолчанию),zstd
,lz4
,gzip
,deflate
,br
. Если значение равноtrue
, будет использоватьсяlz4
. Толькоlz4
иzstd
поддерживаются для родной связи.compress_level
- уровень сжатия (по умолчанию0
). См. сжатие. Это специфично для алгоритма:gzip
--2
(Лучшая скорость) до9
(Лучшая степень сжатия)deflate
--2
(Лучшая скорость) до9
(Лучшая степень сжатия)br
-0
(Лучшая скорость) до11
(Лучшая степень сжатия)zstd
,lz4
- игнорируется
secure
- установить защищенное SSL-подключение (по умолчаниюfalse
)skip_verify
- пропустить проверку сертификата (по умолчаниюfalse
)block_buffer_size
- позволяет пользователям контролировать размер буфера блока. См.BlockBufferSize
. (по умолчанию2
)
Пул подключений
Пользователи могут влиять на использование предоставленного списка адресов узлов, как описано в Подключение к нескольким узлам. Управление подключениями и пул подключений передано sql.DB
по замыслу.
Подключение через HTTP
По умолчанию подключения устанавливаются через родной протокол. Для пользователей, которым необходим HTTP, это можно включить, либо изменив строку DSN, чтобы включить протокол HTTP, либо указав Протокол в параметрах соединения.
Подключение к нескольким узлам
При использовании OpenDB
подключитесь к нескольким узлам, используя тот же подход с параметрами, что и для API ClickHouse - опционально указав параметр ConnOpenStrategy
.
Для подключений на основе DSN строка принимает несколько узлов и параметр connection_open_strategy
, для которого можно установить значение round_robin
или in_order
.
Использование TLS
Если вы используете строку подключения DSN, SSL можно включить через параметр "secure=true". Метод OpenDB
использует тот же подход, что и родное API для TLS, полагаясь на спецификацию неоднородной структуры TLS. В то время как строка подключения DSN поддерживает параметр skip_verify для пропуска проверки SSL, метод OpenDB
необходим для более сложных конфигураций TLS - так как он позволяет передавать конфигурацию.
Аутентификация
Если вы используете OpenDB
, информацию об аутентификации можно передать через обычные параметры. Для подключений на основе DSN имя пользователя и пароль можно передать в строке подключения - либо в качестве параметров, либо в качестве учетных данных, закодированных в адресе.
Выполнение
После получения подключения пользователи могут выполнить sql
операторы через метод Exec.
Этот метод не поддерживает получение контекста - по умолчанию он выполняется с фоновым контекстом. Пользователи могут использовать ExecContext
, если это необходимо - см. Использование контекста.
Пакетная вставка
Семантику пакетов можно достичь, создав sql.Tx
через метод Being
. Из этого можно получить пакет, используя метод Prepare
с инструкцией INSERT
. Это возвращает sql.Stmt
, к которому можно добавлять строки с помощью метода Exec
. Пакет будет накапливаться в памяти до выполнения Commit
на исходном sql.Tx
.
Запрос строки/строк
Запрос одной строки можно выполнить с помощью метода QueryRow
. Это возвращает *sql.Row
, на котором можно вызвать Scan
с указателями на переменные, в которые колонки должны быть преобразованы. Вариант QueryRowContext
позволяет передавать контекст, отличный от фона - см. Использование контекста.
Итерация по нескольким строкам требует метода Query
. Это возвращает структуру *sql.Rows
, на которой можно вызывать Next
для итерации по строкам. Эквивалент QueryContext
позволяет передавать контекст.
Асинхронная вставка
Асинхронные вставки могут быть выполнены путем выполнения вставки с помощью метода ExecContext
. Этот метод должен принимать контекст с включенным асинхронным режимом, как показано ниже. Это позволяет пользователю указать, должен ли клиент ждать завершения вставки сервером или ответить, как только данные будут получены. Это фактически контролирует параметр wait_for_async_insert.
Колонковая вставка
Не поддерживается с использованием стандартного интерфейса.
Использование структур
Не поддерживается с использованием стандартного интерфейса.
Преобразования типов
Стандартный интерфейс database/sql
должен поддерживать те же типы, что и API ClickHouse. Есть несколько исключений, в основном для сложных типов, которые мы документируем ниже. Подобно API ClickHouse, клиент стремится быть максимально гибким в отношении принятия переменных типов как для вставки, так и для преобразования ответов. См. Преобразования типов для получения дополнительных сведений.
Сложные типы
Если не указано иное, обработка сложных типов должна быть такой же, как в API ClickHouse. Отличия являются результатом внутренностей database/sql
.
Карты
В отличие от API ClickHouse, стандартный API требует, чтобы карты были строго типизированы по типу сканирования. Например, пользователи не могут передавать map[string]interface{}
для поля Map(String,String)
и должны использовать map[string]string
вместо этого. Переменная interface{}
всегда будет совместима и может использоваться для более сложных структур. Структуры не поддерживаются во время чтения.
Поведение вставки такое же, как и в API ClickHouse.
Сжатие
Стандартный API поддерживает те же алгоритмы сжатия, что и родное API ClickHouse, т.е. сжатие lz4
и zstd
на уровне блока. Кроме того, для HTTP-соединений поддерживаются сжатие gzip, deflate и br. Если какое-либо из этих параметров включено, сжатие выполняется на блоках во время вставки и для ответов на запросы. Другие запросы, например, повторные запросы или запросы, останутся несжатыми. Это согласуется с параметрами lz4
и zstd
.
Если использовать метод OpenDB
для установления соединения, можно передать конфигурацию сжатия. Это включает возможность указать уровень сжатия (см. ниже). Если подключаться через sql.Open
с использованием DSN, используйте параметр compress
. Это может быть либо конкретный алгоритм сжатия, т.е. gzip
, deflate
, br
, zstd
или lz4
, либо булевый флаг. Если он установлен в true, будет использоваться lz4
. По умолчанию значение none
, т.е. сжатие отключено.
Уровень применяемого сжатия можно контролировать через DSN-параметр compress_level или поле Level опции Compression. По умолчанию это значение равно 0, но оно специфично для алгоритма:
gzip
--2
(Лучшая скорость) до9
(Лучшая степень сжатия)deflate
--2
(Лучшая скорость) до9
(Лучшая степень сжатия)br
-0
(Лучшая скорость) до11
(Лучшая степень сжатия)zstd
,lz4
- игнорируются
Привязка параметров
Стандартный API поддерживает такие же возможности привязки параметров, как и в API ClickHouse, позволяя передавать параметры в методы Exec
, Query
и QueryRow
(и их эквиваленты Context). Поддерживаются позиционные, именованные и нумерованные параметры.
Обратите внимание, что особые случаи по-прежнему применяются.
Использование контекста
Стандартный API поддерживает такую же возможность передачи сроков, сигналов отмены и других значений, относящихся к запросу, через контекст, как и API ClickHouse. В отличие от API ClickHouse, это достигается с помощью вариантов методов Context
, т.е. методы, такие как Exec
, которые по умолчанию используют фоновой контекст, имеют вариант ExecContext
, которому можно передать контекст в качестве первого параметра. Это позволяет передавать контекст на любом этапе потока приложения. Например, пользователи могут передавать контекст при установлении соединения через ConnContext
или при запрашивании строки через QueryRowContext
. Примеры всех доступных методов показаны ниже.
Для получения дополнительной информации о использовании контекста для передачи сроков, сигналов отмены, идентификаторов запросов, ключей квот и параметров соединения см. Использование контекста для API ClickHouse.
Динамическое сканирование
Аналогично ClickHouse API, информация о типах колонок доступна для того, чтобы пользователи могли создавать экземпляры переменных с правильными типами во время выполнения, которые могут быть переданы в Scan
. Это позволяет считывать колонки, тип которых неизвестен.
Внешние таблицы
Внешние таблицы позволяют клиенту отправлять данные в ClickHouse с помощью запроса SELECT
. Эти данные помещаются во временную таблицу и могут быть использованы в самом запросе для оценки.
Чтобы отправить внешние данные клиенту с запросом, пользователь должен сначала создать внешнюю таблицу с помощью ext.NewTable
, а затем передать это через контекст.
Open Telemetry
ClickHouse позволяет передавать контекст трассировки как часть нативного протокола. Клиент позволяет создать Span с помощью функции clickhouse.withSpan
и передать его через контекст для достижения этого. Это не поддерживается при использовании HTTP в качестве транспорта.
Советы по производительности
- Используйте ClickHouse API, где это возможно, особенно для примитивных типов. Это позволяет избежать значительной рефлексии и косвенности.
- Если вы читаете большие наборы данных, подумайте о том, чтобы изменить
BlockBufferSize
. Это увеличит использование памяти, но позволит декодировать больше блоков параллельно во время итерации по строкам. Значение по умолчанию 2 является консервативным и минимизирует нагрузку на память. Более высокие значения будут означать больше блоков в памяти. Это требует тестирования, поскольку разные запросы могут производить разные размеры блоков. Поэтому его можно установить на уровне запроса через контекст. - Будьте конкретны с вашими типами при вставке данных. Хотя клиент стремится быть гибким, например, позволяя строкам парситься для UUID или IP, это требует проверки данных и влечёт за собой дополнительные затраты в момент вставки.
- Используйте колоночные вставки, где это возможно. Снова, они должны быть строго типизированы, избегая необходимости клиенту конвертировать ваши значения.
- Следуйте рекомендациям ClickHouse для оптимальной производительности вставок.