Migração de SQL Server (MSSQL) para MySQL, no Windows

Migrate · · 7 min de leitura

Vai levar uma aplicação do SQL Server para o MySQL ou o MariaDB? O dbSlice copia as tabelas por um app Windows ou pela linha de comando, e depois mantém o MySQL sincronizado com o SQL Server até o dia da troca.

dbSlice ou MySQL Workbench?

O MySQL Workbench tem um assistente de migração gratuito que lê o SQL Server, e para uma migração única vale testar. O dbSlice é para equipes que precisam de execuções repetidas (Upsert ou só linhas novas toda noite até a virada), de uma diferença chave a chave e conferências na tela antes de gravar, de mascaramento para cópias de teste, e da mesma ferramenta para outros pares. Nenhum dos dois converte procedures ou triggers em T-SQL para MySQL; planeje essa parte à parte.

Fluxo da migração: planejar, levantar e desenhar com a sua equipe; carga inicial, atualização agendada e validação chave a chave com o dbSlice; virada depois que as conferências passam.
Onde o dbSlice entra numa migração de SQL Server para MySQL. Guia completo (em inglês): Data migration strategy.

Comparando ferramentas? Veja as melhores ferramentas para migrar SQL Server para MySQL →

Aba Synchronize do dbSlice

O que o dbSlice faz

  • Lê o SQL Server em lotes pequenos, para o banco em uso continuar atendendo os usuários.
  • Grava no MySQL e no MariaDB. As cargas iniciais e completas ficam mais rápidas quando o seu DBA liga o local_infile no servidor e você o permite na conexão; sem isso elas funcionam do mesmo jeito, só mais devagar.
  • Mostra o DDL do destino. Se a tabela não existe no MySQL, o dbSlice para antes de gravar e mostra um CREATE TABLE traduzido do SQL Server para o seu DBA revisar e rodar. Ele não cria objetos nos seus bancos por conta própria.
  • Mantém os seus ids. As linhas chegam com os valores originais de IDENTITY. O InnoDB do MySQL avança o AUTO_INCREMENT da tabela para depois do maior id inserido, então as linhas novas criadas pela aplicação depois da cópia não colidem.

Detalhes do SQL Server para planejar

SQL ServerSugerido no MySQLConfira
datetimeoffsetDATETIME(6)O offset não é mantido. Converta para UTC num SELECT de origem se o fuso importa
datetime2(7)DATETIME(6)O MySQL guarda microssegundos; o 7º dígito é descartado
uniqueidentifierCHAR(36)Guardado como texto; serve para joins, ocupa mais que BINARY(16)
nvarchar(max), varchar acima de 16.383LONGTEXTEsperado; indexe só um prefixo se precisar
bitTINYINT(1)O booleano usual do MySQL
varbinary, imageLONGBLOBEsperado
tinyint, smallint, int, bigintSMALLINT, SMALLINT, INT, BIGINTMesmas faixas; o tinyint ganha um tipo maior
decimal(p,s), money, smallmoneyDECIMAL(p,s)money chega como DECIMAL(19,4)
float, realDOUBLE—
char(n), nchar(n)VARCHAR(n)O preenchimento com espaços no fim não é mantido
time(7)TIMEO TIME do MySQL guarda segundos inteiros; troque para TIME(6) se precisar das frações
text, ntext, xmlLONGTEXTO XML chega como texto simples
timestamp / rowversionLONGBLOBCopiado como bytes. São as versões de linha do SQL Server, e a maioria dos destinos não precisa delas: você pode deixar a coluna fora da cópia
sql_variant, hierarchyid, geography, geometryLONGTEXTConverta num SELECT de origem (por exemplo .ToString() ou CAST) se precisar do valor

Duas configurações do lado do MySQL:

  • Conjunto de caracteres. Crie o banco do MySQL (ou as tabelas) com utf8mb4. Com um padrão latin1 antigo, os caracteres fora dele falham ou viram ?.
  • Maiúsculas nos nomes de tabela. No Linux, os nomes de tabela do MySQL diferenciam maiúsculas por padrão. Escolha uma convenção (normalmente minúsculas) no CREATE TABLE e mantenha; o dbSlice casa as colunas pelo nome sem diferenciar maiúsculas.

Migrar procedures e triggers em T-SQL para MySQL

O dbSlice move os dados; o código é uma frente à parte. A maioria das reescritas de T-SQL se resume à mesma lista:

