O Hologres é compatível com PostgreSQL; portanto, a migração do MySQL exige mapeamento de tipos de dados e adaptação de consultas SQL. Este tópico aborda os métodos de sincronização disponíveis, os mapeamentos de tipos de dados e as diferenças em consultas e funções encontradas após a migração.
Escolha um método de sincronização
A tabela a seguir lista os métodos de sincronização disponíveis para migrar dados do MySQL para o Hologres. Para processamento de Extração, Transformação e Carga (ETL), use o Flink para ler do MySQL e gravar no Hologres. Para mais informações, consulte Realtime Compute for Apache Flink.
|
Método |
Quando usar |
Documentação |
|
Carregar uma única tabela |
Sincronize dados de uma única tabela do MySQL para o Hologres como uma operação em lote única. |
|
|
Sincronizar uma única tabela em tempo real |
Transmita alterações de uma única tabela do MySQL para o Hologres usando binary logging (Binlog) do MySQL. |
|
|
Sincronizar um banco de dados inteiro em tempo real |
Transmita alterações de todo um banco de dados MySQL para o Hologres em tempo real. |
|
|
Solução de sincronização |
Use o Data Integration para sincronizar várias tabelas em uma única operação, com sincronização completa integrada seguida por sincronização incremental contínua. |
Mapeamento de tipos de dados
Use a tabela a seguir para mapear tipos do MySQL para tipos do Hologres. Para obter uma referência completa dos tipos do Hologres, consulte Visão geral dos tipos de dados.
Regras importantes antes de começar:
Tamanho de inteiros: O Hologres possui três tipos inteiros — SMALLINT (2 bytes), INTEGER (4 bytes) e BIGINT (8 bytes) — enquanto o MySQL possui cinco. Mapeie cada inteiro do MySQL para um tipo do Hologres com tamanho em bytes igual ou superior.
Inteiros sem sinal: O Hologres não oferece suporte a inteiros sem sinal. Considere possíveis estouros ao mapear campos sem sinal e use um tipo inteiro maior ou TEXT se os valores puderem exceder o intervalo de destino.
Tipos de texto: Mapeie todas as variantes de texto do MySQL (TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT) para TEXT no Hologres.
DATETIME e fusos horários: O DATETIME do MySQL não possui fuso horário e usa o formato
YYYY-MM-DD HH:MM:SS. Por padrão, ele é mapeado paraTIMESTAMPTZ(TIMESTAMP WITH TIME ZONE) no Hologres. Para usar um TIMESTAMP sem fuso horário, especifique-o explicitamente na configuração de sincronização ou na instrução de criação da tabela.
|
Tipo MySQL |
Tipo Hologres |
Observações |
|
BIGINT |
BIGINT |
|
|
BIGINT(20) UNSIGNED |
TEXT |
O Hologres não suporta inteiros sem sinal. O uso de TEXT evita riscos de estouro. |
|
BINARY(n) |
BYTEA |
|
|
BIT |
BOOLEAN |
|
|
CHAR(n), CHARACTER(n) |
CHAR(n), CHARACTER(n) |
|
|
DATE |
DATE |
|
|
DATETIME |
TIMESTAMPTZ (TIMESTAMP WITH TIME ZONE) |
O DATETIME do MySQL não tem fuso horário. Mapeia para TIMESTAMPTZ por padrão. Especifique TIMESTAMP explicitamente para desativar essa opção. |
|
DECIMAL(p,s), DEC(p,s) |
DECIMAL(p,s), DEC(p,s) |
|
|
DOUBLE |
DOUBLE PRECISION |
|
|
FLOAT |
REAL |
|
|
INT, INTEGER |
INT, INTEGER |
|
|
MEDIUMINT |
INTEGER |
MEDIUMINT ocupa 3 bytes; INTEGER ocupa 4 bytes — o próximo tipo inteiro maior do Hologres. |
|
NUMERIC(p,s) |
NUMERIC(p,s) |
|
|
SMALLINT |
SMALLINT |
|
|
TINYBLOB, BLOB, MEDIUMBLOB, LONGBLOB |
BYTEA |
|
|
TINYINT |
SMALLINT |
TINYINT ocupa 1 byte; SMALLINT é o menor tipo inteiro do Hologres (2 bytes). |
|
TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT |
TEXT |
Todas as variantes de texto do MySQL são mapeadas para TEXT. |
|
TIME |
TIME [WITHOUT TIME ZONE] |
|
|
TIMESTAMP |
TIMESTAMP [WITH TIME ZONE] |
|
|
VARBINARY(n), VARBINARY(max) |
BYTEA |
|
|
VARCHAR(n) |
VARCHAR(n) |
|
|
VARCHAR(max) |
TEXT |
Diferenças na sintaxe de consulta
Como o Hologres é compatível com PostgreSQL, vários padrões de consulta do MySQL exigem adaptação.
Aspas
Por padrão, o Hologres não diferencia maiúsculas de minúsculas. Para referenciar um identificador sensível a maiúsculas e minúsculas, envolva-o com aspas duplas ("").
Substitua a sintaxe de crase do MySQL por aspas duplas:
-- MySQL
SELECT `A` FROM b;
-- Hologres
SELECT "A" FROM b;
Condições de filtro
O Hologres exige correspondência exata de tipos nas condições de filtro e não realiza conversão implícita de tipos. Se os tipos não corresponderem, ocorrerá um erro como:
operator does not exist: text = integer
Para resolver isso, crie conversões de tipo personalizadas:
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;
Exemplo: Se a coluna ds for TEXT e você filtrar com um valor inteiro, a seguinte consulta falhará no Hologres:
SELECT * FROM business_module WHERE ds = 20210329;
Após criar a conversão apropriada, a consulta será executada sem erros.
Paginação
Substitua a sintaxe LIMIT de dois argumentos do MySQL pela forma padrão OFFSET/LIMIT:
-- MySQL
LIMIT 0, 10
-- Hologres
OFFSET 0 LIMIT 10
Ordenação
MySQL e Hologres diferem na forma como ordenam valores NULL em ordem ascendente:
|
Banco de dados |
Padrão ASC |
Padrão DESC |
|
MySQL |
NULLS FIRST |
NULLS FIRST |
|
Hologres |
NULLS LAST |
NULLS FIRST |
Para obter resultados consistentes, especifique explicitamente a ordem de classificação dos NULLs:
ORDER BY column DESC NULLS LAST
Agrupamento
Por padrão, o Hologres não suporta GROUP BY em tipos não exatos (FLOAT, DOUBLE). Existem duas opções:
Converta a coluna para DECIMAL antes de agrupar.
-
Ative o parâmetro
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;
Este parâmetro requer o Hologres V0.10 ou posterior. Se sua instância executar uma versão anterior, entre em contato com o suporte técnico pelo grupo DingTalk do Hologres para solicitar uma atualização. Para detalhes, consulte Como obtenho mais suporte online? .
UNION
O operador UNION exige tipos de colunas correspondentes em todas as consultas. O MySQL realiza conversão implícita de tipos; o Hologres não. Uma incompatibilidade de tipos gera:
UNION types bigint and text cannot be matched
Converta explicitamente as colunas incompatíveis:
-- 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;
Diferenças nas funções
O Hologres suporta a maioria das funções compatíveis com PostgreSQL. Para a lista completa, consulte Funções compatíveis com PostgreSQL. As seguintes funções do MySQL precisam de adaptação.
Divisão por zero
O MySQL retorna NULL para divisões por zero. O Hologres retorna um erro:
ERROR: division by zero
Opção 1: Use NULLIF para tratar o divisor como NULL quando for zero:
SELECT a / NULLIF(b, 0) FROM table;
Opção 2 (Hologres V1.3.21 e posterior): Ative a extensão mysql_compatible para tolerar divisões por zero sem alterar consultas individuais:
-- 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;
Isso abrange múltiplos cenários:
-- 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;
Se encontrar problemas, consulte Erros comuns de falha na preparação de atualização ou entre em contato com o suporte técnico pelo grupo DingTalk do Hologres. Para detalhes, consulte Como obtenho suporte online adicional?.
Divisão inteira
O MySQL retorna um decimal ao dividir dois inteiros com resto; o Hologres trunca para um inteiro.
|
Expressão |
Resultado MySQL |
Resultado Hologres |
|
5 / 2 |
2,5 |
2 |
Converta um dos operandos para um tipo de ponto flutuante para obter o resultado decimal:
SELECT 1 / 2::FLOAT;
Função IF
O Hologres não suporta a função IF. Substitua-a por uma expressão CASE WHEN:
-- MySQL
IF(condition, true_value, false_value)
-- Hologres
CASE WHEN condition THEN true_value ELSE false_value END
Função IFNULL
Substitua a função IFNULL do MySQL por COALESCE:
-- MySQL
IFNULL(x, y)
-- Hologres
COALESCE(x, y)
Função LENGTH
Substitua a função LENGTH do MySQL por CHAR_LENGTH:
-- MySQL
LENGTH(string)
-- Hologres
CHAR_LENGTH(string)
Perguntas frequentes
COUNT DISTINCT retorna resultados diferentes para múltiplas colunas
Sintoma: Uma consulta COUNT DISTINCT com múltiplas colunas retorna contagens de linhas diferentes no MySQL e no Hologres.
Causa: A função count(distinct column_1, column_2, ...) do MySQL exclui linhas onde qualquer uma das colunas especificadas é NULL. Já a função count(distinct(column_1, column_2, ...)) do Hologres inclui linhas mesmo quando algumas colunas são NULL, o que resulta em uma contagem maior.
Solução: Concatene as colunas para que qualquer NULL se propague pela expressão, replicando o comportamento do MySQL:
SELECT count(distinct column_1 || column_2 || ...) FROM table;
Exemplo:
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;