Nem tudo é relacional

Comments
.net binaryformatter modelo relacional serialized lob
01 October 2008

Esses dias me peguei pensando em um costume interessante que temos. Quando digo "nós", falo de min e das pessoas com as quais já trabalhei nesses 4 anos que atuo com .NET. Fomos acostumados, em se tratando de persistência em banco de dados, de sempre utilizar modelo relacional pra qualquer tipo de armazenamento de objeto. O problema é que nem sempre isso é necessário e acabamos perdendo ou tempo em codificação ou desempenho ou espaço em disco.

A idéia de banco de dados orientado a objetos sempre me agradou e acho uma pena não ter chegado ao mainstream. No entanto o conceito de armazenar o grafo todo de objetos é muito interessante em algumas situações. Vou usar um exemplo que talvez não seja o melhor, mas deve passar a idéia.

Imagine um cadastro de cliente com diversas entidades relacionadas: diversos endereços, vários telefones para contato, dependentes, etc.

Modelo de Classes

Normalmente criaríamos uma tabela para cada uma das entidades e essas tabelas teriam uma referência (FK) para a tabela principal de clientes:

Modelo de Dados normalizado

Se considerássemos que um endereço ou automóvel pudesse pertencer a mais de um cliente a coisa ficaria ainda mais complicada e teríamos que criar tabelas de relacionamento N:M.

Para que o exemplo seja útil, vamos considerar que nesse sistema não fosse possível efetuar pesquisas utilizando como filtro nenhuma dessas entidades (em um sistema real é óbvio que requisito é um absurdo) e só seria disponibilizada uma funcionalidade de busca por meio de código (id). Mesmo com esse requisito, como pensamos sempre em de forma relacional o caminho natural seria criar o modelo de dados acima e armazenar tudo bastante normalizado.

No entanto existe outra opção que em determinados casos é muito interessante. Guardar o objeto inteiro no banco.

Em .NET, por exemplo, bastaria criar um modelo simples de dados contendo o idCliente e um campo que armazene binário (varbinary em SQL), serializar o objeto e pronto.

Modelo de dados mais simples

public Cliente Consultar(int codigoCliente)
{
    //Recupera do DB
    byte[] clienteSerializado = DaoCliente.ConsultarPorCodigo(codigoCliente);
    //Devolve o objeto deserializado
    return this.DeserializarObjeto<Cliente>(clienteSerializado);
}

public void Salvar(Cliente novoCliente)
{
    //Serializa o objeto
    byte[] clienteSerializado = this.SerializarObjeto<Cliente>(novoCliente);
    //Guarda o cliente no DB
    DaoCliente.Inserir(novoCliente.Codigo, clienteSerializado);
}

private byte[] SerializarObjeto<T>(T objeto)
{
    MemoryStream ms = new MemoryStream();
    BinaryFormatter formatter = new BinaryFormatter();
    formatter.Serialize(ms, objeto);
    byte[] objetoSerializado = ms.ToArray();
    ms.Close();
    return objetoSerializado;
}

private T DeserializarObjeto<T>(byte[] objetoSerializado)
{
    MemoryStream ms = new MemoryStream();
    BinaryFormatter formatter = new BinaryFormatter();
    ms.Write(objetoSerializado, 0, objetoSerializado.Length);
    ms.Position = 0;
    return (T)formatter.Deserialize(ms);
}

Dessa maneira, sempre que precisarmos, já iremos ter o objeto completo e não seria necessário executar diversas instruções SQL ou stored procedures e muitas chamadas ao banco. Iriamos apenas executar uma chamada que nos retornaria o objeto completo e pronto para uso.

Essa é uma solução diferente e que pode ser útil em alguns cenários, principalmente se você não utiliza nenhum framework ORM. Contudo, é importante verificar todos os requisitos com bastante cuidado, com essa solução corremos o risco de ficar com dados desatualizados e perdemos a possibilidade de efetuar buscas por campos que estejam dentro dos objetos armazenados.

Acho muito legal encontrarmos formas diferentes de fazer as mesmas coisas que estamos habituados. É uma maneira muito eficiente de aprendizado e conhecimento das nossas ferramentas.

O que você acha?

Editado: sem saber, acabei descrevendo o pattern Serialized Lob já catalogo pelo Fowler em seu livro PoEAA. O Bruno achou e comentou o post colocando este link. Valeu! :D


<< Novo Microsoft Architecture Guide lançado
My Job Went to India: Resenha>> 
comments powered by Disqus
tucaz

tucaz

.NET Software Developer
About
All Posts
RSS
@tucaz
GitHub