はじめに
ClickHouseは分析用途に優れた列志向データベースですが、既存のMySQLと組み合わせて利用したい場面も少なくありません。
前回の記事「PeerDB + ClickHouse + MySQL でCDC検証をしてみた話」で触れたように、がっつりCDCでMySQLからClickHouseへデータ同期をする手法もあります。
それとは別に、ClickHouseにはMySQLにデータを残したまま、MySQLのデータを参照するための方法が複数用意されており、それぞれ特徴や適した用途が異なります。
他方で、ClickHouseには、MySQLクライアントからClickHouseへ接続するための機能も用意されています。そのため、用途に応じてさまざまな形でMySQLと連携することができます。
本記事では、以下の5つの方法について実際に動作を確認し、それぞれの使いどころを比較します。
-
テーブル関数
-
Dictionary
-
テーブルエンジン
-
データベースエンジン
-
インターフェイス
全体比較
まずは、それぞれの機能の違いを整理します。
|
機能 |
用途 |
データの所在 |
ClickHouseで高速化できるか |
|---|---|---|---|
|
テーブル関数 |
一時的なデータ参照 |
MySQL |
❌ 高速化できない |
|
Dictionary |
マスタデータの高速参照 |
MySQL→ClickHouseメモリにキャッシュ |
✅ 高速化できる |
|
テーブルエンジン |
継続的なテーブル利用 |
MySQL |
❌ 高速化できない |
|
データベースエンジン |
継続的なスキーマ利用 |
MySQL |
❌ 高速化できない |
|
インターフェイス |
MySQLクライアントからの接続 |
ClickHouse |
✅ ClickHouseがSQLを処理 |
前半の4つはClickHouseからMySQLのデータを利用するための機能であるのに対し、インターフェイスはMySQLクライアントからClickHouseへ接続するための機能という点が大きな違いです。
検証環境
|
項目 |
バージョン |
|---|---|
|
ClickHouse |
26.6.1.1193 |
|
MySQL Community Server |
8.4.9 |
環境構築
今回はDockerでMySQLとClickHouseを構築します。
ネットワーク
最初にDockerネットワークを作成し、その後に各コンテナを接続します。
|
1 |
docker network create db-net |
ClickHouse
|
1 2 3 4 5 6 |
docker run -d \ --name clickhouse \ --network db-net \ --ulimit nofile=262144:262144 \ -v ${PWD}/mysql.xml:/etc/clickhouse-server/config.d/mysql.xml \ clickhouse/clickhouse-server |
マウントしている設定ファイルの内容については後ほど説明します。
MySQL
|
1 2 3 4 5 |
docker run -d \ --name=mysql \ --network db-net \ -e MYSQL_ROOT_PASSWORD='(MySQL ROOT用パスワード)' \ container-registry.oracle.com/mysql/community-server:8.4 |
SakilaサンプルデータベースをMySQLにインポートします。
|
1 2 3 4 |
wget https://downloads.mysql.com/docs/sakila-db.tar.gz tar xf sakila-db.tar.gz docker exec -i mysql mysql -p -vv < sakila-db/sakila-schema.sql docker exec -i mysql mysql -p -vv < sakila-db/sakila-data.sql |
ClickHouseからの接続用ユーザを作成します。
|
1 2 |
CREATE USER 'clickhouse'@'%' IDENTIFIED BY '(ClickHouse接続用パスワード)'; GRANT SELECT ON sakila.* TO 'clickhouse'@'%'; |
テーブル関数
公式ドキュメント:mysql | ClickHouse Docs
テーブル関数は、SQL実行時に直接MySQLへ接続してデータを取得する方法です。
テーブルを作成する必要がなく、一時的な参照やデータ確認に適しています。
一方で、クエリ実行のたびにMySQLへアクセスするため、Dictionaryのようなキャッシュは行われません。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
SELECT ci.city_id, ci.city, co.country FROM mysql('mysql:3306', 'sakila', 'city', 'clickhouse', '(ClickHouse接続用パスワード)') AS ci INNER JOIN mysql('mysql:3306', 'sakila', 'country', 'clickhouse', '(ClickHouse接続用パスワード)') AS co ON ci.country_id = co.country_id ORDER BY ci.city_id ASC LIMIT 5 Query id: 31d3afac-ca65-45b9-be56-659ba514c5b6 ┌─city_id─┬─city─────────────────┬─country──────────────┐ 1. │ 1 │ A Coruña (La Coruña) │ Spain │ 2. │ 2 │ Abha │ Saudi Arabia │ 3. │ 3 │ Abu Dhabi │ United Arab Emirates │ 4. │ 4 │ Acuña │ Mexico │ 5. │ 5 │ Adana │ Turkey │ └─────────┴──────────────────────┴──────────────────────┘ 5 rows in set. Elapsed: 0.032 sec. |
名前付きコレクション
公式ドキュメント:名前付きコレクション | ClickHouse Docs
個々のSQLへ接続情報を直接記述する代わりに、名前付きコレクションを利用して接続設定を外部化し、より安全で再利用しやすい形に書き換えることができます。
名前付きコレクションの作成
|
1 2 3 4 5 |
CREATE NAMED COLLECTION mymysql AS host = 'mysql', port = 3306, user = 'clickhouse', password = '(ClickHouse接続用パスワード)' |
クエリを書き換えた場合
|
1 2 3 4 5 6 7 8 |
SELECT ci.city_id, ci.city, co.country FROM mysql(mymysql, database = 'sakila', `table` = 'city') AS ci INNER JOIN mysql(mymysql, database = 'sakila', `table` = 'country') AS co ON ci.country_id = co.country_id ORDER BY ci.city_id ASC LIMIT 5 |
Dictionary
公式ドキュメント:MySQL Dictionary ソース | ClickHouse Docs
Dictionaryは、外部データをキー検索用途に最適化した機能です。
一度読み込んだデータはキャッシュされるため、小さなマスタデータを高速に参照したい場合によく利用されます。
マスタのように更新頻度が低く、参照頻度が高いテーブルと相性が良い機能です。
|
1 2 3 4 5 6 7 8 9 10 |
CREATE DICTIONARY mysql_country_dict ( `country_id` UInt64, `country` String, `last_update` DateTime ) PRIMARY KEY country_id SOURCE(MYSQL(HOST 'mysql' PORT 3306 USER 'clickhouse' PASSWORD '(ClickHouse接続用パスワード)' DB 'sakila' TABLE 'country')) LIFETIME(MIN 0 MAX 300) LAYOUT(HASHED()) |
名前付きコレクションで書き換えた場合(8行目)
|
1 |
SOURCE(MYSQL(NAME mymysql DB 'sakila' TABLE 'country')) |
今回設定しているLIFETIMEはDictionaryの更新間隔を表しています。
今回の設定では最大300秒間キャッシュされるため、MySQL側で更新があっても即座には反映されません。
リアルタイム性が必要な場合はこの値を考慮して設定する必要があります。
辞書からキーを元に値を取り出すときは、dictGet()関数を使用します。
|
1 2 3 4 5 6 7 8 9 |
SELECT dictGet('mysql_country_dict', 'country', 1) Query id: 261ba31d-f529-47a6-8382-5eb4f6f05e37 ┌─dictGet('mys⋯ountry', 1)─┐ 1. │ Afghanistan │ └──────────────────────────┘ 1 row in set. Elapsed: 0.003 sec. |
JOIN風に行うとこのような形になります。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
SELECT c.city_id, c.city, dictGet('mysql_country_dict', 'country', c.country_id) AS country FROM mysql('mysql:3306', 'sakila', 'city', 'clickhouse', '(ClickHouse接続用パスワード)') AS c ORDER BY c.city_id ASC LIMIT 5 Query id: bb5a0920-d931-4ab9-8dcf-7c0861a0f54d ┌─city_id─┬─city─────────────────┬─country──────────────┐ 1. │ 1 │ A Coruña (La Coruña) │ Spain │ 2. │ 2 │ Abha │ Saudi Arabia │ 3. │ 3 │ Abu Dhabi │ United Arab Emirates │ 4. │ 4 │ Acuña │ Mexico │ 5. │ 5 │ Adana │ Turkey │ └─────────┴──────────────────────┴──────────────────────┘ 5 rows in set. Elapsed: 0.045 sec. |
テーブルエンジン
公式ドキュメント:MySQL と ClickHouse の統合 | ClickHouse Docs
テーブルエンジンは、MySQL上のテーブルをClickHouseのテーブルとして扱える機能です。
CREATE TABLEを一度実行しておけば、通常のClickHouseテーブルと同じ感覚で利用できます。
継続的に参照するテーブルではテーブル関数より扱いやすいケースが多くあります。
|
1 2 3 4 5 |
CREATE TABLE sakila_city ENGINE = MySQL('mysql:3306', 'sakila', 'city', 'clickhouse', '(ClickHouse接続用パスワード)'); CREATE TABLE sakila_country ENGINE = MySQL('mysql:3306', 'sakila', 'country', 'clickhouse', '(ClickHouse接続用パスワード)'); |
名前付きコレクションで書き換えた場合
|
1 2 3 4 5 |
CREATE TABLE sakila_city ENGINE = MySQL(mymysql, database = 'sakila', `table` = 'city') CREATE TABLE sakila_city ENGINE = MySQL(mymysql, database = 'sakila', `table` = 'country') |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
SELECT ci.city_id, ci.city, co.country FROM sakila_city AS ci INNER JOIN sakila_country AS co ON ci.country_id = co.country_id ORDER BY ci.city_id ASC LIMIT 5 Query id: 83a501df-3233-4f24-b13c-c6969e58f431 ┌─city_id─┬─city─────────────────┬─country──────────────┐ 1. │ 1 │ A Coruña (La Coruña) │ Spain │ 2. │ 2 │ Abha │ Saudi Arabia │ 3. │ 3 │ Abu Dhabi │ United Arab Emirates │ 4. │ 4 │ Acuña │ Mexico │ 5. │ 5 │ Adana │ Turkey │ └─────────┴──────────────────────┴──────────────────────┘ 5 rows in set. Elapsed: 0.011 sec. |
データベースエンジン
公式ドキュメント:MySQL | ClickHouse Docs
データベースエンジンは、MySQL上のスキーマをClickHouseのスキーマとして扱える機能です。
テーブルごとにエンジンを定義する必要がなく、多数のテーブルをまとめて扱いたい場合に便利です。
|
1 2 |
CREATE DATABASE sakila ENGINE = MySQL('mysql:3306', 'sakila', 'clickhouse', '(ClickHouse接続用パスワード)'); |
名前付きコレクションで書き換えた場合
|
1 2 |
CREATE DATABASE sakila ENGINE = MySQL(mymysql, database = 'sakila') |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
SELECT ci.city_id, ci.city, co.country FROM sakila.city AS ci INNER JOIN sakila.country AS co ON ci.country_id = co.country_id ORDER BY ci.city_id ASC LIMIT 5 Query id: a321f931-76b5-4e0c-af70-a21d55bbfcbc ┌─city_id─┬─city─────────────────┬─country──────────────┐ 1. │ 1 │ A Coruña (La Coruña) │ Spain │ 2. │ 2 │ Abha │ Saudi Arabia │ 3. │ 3 │ Abu Dhabi │ United Arab Emirates │ 4. │ 4 │ Acuña │ Mexico │ 5. │ 5 │ Adana │ Turkey │ └─────────┴──────────────────────┴──────────────────────┘ 5 rows in set. Elapsed: 0.019 sec. |
インターフェイス
公式ドキュメント:MySQL インターフェイス | ClickHouse Docs
ここまで紹介した4つの機能は、ClickHouseからMySQLのデータを参照する機能でした。
一方でClickHouseには、MySQLクライアントからClickHouseへ接続するための機能も用意されています。
これはMySQL Serverとして動作するわけではなく、MySQLクライアントが利用する通信プロトコルをClickHouseが実装している機能です。
そのため、普段利用している
-
MySQLクライアント
-
BIツール(Looker Studio、Tableau Online、QuickSight)
など、MySQLプロトコルに対応したツールからClickHouseへ接続できます。
イメージとしては以下のようになります。
|
1 2 3 4 5 |
MySQLクライアントなど │ │ MySQLプロトコル ▼ ClickHouse |
設定方法
インターフェイスが使用するポート設定をClickHouseサーバーの構成ファイルに追加する必要があります。
以下のXMLファイルを作成し、コンテナ作成時に/etc/clickhouse-server/config.d/mysql.xmlにマウントしました。
mysql.xml
|
1 2 3 |
<clickhouse> <mysql_port>9004</mysql_port> </clickhouse> |
|
1 2 3 |
docker run -d \ -v ${PWD}/mysql.xml:/etc/clickhouse-server/config.d/mysql.xml \ (...) |
接続用ユーザーを作成
実運用では、必要最小限の権限のみを付与したユーザーを利用することを推奨します。
|
1 2 3 4 5 6 |
CREATE USER mysql_interface IDENTIFIED WITH double_sha1_password BY '(インターフェイス用パスワード)'; GRANT CREATE, SELECT, INSERT ON default.* TO mysql_interface; GRANT SELECT ON sakila.* TO mysql_interface; GRANT MYSQL ON *.* TO mysql_interface; GRANT NAMED COLLECTION ON mymysql TO mysql_interface; |
MySQLクライアントから接続する
MySQLクライアントから以下のようにClickHouseへ接続してみます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
$ docker exec -it mysql \ mysql \ --protocol tcp \ -h clickhouse \ -u mysql_interface \ -P 9004 \ --password \ default Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 Server version: 26.6.1.1193-ClickHouse Copyright (c) 2000, 2026, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> |
ここでServer version表示からも分かるように、接続先はMySQLではなくClickHouseです。 MySQLクライアントを利用していますが、実際にSQLを処理しているのはClickHouseになります。
そのため、ClickHouse固有のSQLや関数も使用できます。
試しに、テーブル関数をクエリしてみます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
mysql> SELECT -> ci.city_id, -> ci.city, -> co.country -> FROM mysql(mymysql, database = 'sakila', `table` = 'city') AS ci -> INNER JOIN mysql(mymysql, database = 'sakila', `table` = 'country') AS co ON ci.country_id = co.country_id -> ORDER BY ci.city_id ASC -> LIMIT 5; +---------+------------------------+----------------------+ | city_id | city | country | +---------+------------------------+----------------------+ | 1 | A Coruña (La Coruña) | Spain | | 2 | Abha | Saudi Arabia | | 3 | Abu Dhabi | United Arab Emirates | | 4 | Acuña | Mexico | | 5 | Adana | Turkey | +---------+------------------------+----------------------+ 5 rows in set (0.03 sec) Read 709 rows, 14.09 KiB in 0.021718 sec., 32645 rows/sec., 648.76 KiB/sec. |
利用時の注意点
インターフェイスは便利な機能ですが、いくつか注意点があります。
-
MySQL固有のSQLやコマンドがすべて利用できるわけではない
-
ClickHouse固有のSQLや関数が利用できる
-
ClickHouseセルフマネージド版の場合、接続ポートは通常のMySQL(3306)ではなく、デフォルトでは9004を使用する
そのため、「MySQLクライアントでClickHouseを操作するための互換機能」と理解しておくと混乱しません。
まとめ
本記事では、ClickHouseとMySQLを連携する5つの方法を紹介しました。
前半の4つ(テーブル関数、Dictionary、テーブルエンジン、データベースエンジン)は、ClickHouseからMySQLのデータを利用するための機能です。 一方、インターフェイスは、MySQLクライアントやMySQLプロトコル対応のGUIツールからClickHouseへ接続するための機能であり、用途が異なります。
それぞれ目的や仕組みが異なるため、利用シーンに応じて適切な機能を選択することが重要です。
ClickHouseは分析基盤として利用されることが多い一方で、このようなMySQL連携機能を活用することで、既存のMySQL環境と組み合わせた柔軟なシステム構成を実現できます。 用途に応じて各機能を使い分けることで、ClickHouseをより効果的に活用できるでしょう。


