Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

mysql

Permet d'exécuter des requêtes SELECT et INSERT sur des données stockées sur un serveur MySQL distant.

Syntaxe

mysql({host:port, database, table, user, password[, replace_query, on_duplicate_clause] | named_collection[, option=value [,..]]})

Arguments

Argument Description
host:port Adresse du serveur MySQL.
database Nom de la base de données distante.
table Nom de la table distante, ou requête transmise telle quelle à MySQL (voir Utilisation d’une requête à la place d’un nom de table).
user Utilisateur MySQL.
password Mot de passe de l’utilisateur.
replace_query Indicateur qui convertit les requêtes INSERT INTO en REPLACE INTO. Valeurs possibles :
- 0 - La requête est exécutée comme INSERT INTO.
- 1 - La requête est exécutée comme REPLACE INTO.
on_duplicate_clause Expression ON DUPLICATE KEY on_duplicate_clause ajoutée à la requête INSERT. Elle ne peut être spécifiée qu’avec replace_query = 0 (si vous passez simultanément replace_query = 1 et on_duplicate_clause, ClickHouse génère une exception).
Exemple : INSERT INTO t (c1,c2) VALUES ('a', 2) ON DUPLICATE KEY UPDATE c2 = c2 + 1;
Ici, on_duplicate_clause correspond à UPDATE c2 = c2 + 1. Consultez la documentation MySQL pour savoir quelle valeur de on_duplicate_clause vous pouvez utiliser avec la clause ON DUPLICATE KEY.

Les arguments peuvent également être transmis à l’aide de collections nommées. Dans ce cas, host et port doivent être spécifiés séparément. Cette approche est recommandée en environnement de production.

Les clauses WHERE simples telles que =, !=, >, >=, <, <= sont actuellement exécutées sur le serveur MySQL.

Le reste des conditions et la contrainte d’échantillonnage LIMIT ne sont exécutés dans ClickHouse qu’une fois la requête MySQL terminée.

TLS/SSL

Les identifiants d'une connexion chiffrée à MySQL sont transmis sous forme de clés d'une collection nommée (ou d'arguments clé-valeur) :

Paramètre Description
ssl_ca_pem Contenu du certificat de l'autorité de certification utilisé pour vérifier le certificat du serveur MySQL.
ssl_cert_pem Contenu du certificat client, pour l'authentification par certificat.
ssl_key_pem Contenu de la clé privée associée à ssl_cert_pem.

Les valeurs correspondent au contenu des fichiers PEM correspondants, qui peut être copié dans une collection nommée ou dans une requête. Elles sont masquées dans les logs et dans les requêtes SHOW, comme les mots de passe.

Les mêmes identifiants peuvent également être fournis sous forme de chemins vers des fichiers sur le serveur, dans ssl_ca, ssl_cert et ssl_key — mais uniquement dans une collection nommée définie dans le fichier de configuration du serveur ; une telle valeur ne peut pas être remplacée dans une requête. Le serveur ouvre ces fichiers avec ses propres privilèges : accepter un chemin depuis SQL permettrait donc à tout utilisateur capable de définir une source MySQL d'explorer le système de fichiers local et de s'authentifier avec un certificat et une clé auxquels il n'est pas autorisé à accéder.

Utilisation d’une requête à la place d’un nom de table

À la place d’un nom de table, le troisième argument peut être une requête SELECT transmise à MySQL telle quelle. La structure de la table résultante est inférée à partir du résultat de la requête. La requête peut être écrite soit sous forme de sous-requête, soit encapsulée dans la fonction query :

SELECT * FROM mysql('localhost:3306', 'test', (SELECT a, b FROM t1 JOIN t2 USING (id) WHERE a > 0), 'user', 'password');
SELECT * FROM mysql('localhost:3306', 'test', query('SELECT a, b FROM t1 JOIN t2 USING (id) WHERE a > 0'), 'user', 'password');

Cela est utile pour déporter vers MySQL les jointures, agrégations ou tout autre traitement. Une telle table est en lecture seule : INSERT n'y est pas autorisé. La même syntaxe est prise en charge par le moteur de table MySQL.

Prend en charge plusieurs répliques, qui doivent être listées à l'aide de |. Par exemple :

SELECT name FROM mysql(`mysql{1|2|3}:3306`, 'mysql_database', 'mysql_table', 'user', 'password');

ou

SELECT name FROM mysql(`mysql1:3306|mysql2:3306|mysql3:3306`, 'mysql_database', 'mysql_table', 'user', 'password');

Valeur retournée

Un objet de table avec les mêmes colonnes que la table MySQL d’origine.

Exemples

Table dans MySQL :

mysql> CREATE TABLE `test`.`test` (
    ->   `int_id` INT NOT NULL AUTO_INCREMENT,
    ->   `float` FLOAT NOT NULL,
    ->   PRIMARY KEY (`int_id`));

mysql> INSERT INTO test (`int_id`, `float`) VALUES (1,2);

mysql> SELECT * FROM test;
+--------+-------+
| int_id | float |
+--------+-------+
|      1 |     2 |
+--------+-------+

Sélection de données dans ClickHouse :

SELECT * FROM mysql('localhost:3306', 'test', 'test', 'bayonet', '123');

Ou avec les collections nommées :

CREATE NAMED COLLECTION creds AS
        host = 'localhost',
        port = 3306,
        database = 'test',
        user = 'bayonet',
        password = '123';
SELECT * FROM mysql(creds, table='test');
┌─int_id─┬─float─┐
│      1 │     2 │
└────────┴───────┘

enable_compression

Active la compression pour les connexions via le protocole MySQL.

Valeur par défaut : false.

Ce paramètre s’applique à :

  • la fonction de table mysql ;
  • le moteur de table MySQL ;
  • le moteur de base de données MySQL ;
  • les collections nommées utilisées par les intégrations MySQL.

Lorsqu’il est activé, ClickHouse demande la compression pour cette connexion.

Exemple :

SELECT *
FROM mysql(
    'mysql80:3306',
    'clickhouse',
    'test_table',
    'root',
    'password',
    SETTINGS enable_compression = 1
);

Remplacement et insertion :

INSERT INTO FUNCTION mysql('localhost:3306', 'test', 'test', 'bayonet', '123', 1) (int_id, float) VALUES (1, 3);
INSERT INTO TABLE FUNCTION mysql('localhost:3306', 'test', 'test', 'bayonet', '123', 0, 'UPDATE int_id = int_id + 1') (int_id, float) VALUES (1, 4);
SELECT * FROM mysql('localhost:3306', 'test', 'test', 'bayonet', '123');
┌─int_id─┬─float─┐
│      1 │     3 │
│      2 │     4 │
└────────┴───────┘

Copie des données d'une table MySQL vers une table ClickHouse :

CREATE TABLE mysql_copy
(
   `id` UInt64,
   `datetime` DateTime('UTC'),
   `description` String,
)
ENGINE = MergeTree
ORDER BY (id,datetime);

INSERT INTO mysql_copy
SELECT * FROM mysql('host:port', 'database', 'table', 'user', 'password');

Ou, si vous copiez uniquement un lot incrémentiel depuis MySQL en vous basant sur l’ID maximal actuel :

INSERT INTO mysql_copy
SELECT * FROM mysql('host:port', 'database', 'table', 'user', 'password')
WHERE id > (SELECT max(id) FROM mysql_copy);
Navigation