T-SQL (SQL Server)MySQL
SELECT TOP 10 …SELECT … LIMIT 10
ISNULL(a, b)IFNULL(a, b) ou COALESCE(a, b)
GETDATE(), SYSDATETIME()NOW(), NOW(6)
IDENTITY(1,1)AUTO_INCREMENT
@variable declarada com DECLAREDECLARE dentro da procedure, ou @user_variable
Tabelas #tempCREATE TEMPORARY TABLE
TRY … CATCHDECLARE … HANDLER FOR SQLEXCEPTION
+ para juntar stringsCONCAT(a, b)
[colchetes] em volta dos nomes`crases`
Parâmetros OUTPUTParâmetros OUT
Triggers com as tabelas inserted / deletedTriggers de linha com NEW / OLD, um por evento
MERGEINSERT … ON DUPLICATE KEY UPDATE

Reescreva e teste o código contra uma cópia dos dados primeiro: carregue as tabelas com o dbSlice, rode as novas procedures no MySQL e compare os resultados com o SQL Server antes da virada.

Erros comuns e o que significam

  • Incorrect string value: '\xF0\x9F…' for column … — a tabela do MySQL não está em utf8mb4. Recrie a tabela (ou o banco) com utf8mb4, como acima.
  • Data too long for column … — a coluna de destino é menor que os dados, muitas vezes um VARCHAR declarado à mão. Aumente o tamanho ou troque para LONGTEXT.
  • Row size too large (> 8126) — muitas colunas VARCHAR largas numa linha InnoDB. Transforme as maiores em TEXT ou LONGTEXT no CREATE TABLE.
  • Loading local data is disabled — o local_infile está desligado no servidor ou na conexão. A carga roda sem ele, só mais devagar; fale com o seu DBA se quiser o caminho mais rápido.
  • Duplicate entry … for key 'PRIMARY' — a linha já está no MySQL. Use Upsert ou Insert new em vez de Initial load nas execuções repetidas.

Passo a passo

Antes de começar

  1. Conecte no SQL Server e no MySQL ou MariaDB.
  2. Escolha a tabela de origem ou um SELECT, e a tabela de destino.
  3. Escolha a coluna-chave usada para casar as linhas.
  4. Escolha o modo: Initial load na primeira vez, depois Upsert ou Insert new.
  5. Confira antes de gravar: o Record Diff compara as chaves dos dois lados.
  6. Rode, ou salve como job e agende pela CLI. O Replicador copia uma lista de tabelas numa execução, as pais antes das filhas.

Mantenha os dois sincronizados até a virada

Agende um job Upsert toda noite. Com uma coluna que só cresce (um updated_at ou o id IDENTITY), cada execução lê só as linhas acima do último valor visto. Exclusões no SQL Server não são detectadas pelas execuções incrementais; por isso, planeje uma comparação completa ou uma recarga antes da troca.

Perguntas frequentes

O dbSlice converte stored procedures ou triggers em T-SQL?

Não. Ele move dados. Reescreva procedures e triggers para o MySQL à parte, e use o dbSlice para os dados e a sincronia até a virada.

O SQL Server pode continuar rodando durante a migração?

Sim. O dbSlice lê em lotes pequenos, e execuções noturnas Upsert ou só de linhas novas mantêm o MySQL perto do SQL Server até você trocar.

Ele cria as tabelas no MySQL?

Não por padrão. Ele para antes de gravar e mostra um CREATE TABLE para o seu DBA revisar e rodar.

MySQL ou MariaDB?

Os dois. O dbSlice conecta em qualquer um deles sem nada extra para instalar.

Posso testar antes de comprar?

Sim. A versão gratuita da Microsoft Store não precisa de chave de licença; gravar num banco de destino exige uma licença Desktop ou Server.

Existe ferramenta gratuita para migrar SQL Server para MySQL?

O assistente de migração do MySQL Workbench é gratuito e faz uma cópia única de esquema e dados. A versão gratuita do dbSlice na Microsoft Store não precisa de chave de licença; gravar no MySQL exige uma licença Desktop ou Server.

Quanto tempo leva uma migração de SQL Server para MySQL?

Depende das linhas, da largura das linhas, da rede e do servidor MySQL. Meça uma tabela grande num ensaio e dimensione o resto a partir dela; veja how to read a sync speed number (em inglês).

Também serve para

SQL Server para PostgreSQL (guia de sincronia), Oracle, Firebird, SQLite ou InterSystems IRIS, e MySQL de volta para o SQL Server.

Vai mover dados no outro sentido? MySQL para SQL Server.

Ainda não usa o dbSlice?
Experimente a versão gratuita da Microsoft Store: ela conecta, navega pelos dados, compara estruturas e exporta para CSV.

Experimente grátis Veja as demonstrações

Em produção há mais de 6 anos · Garantia de 14 dias · Roda na sua máquina