Arquitetando com MongoDB - Overview
Arquitetar um banco com o MongoDB é fácil, no entanto a flexibilidade que ele nos dá sobre a estrutura pode ser um grande problema, pois um projeto pode priorizar a consistência sobre a performance ou vice-versa. Nesse artigo demonstrarei os conceitos necessários para arquitetar um banco usando o MongoDB.
Conteúdo completo aqui: Introdução à modelagem de dados com o MongoDB.
Ao arquitetar um banco de dados com o MongoDB devemos equilibrar as necessidades da aplicação, performance e padrões de acesso aos dados. Devemos pensar em termos de entidades (documentos) e o relacionamento entre elas, através de referência direta (links) ou documentos encadeados. Além disso, é necessário entender alguns conceitos específicos da engine do MongoDB.
###Modelo de documentos linkados (normalizado) Essa é uma arquitetura bem próxima ao modelo relacional e, portanto, se usada em todo o banco, podemos obter sua normalização. Essa abordagem, contudo, possui efeitos negativos na performance das queries, visto que os relacionamentos se dão entre vários documentos.

#####casos de uso:
- quando for necessário representar relações N:N (vários para vários)
- quando tiver um relacionamento 1:N (um para vários), no qual N é um número muito grande de documentos
- quando a permormance (tempo e consumo de memória) não for priorizada
- sempre que for necessária a normalização dos dados
###Modelo de documentos encadeados (desnormalizado) Encadear documentos desnormaliza a estrutura do banco, porém facilita a inserção e recuperação de dados correlacionados, demandando menos operações CRUD, pois são guardados em um mesmo documento. Essa abordagem, no entanto, pode ser perigosa se o tamanho ou a quantidade de documentos filhos crescer a ponto de consumir quantidades superiores a 1MB de memória por documento para uma simples operação find(), por exemplo.

#####casos de uso:
- quando existir um relacionamento 1:1 (um para um)
- quando existir um relacionamento 1:N (um para vários), no qual N é um número pequeno de documentos
###GridFS Documentos maiores que 16MB (limite de um documento BSON), devem ser armazenados usando o GridFS, que separa um documento em várias partes, a fim de carregá-lo parcialmente em memória. #####casos de uso:
- sempre que for preciso armazenar arquivos maiores que 16MB, como textos longos, imagens, videos…
- quando quiser acessar um arquivo sem carregá-lo por completo na memória
###Sharding (escalonamento horizontal) Se o banco tiver que lidar com quantidades massivas de dados, é possível que ele seja distribuído em várias instâncias, a fim de otimizar sua performance. Isso pode ser conseguido por técnicas de sharding, escalando o banco de dados horizontalmente. Ao contrário dos bancos relacionais, o Mongo é capaz de realizar essa tarefa de forma bastante conveniente, facilitando a vida do DBA.
###Uso de índices
As queries podem ter sua performance maximizada usando a chave (_id) para realizar as operações de CRUD. É possível (e imprescindível) também criarmos índices em um ou mais campos, assim como fazemos com bancos relacionais. O MongoDB facilita o processo de tuning do banco, principalmente por prover informações detalhadas sobre a eficiência das queries através do método explain
.
###Coleções muito grandes Se uma coleção crescer muito, é preferível que ela seja repartida em outras coleções. Por exemplo uma coleção de log, que pode ser repartida em log_usuarios e log_sistema.
###Arrays muito grandes Se um array começar a crescer rapidamente, é preferível que ele seja repartido e guardado em outros documentos. Isso pode ser feito, por exemplo, referenciando o próximo documento através de um campo “prox”, que guarda o _id do documento que guarda o próximo pedaço do array.
###Ciclo de vida dos dados O MongoDB pode dar uma data de expiração para um documento (Time to Live) ou usar o algoritmo FIFO para eliminar documentos antigos (capped collections). Isso pode maximizar a performance do banco, caso seja possível eliminar documentos automaticamente.
Com esses conceitos em mente, é possível arquitetar um banco com eventual consistência (priorizando performance) ou sempre consistente (priorizando a normalização). Em próximos artigos mostrarei como arquitetar um banco para suprir diferentes tipos de requisitos.
Veja vários exemplos de arquiteturas usando MongoDB.