Hologres étant compatible avec PostgreSQL, la migration depuis MySQL nécessite un mappage des types de données et une adaptation des requêtes SQL. Cette rubrique présente les méthodes de synchronisation disponibles, le mappage des types de données ainsi que les différences en matière de requêtes et de fonctions que vous rencontrerez après la migration.
Choisir une méthode de synchronisation
Le tableau suivant répertorie les méthodes de synchronisation disponibles pour migrer les données MySQL vers Hologres. Pour le traitement ETL (Extract, Transform, Load), utilisez Flink pour lire les données depuis MySQL et les écrire dans Hologres. Pour plus d'informations, consultez la rubrique Présentation de Fully Managed Flink.
|
Méthode |
Cas d'utilisation |
Documentation |
|
Chargement d'une table unique |
Synchronisez les données d'une seule table MySQL vers Hologres lors d'une opération par lot ponctuelle. |
|
|
Synchronisation en temps réel d'une table unique |
Diffusez en continu les modifications d'une seule table MySQL vers Hologres à l'aide du journal binaire MySQL (Binlog). |
|
|
Synchronisation en temps réel d'une base de données entière |
Diffusez en continu les modifications d'une base de données MySQL entière vers Hologres en temps réel. |
Configuration et gestion d'un nœud de synchronisation en temps réel |
|
Solution de synchronisation |
Utilisez Data Integration pour synchroniser plusieurs tables en une seule opération, avec une synchronisation complète des données suivie d'une synchronisation continue des données incrémentielles. |
Mappage des types de données
Utilisez le tableau suivant pour mapper les types MySQL aux types Hologres. Pour une référence complète des types Hologres, consultez la rubrique Présentation des types de données.
Règles clés à respecter avant de commencer :
Taille des entiers : Hologres propose trois types d'entiers — SMALLINT (2 octets), INTEGER (4 octets) et BIGINT (8 octets) — contre cinq pour MySQL. Mappez chaque entier MySQL vers un type Hologres dont la taille en octets est égale ou supérieure.
Entiers non signés : Hologres ne prend pas en charge les entiers non signés. Tenez compte des risques de dépassement de capacité lors du mappage des champs non signés et utilisez un type d'entier plus grand ou TEXT si les valeurs risquent de dépasser la plage cible.
Types texte : Mappez toutes les variantes de texte MySQL (TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT) vers TEXT dans Hologres.
DATETIME et fuseaux horaires : Le type DATETIME de MySQL ne gère pas les fuseaux horaires et utilise le format
YYYY-MM-DD HH:MM:SS. Par défaut, il est mappé versTIMESTAMPTZ(TIMESTAMP WITH TIME ZONE) dans Hologres. Pour utiliser un TIMESTAMP sans fuseau horaire, spécifiez-le explicitement dans votre configuration de synchronisation ou dans l'instruction de création de table.
|
Type MySQL |
Type Hologres |
Notes |
|
BIGINT |
BIGINT |
|
|
BIGINT(20) UNSIGNED |
TEXT |
Hologres ne prend pas en charge les entiers non signés. L'utilisation de TEXT évite les risques de dépassement de capacité. |
|
BINARY(n) |
BYTEA |
|
|
BIT |
BOOLEAN |
|
|
CHAR(n), CHARACTER(n) |
CHAR(n), CHARACTER(n) |
|
|
DATE |
DATE |
|
|
DATETIME |
TIMESTAMPTZ (TIMESTAMP WITH TIME ZONE) |
Le type DATETIME de MySQL ne gère pas les fuseaux horaires. Il est mappé par défaut vers TIMESTAMPTZ. Spécifiez explicitement TIMESTAMP pour désactiver cette option. |
|
DECIMAL(p,s), DEC(p,s) |
DECIMAL(p,s), DEC(p,s) |
|
|
DOUBLE |
DOUBLE PRECISION |
|
|
FLOAT |
REAL |
|
|
INT, INTEGER |
INT, INTEGER |
|
|
MEDIUMINT |
INTEGER |
MEDIUMINT occupe 3 octets ; INTEGER en occupe 4, ce qui correspond au type entier supérieur disponible dans Hologres. |
|
NUMERIC(p,s) |
NUMERIC(p,s) |
|
|
SMALLINT |
SMALLINT |
|
|
TINYBLOB, BLOB, MEDIUMBLOB, LONGBLOB |
BYTEA |
|
|
TINYINT |
SMALLINT |
TINYINT occupe 1 octet ; SMALLINT est le plus petit type entier disponible dans Hologres (2 octets). |
|
TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT |
TEXT |
Toutes les variantes de texte MySQL sont mappées vers TEXT. |
|
TIME |
TIME [WITHOUT TIME ZONE] |
|
|
TIMESTAMP |
TIMESTAMP [WITH TIME ZONE] |
|
|
VARBINARY(n), VARBINARY(max) |
BYTEA |
|
|
VARCHAR(n) |
VARCHAR(n) |
|
|
VARCHAR(max) |
TEXT |
Différences de syntaxe des requêtes
Hologres étant compatible avec PostgreSQL, plusieurs modèles de requête MySQL nécessitent une adaptation.
Guillemets
Par défaut, Hologres ne distingue pas la casse. Pour référencer un identifiant sensible à la casse, encadrez-le avec des guillemets doubles ("").
Remplacez la syntaxe des accents graves de MySQL par des guillemets doubles :
-- MySQL
SELECT `A` FROM b;
-- Hologres
SELECT "A" FROM b;
Conditions de filtrage
Hologres exige une correspondance exacte des types dans les conditions de filtrage et n'effectue pas de conversion implicite de type. Si les types ne correspondent pas, vous obtiendrez une erreur telle que :
operator does not exist: text = integer
Pour résoudre ce problème, créez des casts de type personnalisés :
CREATE CAST (TEXT AS INTEGER) WITH INOUT AS IMPLICIT;
CREATE CAST (TEXT AS BIGINT) WITH INOUT AS IMPLICIT;
CREATE CAST (TEXT AS DECIMAL) WITH INOUT AS IMPLICIT;
CREATE CAST (TEXT AS TIMESTAMP) WITH INOUT AS IMPLICIT;
CREATE CAST (NUMERIC AS TEXT) WITH INOUT AS IMPLICIT;
Exemple : Si la colonne ds est de type TEXT et que vous appliquez un filtre avec une valeur entière, la requête suivante échoue dans Hologres :
SELECT * FROM business_module WHERE ds = 20210329;
Après avoir créé le cast approprié, la requête s'exécute sans erreur.
Pagination
Remplacez la syntaxe LIMIT à deux arguments de MySQL par la forme standard OFFSET/LIMIT :
-- MySQL
LIMIT 0, 10
-- Hologres
OFFSET 0 LIMIT 10
Tri
MySQL et Hologres diffèrent dans la manière dont ils trient les valeurs NULL par ordre croissant :
|
Base de données |
ASC par défaut |
DESC par défaut |
|
MySQL |
NULLS FIRST |
NULLS FIRST |
|
Hologres |
NULLS LAST |
NULLS FIRST |
Pour obtenir des résultats cohérents, spécifiez explicitement l'ordre de tri des valeurs NULL :
ORDER BY column DESC NULLS LAST
Groupement
Par défaut, Hologres ne prend pas en charge GROUP BY sur les types inexacts (FLOAT, DOUBLE). Deux options s'offrent à vous :
Convertissez la colonne en DECIMAL avant le groupement.
-
Activez le paramètre
hg_experimental_enable_double_equivalent:-- Session level SET hg_experimental_enable_double_equivalent = on; -- Database level ALTER DATABASE <database_name> SET hg_experimental_enable_double_equivalent = on;
Ce paramètre nécessite Hologres V0.10 ou une version ultérieure. Si votre instance exécute une version antérieure, contactez le support technique via le groupe DingTalk Hologres pour demander une mise à niveau. Pour plus de détails, consultez la rubrique Comment obtenir davantage d'assistance en ligne ? .
UNION
L'opérateur UNION requiert des types de colonnes correspondants dans toutes les requêtes. MySQL effectue une conversion implicite de type, contrairement à Hologres. Une incompatibilité de type génère l'erreur suivante :
UNION types bigint and text cannot be matched
Convertissez explicitement les colonnes incompatibles :
-- Fails if project_id is BIGINT in tableA and TEXT in tableB
SELECT project_id FROM tableA
UNION ALL
SELECT project_id FROM tableB;
-- Fix: cast to a matching type
SELECT project_id FROM tableA
UNION ALL
SELECT CAST(project_id AS BIGINT) FROM tableB;
Différences de fonctions
Hologres prend en charge la plupart des fonctions compatibles avec PostgreSQL. Pour la liste complète, consultez la rubrique Fonctions compatibles avec PostgreSQL. Les fonctions MySQL suivantes nécessitent une adaptation.
Division par zéro
MySQL renvoie NULL en cas de division par zéro. Hologres renvoie une erreur :
ERROR: division by zero
Option 1 : Utilisez NULLIF pour traiter le diviseur comme NULL lorsqu'il est égal à zéro :
SELECT a / NULLIF(b, 0) FROM table;
Option 2 (Hologres V1.3.21 et versions ultérieures) : Activez l'extension mysql_compatible pour tolérer la division par zéro sans modifier les requêtes individuelles :
-- Run once per database (requires Superuser)
CREATE EXTENSION IF NOT EXISTS mysql_compatible;
-- Enable division-by-zero tolerance for the current session
SET mysql_compatible.enable = on;
Cette solution couvre plusieurs scénarios :
-- Scenario 1: Constant division of the same type
SET mysql_compatible.enable = on;
SELECT 1 / 0;
-- Scenario 2: Constant division with type conversion
SET mysql_compatible.enable = on;
SELECT 1.0 / 0;
-- Scenario 3: Dividend is a column expression
SET mysql_compatible.enable = on;
SELECT SUM(c) / 0 FROM (SELECT generate_series(1, 100) AS c) AS t;
-- Scenario 4: Divisor is a column expression
SET mysql_compatible.enable = on;
SELECT MAX(c) / SUM(d)
FROM (
SELECT generate_series(1, 101) AS c,
generate_series(-50, 50) AS d
) AS t;
-- Scenario 5: Tolerate division by zero during INSERT
CREATE TABLE IF NOT EXISTS test_insert_divide_by_zero (c1 INT);
SET mysql_compatible.strict_mode = off;
SET mysql_compatible.enable = on;
INSERT INTO test_insert_divide_by_zero SELECT 100 / 0.0;
Si vous rencontrez des problèmes, consultez la rubrique Erreurs courantes lors de la préparation de la mise à niveau ou contactez le support technique via le groupe DingTalk Hologres. Pour plus de détails, consultez la rubrique Comment obtenir une assistance en ligne supplémentaire ?.
Division d'entiers
MySQL renvoie une valeur décimale lors de la division de deux entiers avec un reste, tandis que Hologres tronque le résultat en un entier.
|
Expression |
Résultat MySQL |
Résultat Hologres |
|
5 / 2 |
2,5 |
2 |
Convertissez l'un des opérandes en un type à virgule flottante pour obtenir le résultat décimal :
SELECT 1 / 2::FLOAT;
Fonction IF
Hologres ne prend pas en charge la fonction IF. Remplacez-la par une expression CASE WHEN :
-- MySQL
IF(condition, true_value, false_value)
-- Hologres
CASE WHEN condition THEN true_value ELSE false_value END
Fonction IFNULL
Remplacez la fonction IFNULL de MySQL par COALESCE :
-- MySQL
IFNULL(x, y)
-- Hologres
COALESCE(x, y)
Fonction LENGTH
Remplacez la fonction LENGTH de MySQL par CHAR_LENGTH :
-- MySQL
LENGTH(string)
-- Hologres
CHAR_LENGTH(string)
FAQ
COUNT DISTINCT renvoie des résultats différents pour plusieurs colonnes
Symptôme : Une requête COUNT DISTINCT multicolumnes renvoie des nombres de lignes différents dans MySQL et Hologres.
Cause : La fonction count(distinct column_1, column_2, ...) de MySQL exclut les lignes où l'une des colonnes spécifiées est NULL. La fonction count(distinct(column_1, column_2, ...)) de Hologres inclut les lignes même lorsque certaines colonnes sont NULL, ce qui produit un nombre plus élevé.
Solution : Concaténez les colonnes afin que toute valeur NULL se propage à travers l'expression, reproduisant ainsi le comportement de MySQL :
SELECT count(distinct column_1 || column_2 || ...) FROM table;
Exemple :
CREATE TABLE count_distinct_test (
a TEXT,
b TEXT
);
INSERT INTO count_distinct_test VALUES
('a', 'b'),
('a', NULL),
(NULL, 'b'),
('a', 'b');
-- Hologres default: includes rows with NULL columns → returns 3
SELECT count(distinct(a, b)::text) FROM count_distinct_test;
-- MySQL-compatible: NULL propagates through concatenation → returns 1
SELECT count(distinct a || b) FROM count_distinct_test;