ClickHouse Go
Простой пример
Давайте начнем с простого примера. Этот код подключится к ClickHouse и выполнит выборку из системной базы данных. Чтобы начать, вам понадобятся ваши данные для подключения.
Данные для подключения
To connect to ClickHouse with native TCP you need this information:
-
The HOST and PORT: typically, the port is 9440 when using TLS, or 9000 when not using TLS.
-
The DATABASE NAME: out of the box there is a database named
default
, use the name of the database that you want to connect to. -
The USERNAME and PASSWORD: out of the box the username is
default
. Use the username appropriate for your use case.
The details for your ClickHouse Cloud service are available in the ClickHouse Cloud console. Select the service that you will connect to and click Connect:

Choose Native, and the details are available in an example clickhouse-client
command.

If you are using self-managed ClickHouse, the connection details are set by your ClickHouse administrator.
Инициализация модуля
Скопируйте пример кода
Скопируйте этот код в директорию clickhouse-golang-example
как main.go
.
Запустите go mod tidy
Установите свои данные для подключения
Ранее вы узнали свои данные для подключения. Установите их в main.go
в функции connect()
:
Запустите пример
Узнать больше
Остальная часть документации в этой категории охватывает детали клиента ClickHouse для Go.
Клиент ClickHouse Go
ClickHouse поддерживает два официальных клиента Go. Эти клиенты дополняют друг друга и намеренно поддерживают разные сценарии использования.
- clickhouse-go - клиент на высоком уровне, который поддерживает как стандартный интерфейс базы данных/sql, так и нативный интерфейс.
- ch-go - клиент низкого уровня. Только нативный интерфейс.
clickhouse-go предоставляет интерфейс высокого уровня, позволяя пользователям выполнять запросы и вставлять данные, используя ориентированную на строки семантику и пакетирование, которые допускают гибкость в отношении типов данных - значения будут преобразованы при условии, что возможные потери точности не произойдут. ch-go, в свою очередь, предлагает оптимизированный ориентированный на столбцы интерфейс, который обеспечивает быструю потоковую передачу блоков данных с низкими накладными расходами на ЦП и память за счет строгости типов и более сложного использования.
Начиная с версии 2.3, clickhouse-go использует ch-go для низкоуровневых функций, таких как кодирование, декодирование и сжатие. Обратите внимание, что clickhouse-go также поддерживает стандартный интерфейс 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 протокол | Поддержка массовой записи | Преобразование структур | Сжатие | Заполнитель запросов | |
---|---|---|---|---|---|---|---|
API ClickHouse | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | |
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
.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
) будут использовать пакет tls Go для установления безопасного соединения. Клиент знает, что необходимо использовать TLS, если структура Options содержит ненулевой указатель на tls.Config
.
Этот минимальный TLS.Config
обычно достаточен для подключения к защищенному нативному порту (обычно 9440) на сервере ClickHouse. Если на сервере ClickHouse нет действительного сертификата (истек срок действия, неправильное имя хоста, не подписан признанным корневым удостоверяющим центром), InsecureSkipVerify
может быть true, но это настоятельно не рекомендуется.
Если необходимы дополнительные параметры TLS, код приложения должен установить необходимые поля в структуре tls.Config
. Это может включать конкретные наборы шифров, принудительное использование определенной версии TLS (например, 1.2 или 1.3), добавление внутренней цепочки сертификатов CA, добавление клиентского сертификата (и закрытого ключа), если это требуется сервером ClickHouse, и большинство других опций, которые применяются к более специализированной конфигурации безопасности.
Аутентификация
Укажите структуру Auth в данных подключения, чтобы задать имя пользователя и пароль.
Подключение к нескольким узлам
Несколько адресов можно указать через структуру Addr
.
Две стратегии подключения доступны:
ConnOpenInOrder
(по умолчанию) - адреса используются по порядку. Поздние адреса используются только в случае неудачи при попытке подключения по ранним адресам из списка. Это фактически стратегия резервирования.ConnOpenRoundRobin
- Нагрузка балансируется по адресам с использованием стратегии кругового распределения.
Это можно управлять с помощью опции ConnOpenStrategy
Выполнение
Произвольные операторы могут быть выполнены с помощью метода Exec
. Это полезно для DDL и простых операторов. Его не следует использовать для крупных вставок или итераций запросов.
Обратите внимание на возможность передать контекст в запрос. Это может быть использовано для передачи определенных настроек на уровне запроса - см. Использование контекста.
Пакетная вставка
Для вставки большого количества строк клиент предоставляет семантику пакетной вставки. Это требует подготовки пакета, к которому могут быть добавлены строки. Этот пакет в конечном итоге отправляется через метод Send()
. Пакеты будут находиться в памяти до момента выполнения Send.
Рекомендации для ClickHouse применимы здесь. Пакеты не должны использоваться между горутинами - создавайте отдельный пакет для каждой рутины.
Из приведенного выше примера обратите внимание на необходимость, чтобы типы переменных соответствовали типу столбца при добавлении строк. Хотя отображение обычно очевидно, этот интерфейс старается быть гибким, и типы будут преобразованы при условии, что потерь точности не будет. Например, следующее демонстрирует вставку строки в datetime64.
Для полного свода поддерживаемых типов go для каждого типа столбца смотрите Преобразования типов.
Запрос строк
Пользователи могут либо запрашивать одну строку с помощью метода QueryRow
, либо получать курсор для итерации по набору результатов через Query
. В то время как первый принимает назначение для данных, чтобы их сериализовать, последний требует вызова Scan
для каждой строки.
Обратите внимание, что в обоих случаях нам необходимо передать указатель на переменные, в которые мы хотим сериализовать соответствующие значения столбцов. Эти переменные должны передаваться в указанном порядке в операторе SELECT
- по умолчанию будет использоваться порядок объявления столбцов в случае SELECT *
, как показано выше.
Аналогично вставке, метод Scan требует, чтобы целевые переменные имели соответствующий тип. Это снова пытается быть гибким, с преобразованием типов, где это возможно, при условии, что потерь точности не может произойти, например, в приведенном выше примере столбец UUID считывается в строковую переменную. Для полного списка поддерживаемых типов go для каждого типа столбца смотрите Преобразования типов.
Наконец, обратите внимание на возможность передать Context
в методы Query
и QueryRow
. Это можно использовать для настройки уровня запроса - см. Использование контекста для получения дополнительной информации.
Асинхронная вставка
Асинхронные вставки поддерживаются с помощью метода Async. Это позволяет пользователю указать, должен ли клиент ожидать завершения вставки сервером или ответить, как только данные будут получены. Это фактически контролирует параметр wait_for_async_insert.
Вставка в столбцовом формате
Вставки могут производиться в столбцовом формате. Это может обеспечить преимущества по производительности, если данные уже ориентированы в такой структуре, избегая необходимости преобразовывать в строки.
Использование структур
Для пользователей структуры Golang предоставляют логическое представление строки данных в ClickHouse. Для этого нативный интерфейс предоставляет несколько удобных функций.
Выбор с сериализацией
Метод Select позволяет набору строк ответа быть сериализованным в срез структур с единой инвокацией.
Scan Struct
ScanStruct
позволяет сериализовать одну строку из запроса в структуру.
Append Struct
AppendStruct
позволяет добавить структуру к существующему батчу и интерпретировать ее как полную строку. Это требует, чтобы колонки структуры соответствовали по имени и типу таблице. Хотя все колонки должны иметь эквивалентное поле структуры, некоторые поля структуры могут не иметь эквивалентного представления в колонке. Эти поля просто будут проигнорированы.
Преобразования типов
Клиент стремится быть как можно более гибким в отношении принятия переменных типов как для вставки, так и для сериализации ответов. В большинстве случаев для типа колонки ClickHouse существует эквивалентный тип Golang, например, 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. Если часовой пояс не указан, клиент будет предполагать локальный часовой пояс клиента.
time.Time{}
илиsql.NullTime
будут преобразованы в эпоху соответственно. - Во время выборки будет использоваться часовой пояс колонки, если он установлен, при возврате значения
time.Time
. Если нет, будет использоваться часовой пояс сервера.
- Во время вставки значение отправляется в ClickHouse в формате временной метки UNIX. Если часовой пояс не указан, клиент будет предполагать локальный часовой пояс клиента.
- Date/Date32
- Во время вставки часовой пояс любой даты учитывается при преобразовании даты в временную метку unix, т.е. он будет смещен по часовому поясу перед хранением как дата, поскольку типы Date не имеют локали в ClickHouse. Если это не указано в строковом значении, будет использоваться локальный часовой пояс.
- Во время выборки, даты будут считаны в
time.Time{}
или возвращены экземплярыsql.NullTime{}
без информации о часовом поясе.
Массив
Массивы должны быть вставлены как срезы. Правила типизации для элементов согласуются с таковыми для примитивных типов, т.е. при возможности элементы будут преобразованы.
Указатель на срез должен быть предоставлен во время сериализации.
Map
Maps должны быть вставлены как карты 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
Тип Decimal поддерживается пакетом github.com/shopspring/decimal.
Nullable
Значение Nil в Go представляет ClickHouse NULL. Это может быть использовано, если поле объявлено Nullable. Во время вставки Nil может быть передан как для обычной, так и для Nullable версии колонки. Для первой будет сохранено значение по умолчанию для типа, например, пустая строка для строки. Для версии nullable будет сохранено значение NULL в ClickHouse.
Во время сериализации пользователь должен передать указатель на тип, который поддерживает nil, например, *string, чтобы представить значение nil для поля Nullable. В следующем примере col1, который является Nullable(String), получает **string. Это позволяет представить nil.
Клиент дополнительно поддерживает типы sql.Null*
, например, sql.NullInt64
. Эти типы совместимы с их эквивалентными типами ClickHouse.
Большие целые числа - Int128, Int256, UInt128, UInt256
Числовые типы больше 64 бит представляются с использованием родного пакета Go big.
Сжатие
Поддержка методов сжатия зависит от используемого протокола. Для родного протокола клиент поддерживает сжатие LZ4
и ZSTD
. Это происходит на уровне блоков. Сжатие может быть включено путем добавления конфигурации Compression
с соединением.
Дополнительные методы сжатия доступны при использовании стандартного интерфейса через HTTP. См. API database/sql - Сжатие для получения дополнительной информации.
Привязка параметров
Клиент поддерживает привязку параметров для методов Exec
, Query
и QueryRow
. Как показано в примере ниже, это поддерживается с помощью именованных, пронумерованных и позиционных параметров. Мы приводим примеры этих ниже.
Специальные случаи
По умолчанию срезы будут развернуты в список значений, разделенных запятыми, если переданы как параметр запроса. Если пользователи требуют набора значений, обернутых в [ ]
, следует использовать ArraySet
.
Если требуются группы/кортежи с оберткой ( )
, например, для использования с операторами IN, пользователи могут воспользоваться GroupSet
. Это особенно полезно для случаев, когда требуется несколько групп, как показано в следующем примере.
Наконец, для полей DateTime64 требуется точность, чтобы гарантировать, что параметры отображаются должным образом. Уровень точности для поля неизвестен клиенту, однако пользователь должен его предоставить. Для облегчения этого мы предоставляем параметр DateNamed
.
Использование контекста
Контексты Go предоставляют возможность передачи дедлайнов, сигналов отмены и других значений, относящихся к запросу, через границы API. Все методы соединения принимают контекст в качестве своей первой переменной. Хотя в предыдущих примерах использовался context.Background()
, пользователи могут использовать эту возможность для передачи настроек и дедлайнов, а также для отмены запросов.
Передача контекста, созданного с помощью withDeadline
, позволяет установить ограничения по времени выполнения для запросов. Обратите внимание, что это абсолютное время, и истечение срока только освободит соединение и отправит сигнал отмены в ClickHouse. В качестве альтернативы можно использовать WithCancel
для явной отмены запроса.
Помощники clickhouse.WithQueryID
и clickhouse.WithQuotaKey
позволяют указать id запроса и ключ квоты. Идентификаторы запросов могут быть полезны для отслеживания запросов в журналах и для целей отмены. Ключ квоты может использоваться для наложения ограничений на использование ClickHouse на основе уникального значения ключа - см. Управление квотами для получения дополнительной информации.
Пользователи также могут использовать контекст, чтобы убедиться, что настройка применяется только для конкретного запроса, а не для всего соединения, как показано в Настройки соединения.
Наконец, пользователи могут контролировать размер буфера блока с помощью clickhouse.WithBlockSize
. Это переопределяет настройку уровня соединения BlockBufferSize
и контролирует максимальное количество блоков, которые декодируются и удерживаются в памяти в любое время. Более крупные значения могут означать большую параллелизацию за счет использования памяти.
Примеры выше показаны ниже.
Информация о прогрессе/профиле/журнале
Информация о прогрессе, профиле и журнале может запрашиваться по запросам. Информация о прогрессе будет сообщать статистику о количестве строк и байтов, которые были прочитаны и обработаны в ClickHouse. Напротив, информация о профиле предоставляет краткое резюме данных, возвращаемых клиенту, включая общие данные о байтах (не сжатых), строках и блоках. Наконец, информация журнала предоставляет статистику по потокам, например, использование памяти и скорость передачи данных.
Получение этой информации требует от пользователя использования Контекста, в который пользователь может передать функции обратного вызова.
Динамическое сканирование
Пользователям может потребоваться читать таблицы, для которых они не знают схему или тип полей, которые будут возвращены. Это распространено в случаях, когда выполняется спонтанный анализ данных или пишутся универсальные инструменты. Для достижения этого информация о типе колонки доступна в ответах запросов. Это можно использовать с помощью рефлексии Go для создания экземпляров переменных правильного типа во время выполнения, которые могут быть переданы в Scan.
Внешние таблицы
Внешние таблицы позволяют клиенту отправлять данные в ClickHouse с помощью запроса SELECT. Эти данные помещаются во временную таблицу и могут использоваться в самом запросе для оценки.
Чтобы отправить внешние данные клиенту с помощью запроса, пользователю необходимо построить внешнюю таблицу через ext.NewTable
, прежде чем передать её через контекст.
Open Telemetry
ClickHouse позволяет передавать контекст трассировки как часть родного протокола. Клиент позволяет создать Span с помощью функции clickhouse.withSpan
и передать его через Контекст для достижения этой цели.
Полные детали о том, как использовать трассировку, можно найти в разделе Поддержка OpenTelemetry.
Database/SQL API
database/sql
или "стандартный" API позволяет пользователям использовать клиент в сценариях, где код приложения должен быть независим от баз данных, использующихся, соблюдая стандартный интерфейс. Это связано с определенными затратами - дополнительными уровнями абстракций и примитивами, которые не обязательно совместимы с ClickHouse. Тем не менее, эти затраты обычно приемлемы в сценариях, когда инструменты должны подключаться к нескольким базам данных.
Кроме того, этот клиент поддерживает использование HTTP в качестве транспортного слоя - данные по-прежнему будут кодироваться в родном формате для оптимальной производительности.
Следующее стремится отразить структуру документации для 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
через метод Begin
. Из этого пакета можно получить с помощью метода 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 поддерживает те же алгоритмы сжатия, что и родной ClickHouse API, то есть сжатие lz4
и zstd
на уровне блока. Кроме того, поддерживаются сжатия gzip, deflate и br для HTTP-соединений. Если любой из этих методов включен, сжатие выполняется на блоках во время вставки и для ответов на запросы. Другие запросы, например, пинги или запросы, останутся несжатыми. Это согласуется с параметрами 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 поддерживает те же возможности привязки параметров, что и ClickHouse API, позволяя передавать параметры в методы Exec
, Query
и QueryRow
(а также их эквиваленты Context). Поддерживаются позиционные, именованные и нумерованные параметры.
Обратите внимание, что особые случаи все еще применимы.
Использование контекста
Стандартный API поддерживает возможность передачи сроков, сигналов отмены и других значений, связанных с запросами, через контекст так же, как и ClickHouse API. В отличие от ClickHouse API, это достигается с помощью вариантов методов Context
, то есть методов, таких как Exec
, которые по умолчанию используют фоновый контекст, имеют вариант ExecContext
, в который можно передать контекст в качестве первого параметра. Это позволяет передавать контекст на любом этапе потока приложения. Например, пользователи могут передавать контекст при установлении соединения через ConnContext
или при запросе строки через QueryRowContext
. Примеры всех доступных методов показаны ниже.
Для получения более подробной информации о том, как использовать контекст для передачи сроков, сигналов отмены, идентификаторов запросов, ключей квот и настроек соединения, смотрите раздел Использование контекста в ClickHouse API.
Сессии
Хотя родные соединения по своей сути имеют сессию, соединения по HTTP требуют от пользователя создания идентификатора сессии для передачи в контексте в качестве настройки. Это позволяет использовать возможности, например, временные таблицы, которые связаны с сессией.
Динамическое сканирование
Аналогично ClickHouse API, информация о типах столбцов доступна для того, чтобы пользователи могли создавать экземпляры переменных правильного типа во время выполнения, которые могут быть переданы в Scan
. Это позволяет считывать столбцы, где тип не известен.
Внешние таблицы
Внешние таблицы позволяют клиенту отправлять данные в ClickHouse с помощью запроса SELECT
. Эти данные помещаются во временную таблицу и могут использоваться в самом запросе для оценки.
Чтобы отправить внешние данные клиенту с помощью запроса, пользователь должен создать внешнюю таблицу через ext.NewTable
перед передачей ее через контекст.
Open Telemetry
ClickHouse позволяет передавать контекст трассировки в качестве части родного протокола. Клиент позволяет создать Span
с помощью функции clickhouse.withSpan
и передать его через контекст для достижения этого. Это не поддерживается, когда в качестве транспорта используется HTTP.
Советы по производительности
- Используйте ClickHouse API, где это возможно, особенно для примитивных типов. Это избегает значительного отражения и косвенности.
- Если вы читаете большие наборы данных, рассмотрите возможность изменения
BlockBufferSize
. Это увеличит объем используемой памяти, но позволит декодировать больше блоков параллельно во время итерации по строкам. Значение по умолчанию — 2, что консервативно и минимизирует накладные расходы по памяти. Более высокие значения приведут к большему количеству блоков в памяти. Это требует тестирования, так как разные запросы могут генерировать разные размеры блоков. Поэтому это можно установить на уровне запроса через контекст. - Будьте конкретными с вашими типами при вставке данных. Хотя клиент стремится быть гибким, например, позволяя строкам разбиваться на UUID или IP, это требует валидации данных и влечет за собой затраты во время вставки.
- Используйте вставки ориентированные на столбцы, где это возможно. Опять же, они должны быть строго типизированными, чтобы избежать необходимости клиенту конвертировать ваши значения.
- Следуйте рекомендациям ClickHouse для оптимальной производительности вставки.