Este não é um post tutorial para explicar a migração de um banco de dados MySQL para o SQL Server da Microsoft. Apenas quero registrar algumas dicas e armadilhas que encontrei nesse processo.
Eu migrei dois aplicativos web: A intranet da empresa onde trabalho e meu site sobre MMOGs. Ambos usavam MySQL 5.1 acessado pelo Entity Framework do .NET.
Estrutura
Eu poderia ter usado a ferramenta de migração da Microsoft mas preferi criar um Database Project no Visual Studio 2010. Para isso usei o SQL Create Script do MySQL Workbench para exportar o modelo. Feito isso, eu copiei cada CREATE TABLE do MySQL para um arquivo do tipo Table do Database Project, separando as Constraints e Índices. Nessa etapa, no meu caso, foi tranquilo já que a sintaxe do Create do MySQL é parecida com o SQL Server, ficando ajustes apenas nos tipos de dados.
Aqui vem o primeiro cuidado. No Create Script do MySQL Workbench as Constraints são criadas com o comando Create Table em uma seqüencia específica para que as referências sempre existam:
CREATE TABLE IF NOT EXISTS `Departamento` (
`ID` INT NOT NULL AUTO_INCREMENT ,
`EmpresaID` INT NOT NULL ,
`Nome` VARCHAR(64) NOT NULL ,
PRIMARY KEY (`ID`) ,
INDEX `fk_empresa_departamento_empresa1` (`EmpresaID` ASC) ,
CONSTRAINT `fk_empresa_departamento_empresa1`
FOREIGN KEY (`EmpresaID` )
REFERENCES `Empresa` (`ID` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
Este script acima no Database Project será 3 arquivos:
Departamento.table.sql:
CREATE TABLE [dbo].[Departamento]
(
ID INT PRIMARY KEY IDENTITY(1,1) ,
EmpresaID INT NOT NULL ,
Nome VARCHAR(64) NOT NULL
)
Departamento.fkey.sql:
ALTER TABLE [dbo].[Departamento]
ADD CONSTRAINT FK_Departamento_EmpresaID
FOREIGN KEY (EmpresaID)
REFERENCES Empresa(ID)
ON DELETE NO ACTION
ON UPDATE NO ACTION
Departamento.fkey.sql:
CREATE INDEX IX_Departamento_EmpresaID
ON [dbo].Departamento (EmpresaID)
Nada impede que você coloque o CREATE INDEX no mesmo script do CREATE TABLE lembrando de separa-los pelo comando GO.
A medida que os scripts vão sendo criados no Database Project pode-se ir ajustando alguns tipos de dados. No MySQL Workbench quando criamos os modelos em diagrama é possível definir um campo como Boolean que depois e convertido em Tinyint(1) no MySQL e este deverá ser convertido para BIT do SQL Server. Terminado esse processo vem a parte legal: faça o Build do Database Project e todos os scripts serão validados, gerando uma lista de erros encontrados. Boa parte dos meus erros eram a falta do comando GO em alguns scripts, tipos de dados ou a falta do owner(dbo) antes do nome de algumas tabelas.
Eu não tinha muitas funções definidas no MySQL mas as poucas se limitaram em mudar alguma ou outra função agregada pela sua equivalente no SQL Server, por exemplo, Now() no MySQL é getdate() no SQL Server.
Minhas Store Procedures também foram fáceis de converter.
O próximo passo então é fazer o Deploy para o banco de dados através do comando com o mesmo nome no Visual Studio. O Deploy é muito bacana, principalmente quando nosso Database Project faz parte de uma solução e isso agiliza todo o processo de alterar banco de dados e atualizar o Entity Data Model, por exemplo.
Entity Data Model
Ambos os projetos que converti usam uma class library que contém um Entity Data Model. No meu caso, eu sempre gerei ele a partir do banco de dados e qualquer problema ou inconsistência entre o modelo e o banco eu fazia um “upgrade from database” ou simplesmente apagava ele e gerava novamente. Não fosse o fato de eu ter alterado o nome de algumas views, bastaria gerar o modelo a partir do SQL Server e já estaria tudo pronto para os sistemas. Assim, acabei tendo que fazer um replace em alguns arquivos cujos objetos tinha uma nomenclatura “view_clientes” para “ViewClientes”. A geração do modelo usando o SQL Server é muito mais rápido que no MySQL!
Dados
O último passo é migrar os dados do MySQL para o SQL Server.
Neste processo fiz um Data Dump do MySQL usando o MySQL Workbench e marcando apenas as seguintes opções em “Advanced Export Options”:
- complete-insert
- hex-blob
- no-create-info
Os comando de Insert gerados são compatíveis com o SQL SERVER mas algumas substituições nas seqüencias de escape são necessárias:
- Troque \' por '' (dois apóstrofos)
- Troque \" por " (aspas)
- Troque \\ por \
Além disso acrescente no início do script de cada tabela:
SET IDENTITY_INSERT <NomeDaTabela> ON
e no final:
SET IDENTITY_INSERT <NomeDaTabela> OFF
Dependendo do formato de datas gerado pelo backup do MySQL Workbench e do formato existente no SQL Server, será necessário usar o seguinte comando no início dos scripts:
SET DATEFORMAT ymd
No caso acima, o script gerado pelo MySQL tem datas nos formato YYYY-MM-DD e informa ao SQL Server que a conversão de varchar para datetime encontradas deverão assumir que os valores do ano, mes e dia estão na sequencia ymd.
Pronto, minha migração está concluída!
No meu caso esse processo foi fácil, em boa parte, porque meus projetos estão baseados no Entity Framework.
Próximo passo: Code-First!