MySQL e PostgreSQL usam SQL, mas nem sempre o interpretam da mesma forma.
Uma consulta pode parecer perfeitamente normal no MySQL e ainda assim falhar ou se comportar de maneira diferente após ser movida para o PostgreSQL.
Aqui estão sete diferenças que vale a pena verificar durante uma migração.
1. Aspas em identificadores
O MySQL costuma usar acentos graves ao redor dos nomes de tabelas e colunas:
SELECT `name`, `order`
FROM `customers`;
O PostgreSQL usa aspas duplas para identificadores entre aspas:
SELECT "name", "order"
FROM "customers";
O uso de aspas se torna especialmente importante quando um identificador contém espaços, letras maiúsculas ou palavras reservadas.
Uma abordagem melhor a longo prazo é usar identificadores simples, em letras minúsculas e que não exijam aspas sempre que possível.
2. IDs gerados automaticamente
Uma tabela do MySQL pode usar AUTO_INCREMENT:
CREATE TABLE customers (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100)
);
Um equivalente moderno no PostgreSQL pode usar uma coluna de identidade:
CREATE TABLE customers (
id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
name VARCHAR(100)
);
O PostgreSQL também oferece suporte a SERIAL, mas as colunas de identidade fornecem um comportamento mais claro e baseado em padrões para novos esquemas.
Após migrar os dados, verifique se a sequência do PostgreSQL continua depois do ID importado mais alto.
3. Valores booleanos
As aplicações MySQL costumam representar valores booleanos com TINYINT:
CREATE TABLE users (
is_active TINYINT(1)
);
O PostgreSQL tem um tipo BOOLEAN dedicado:
CREATE TABLE users (
is_active BOOLEAN
);
Valores como 1 e 0 talvez precisem ser convertidos para TRUE e FALSE.
Essa diferença também pode afetar o código da aplicação, filtros, valores padrão e dados importados.
4. Tratamento de valores NULL
O MySQL oferece IFNULL:
SELECT IFNULL(phone_number, 'Not provided')
FROM customers;
O PostgreSQL costuma usar COALESCE:
SELECT COALESCE(phone_number, 'Not provided')
FROM customers;
COALESCE é compatível com ambos os bancos de dados e pode facilitar migrações futuras.
O comportamento de NULL ainda deve ser testado cuidadosamente em comparações, concatenações, cálculos e expressões condicionais.
5. Operações aritméticas com datas
O MySQL pode adicionar sete dias com DATE_ADD:
SELECT DATE_ADD(order_date, INTERVAL 7 DAY)
FROM orders;
O PostgreSQL pode expressar a mesma operação com um intervalo:
SELECT order_date + INTERVAL '7 days'
FROM orders;
A sintaxe visível é apenas parte da diferença.
Verifique também os tipos de data, os timestamps, os fusos horários, os limites entre meses e o comportamento do horário de verão quando forem relevantes para a aplicação.
6. Concatenação de strings
O MySQL costuma usar CONCAT:
SELECT CONCAT(first_name, ' ', last_name)
FROM customers;
O PostgreSQL oferece suporte a CONCAT, mas também usa com frequência o operador de barra dupla:
SELECT first_name || ' ' || last_name
FROM customers;
Tenha cuidado quando os valores puderem ser NULL. Diferentes métodos de concatenação podem produzir resultados diferentes dependendo das entradas.
Teste nomes, endereços, rótulos de relatórios e outras expressões que combinem várias colunas.
7. Sintaxe de upsert
O MySQL pode inserir ou atualizar uma linha com ON DUPLICATE KEY UPDATE:
INSERT INTO products (id, name, price)
VALUES (10, 'Keyboard', 49.99)
ON DUPLICATE KEY UPDATE
name = VALUES(name),
price = VALUES(price);
O PostgreSQL usa ON CONFLICT:
INSERT INTO products (id, name, price)
VALUES (10, 'Keyboard', 49.99)
ON CONFLICT (id) DO UPDATE SET
name = EXCLUDED.name,
price = EXCLUDED.price;
A instrução do PostgreSQL identifica explicitamente o alvo do conflito.
Revise as restrições e os índices exclusivos antes de converter upserts, pois eles determinam quais conflitos o PostgreSQL pode detectar.
O que mais deve ser testado?
A conversão da sintaxe é apenas o primeiro passo.
Depois de converter uma consulta ou um esquema do MySQL, compare o comportamento da origem e do destino usando dados representativos.
Verifique:
• Contagens de linhas
• Valores NULL
• IDs gerados
• Resultados de data e hora
• Precisão decimal
• Sensibilidade a maiúsculas e minúsculas
• Ordem de classificação
• Tratamento de duplicatas
• Valores padrão
O SQL executado com sucesso não é automaticamente SQL que se comporta corretamente.
Um fluxo de trabalho confiável para a migração
Um fluxo de trabalho prático de MySQL para PostgreSQL é:
Entender o SQL de origem
Convertê-lo para PostgreSQL
Revisar as alterações específicas do dialeto
Inspecionar os diagnósticos
Testar com dados representativos
Comparar os resultados
Implantar somente após a validação
O Sqlinfy pode ajudar a criar uma conversão inicial estruturada entre MySQL e PostgreSQL. Os desenvolvedores ainda devem revisar e testar o SQL convertido antes de usá-lo em produção.