PHPMongrator – Migrando de MySQL para MongoDB

Depois de procurar, acabei eu mesmo criando uma ferrramenta para migrar dados para o MongoDB.

A necessidade é recorrente, e muito procurada: um desenvolvedor resolve migrar um projeto para o MongoDB que estava em MySQL.  Na hora de migrar, como fazer?

Na verdade converter os dados não é tão complicado quanto parece. Exporte no MySQL para CSV e importe no MongoDB da mesma forma. Só que aí reside uma grande armadilha.

Primeiro, a questão de tipos de dados. Se importar em CSV, todos os dados serão importados no MongoDB como string, seja integer, float ou date. Isto é mau, muito mau.

É importante ressaltar também que existe uma mudança de paradigma. Então tabelas de relacionamento do tipo clássico:

FATURA < ITENS_FATURA > PRODUTO

não tem muito sentido no MongoDB. A DE-normalização, a redundância tratada na aplicação são outras características que dificultam a migração direta. O banco deverá ser repensado.

Considerando estas questões, criei uma ferramenta para ajudar nestas situações (mesmo que seja impossível tratar todas).

Funcionalidades:

  • Executa a migração através de um arquivo de configuração usando o formato YAML (muito simples de editar)
  • Para iniciar a configuração, tem um dumper php-cli que lê o RDBMS e cria um arquivo de configuração para começar
  • Suporte a mapeamento de tipos de dados (realmente importa date, boolean, inteiro, float e string em tipos BSON)
  • Suporte à relações simples com chaves estrangeiras
  • Suporte a relações muitos para muitos com chaves estrangeiras (não é criado no dump automaticamente, mas pode ser configurado na mão facilmente se você quiser)
  • Chaves estrangeiras convertidas ou não para MongoDB Ref (veja arquivo de configuração defatul->use_dbref)
  • Facilmente ignorar tabelas e campos para importar

Vou passar pelas suas funcionalidade com detalhes…

Executa a migração através de um arquivo de configuração usando o formato YAML (muito simples de editar)

O formato YAML é um “XML relaxado” usando um arquivo identado que pode ser facilmente transformado em array no PHP. Ele é muito mais simples de editar do que o XML ou um imenso array do PHP.

Para iniciar a configuração, tem um dumper php-cli que lê o RDBMS e cria um arquivo de configuração para começar

Seria bastante duro fazer o arquivo na mão. Então, o script runDumper.php (que roda via shell) cria o arquivo inicial para você. Ele pode ser suficiente ou então você pode realizar ajustes. Ele solicita dados de conexão do banco de origem e gera o arquivo YAML, que então pode ser personalizado depois.

Para facilitar, é possível listar tabelas e ou campos a serem ignoradas, ou simplesmente apagar sua configuração do arquivo. Relações simples (ID de uma tabela em outra, ou seja, foreign keys) são automaticamente mapeadas SE VOCÊ  FEZ AS CONSTRAINTS corretamente no banco de origem.

Uma facilidade também é poder renomear os nomes de campos de detino (target_name), e, eventualmente, também o tipo, se não atende (target_type).

Suporte a mapeamento de tipos de dados (realmente importa date, boolean, inteiro, float e string em tipos BSON)

O PHPMongrationDriverMysql (que deriva da classe PHPMongrationBaseDriver básica) mapeia os tipos básicos do MySQL para o MongoDB. Desta forma, no arquivo YAML é possível escolher qual o tipo que será utilizado para gravar no MongoDB.

Desta forma, campos date serão gravados como MongoDate, e assim por diante.

Suporte à relações simples com chaves estrangeiras

Este mapeamento é automático se a tabela possui as CONSTRAINTS devidamente configuradas. É possível parametrizar se o relacionamento será realizado utilizando ou não dbrefs do MongoDB (veja arquivo de configuração na sessão “default”).

Para que isto seja possível, todos os dados são importados, a chave original (que é a chave estrangeira original) é importada e somente depois são vasculhados os dados para realizar a referência ao MongoID.

Suporte a relações muitos para muitos com chaves estrangeiras (não é criado no dump automaticamente, mas pode ser configurado na mão facilmente se você quiser)

Como cada desenvolvedor pode utilizar um padrão de nomeclatura diferente para suas tabelas com relacionamentos, seria muito trabalhoso adivinhar diversas situações. Além disso, estes são os casos mais comuns de não conversão de dados para adaptar-se ao novo padrão de modelagem.

Então o caminho optado foi mais simples: a configuração manual quando convém. O MongoDB permite que um campo seja um array, então é fácil referenciar vários documentos como “membros” de um documento “mestre”.

A partir desta idéia, é possível escolher em que collection colocar o relacionamento, ou por redundância colocar nas duas collections.

Exemplo clássico:

user
id
username
password
group
id
description
user_group
user_id
group_id

Pode ser configurado em “user”:

(...)
tables:
  user:
    many_references:
      groups:
        reference_table: user_group
        in_id: user_id
        out_id: group_id
        out_table: group
        out_table_id: id

É possível fazer o mesmo em “group”, ou em ambos.

Importante: está previsto a importação “embedded”, que trataria o caso de haver informações adicionais na tabela de referência (por exemplo: ITENS_FATURA teria quantidade, subtotal, etc).

Chaves estrangeiras convertidas ou não para MongoDB Ref (veja arquivo de configuração defatul->use_dbref)

Explicado anteriormente.

Facilmente ignorar tabelas e campos para importar

O arquivo de configuração permite listar tabelas e campos a serem ignorados na importação. Veja opções default->ignore_tables e tables->??->ignore_columns


Acredito que esta visão geral dá uma boa medida da utilidade da ferramenta. Mas ainda há pontos a melhorar…

Colabore: https://github.com/rafaelgou/PHPMongrator

  • Aleks V2

    Parabéns pela iniciativa!
    Muito legal mesmo, só tem um detalhe: acho que transformar tabelas em coleções não é a melhor abordagem para migrar bases relacionais para MongoDB.
    Já pensou fazer algo, como um programinha que defina que tabelas farão parte de qual coleção e assim migrar para MongoDB?
    Só uma sugestão, se isso já for possível em sua solução, me perdoe a falta de atenção.

    Abrsço
    Ales

  • I see a lot of interesting content on your website.
    You have to spend a lot of time writing, i know how to save you a lot of
    time, there is a tool that creates unique, google friendly articles in couple of minutes, just type
    in google – k2 unlimited content

  • Oma

    Want to copy articles from other websites rewrite
    them in seconds and post on your site, or use for contextual backlinks?
    You can save a lot of writing work, just type in gogle:
    Daradess’s Rewriter