Introdução ao MongoDB: um banco de dados NoSQL

Já faz algum tempo que venho estudando o MongoDB.  Dentro da turma dos SGBDs NoSQL este foi aquele com o qual acabei criando maior simpatia pela sua simplicidade e documentação (apesar de muita gente falar do Apache Cassandra, sua documentação ainda é horrível).

O MongoDB é um banco de dados orientados a documentos. Sendo assim, se você, assim como eu (e 99% dos desenvolvedores) vêm de um ambiente dominado pelo modelo relacional, em um primeiro momento verá este SGBD como um alienígena – o que é incrívelmente empolgante e assustador. Meu objetivo neste post não é ensinar a usar o MongoDB (será assunto do próximo), mas sim expor as principais diferenças entre este e o confortável modelo relacional.

Este assustador (e maravilhoso) “mundo novo”

Para os acostumados com o modelo relacional, o MongoDB se mostrará assustador no primeiro contato porque a maior parte dos conceitos que nos forneciam uma certa sensação de segurança basicamente “desaparecem”. Aqui é obrigatório saber lidar com o medo: conforme mostrarei neste post, há riscos, mas os ganhos os compensam.

Não acho que o modelo não relacional possa ser aplicado a todos os casos, porém é sempre importante conhecer mais de um paradigma para que possamos no mínimo ampliar nossos horizontes quando nos deparamos com situações que fogem da nossa zona de conforto (e o MongoDB pode ser bastante desconfortável neste primeiro momento).

Não há registros, mas documentos

Algo sempre me incomodou no modelo relacional: com ele tentamos representar o mundo real (que é n-dimensional) usando uma abordagem bidimensional. Tudo o que eu for representar em minhas tabelas possui apenas duas dimensões: linhas e colunas. É verdade que podemos representar quantas dimensões quisermos no modelo relacional a partir de relacionamentos, porém sempre fica aquela sensação de se estar “forçando a barra”.

Além disto, por mais bem feita que seja o processo de análise, sempre há a possibilidade de posteriormente mais um atributo ser encontardo. O mundo é um ambiente complexo: acredito que para representá-lo, precisamos também de uma terminologia complexa.

No MongoDB, o equivalente aos registros são os documentos, que utilizam a sintaxe JSON. A melhor maneira de se ter um feeling do que quero dizer é ver o bicho. Sendo assim, observe o código abaixo:


Kico = {
nome: "Henrique Lobo Weissmann",
apelido: "Kico (ou seria este o nome?)",
cidade: "Belo Horizonte"
}

Eu criei um documento chamado kico que possui 3 atributos: nome, apelido e cidade. Repare que em momento algum defini o tamanho máximo de cada atributo, regras de validação ou qualquer tipo de restrição. Em seguida, se quiser armazená-lo em um banco de dados, bastaria executar o código abaixo:


db.kicodb.save(Kico)

Neste caso, eu estaria armazenando o documento Kico no banco de dados kicodb. Agora, observe o código abaixo:


Nanna = {nome:"Maria Angélica Alvares da Silva e Silva",
apelido:"Nãnna",
esposaDo:"Kico",
cidade:{nome:"Belo Horizonte", estado:{nome:"Minas Gerais", pais:"Brasil"}},
caes:[{nome:"Fraude", raça:"Pinscher?"}, {nome:"Zé", raça:"Schnauzer"}]}

db.kicodb.save(Nanna)

Repare que um registro com estrutura completamente diferente foi incluida no banco de dados. Até o atributo cidade é diferente. Enquanto no registro “Kico” eu tenho apenas uma string, no objeto Nanna eu tenho um outro documento. Outro ponto interessante: repare que eu tenho inclusive uma coleção associada ao objeto Nanna.

E tudo é mesmo assim salvo no mesmo banco de dados sem problema algum. Na realidade, eu poderia armazenar até o registro abaixo sem problemas:


esquisitao = {quantidade:34, poemaFavorito:"Batatinha"}

Como pode ser visto, não há regras de validação rígidas: qualquer tipo de documento pode ser armazenado no banco de dados. Claro: na prática somente objetos semelhantes são armazenados na base de dados, porém é bacana saber que se um dia aparecer algum novo atributo, poderemos inclui-lo apenas nos documentos aonde o mesmo é necessário, ao contrário do modelo relacional, aonde uma coluna se aplica a todos os registros.

Desvantagem: o desenvolvedor precisa ficar esperto para que suas bases de dados não virem um “samba do criolo doido”

Vantagens:

  • Finalmente você se livrou de uma abordagem bidimensional e pode representar objetos do mundo real como realmente são: complexos e únicos.
  • Caso no futuro surja algum caso no qual novos atributos apareçam, você pode aplicá-los somente aonde é necessário, e não em todos os casos, como no modelo relacional, aonde normalmente cria-se uma nova “coluna” na tabela relacionada

Redundância de dados máxima

No modelo relacional somos o tempo inteiro incentivados a reduzir ao máximo possível a redundância de dados. Aliás, os relacionamentos existem justamente para isto. E é um modelo que inegávelmente funciona muito bem. Já no MongoDB a situação é inversa: não há relacionamentos, e a duplicação de dados, pelo que pude observar é até incentivada.

Dê uma olhada no código abaixo:


pessoa1 = {nome:"Peçonhento", cidade:{nome:"Belo Horizonte", estado:"MG"}}

pessoa2 = {nome:"Zequinha", cidade:{nome:"Belo Horizonte", estado: "MG"}}

pessoa3 = {nome:"Joca", cidade:"Lagoa Santa"}

pessoa4 = {nome:"Complexado", cidade:{nome:"Rio de Janeiro", estado:{nome:"Rio de Janeiro", pais:{nome:"Brasil"}}}

Lembre-se de que aqui não há tabelas: há coleções de documentos. Em cada documento armazeno os dados da forma que eu quiser. Eu poderia criar uma coleção contendo apenas cidades e em seguida criar um relacionamento entre duas ou mais coleções distintas, é verdade (foge do assunto deste post), mas isto iria contra a idéia básica por trás do modelo orientado a documentos.

A idéia básica aqui é a de que um documento deve ser auto-contido, ou seja, isolado já deve conter todas as informações de que necessita. Por que isto? Simples: porque assim você ao invés de fazer uma consulta com vários joins como é o caso do modelo relacional executa uma única consulta, que já te retorna o documento inteiro. Resultado: mais performance.

Desvantagem: se você quiser alterar todos os registros relacionados a uma unidade semântica, precisa tratá-los um a um

Vantagem: maior performance. Uma única consulta já te retorna tudo o que você precisa saber a respeito do documento. Esta é uma das razões pelas quais vêm sendo adotado em projetos que exigem alta performance.

Concluindo

Estas são as duas principais diferenças (que só são vantagens de acordo com o caso) que vi no MongoDB (do modelo baseado em documenots na realidade) com relação ao modelo relacional. É aplicado a todos os casos? Óbvio que não.

O importante a meu ver é sair da área de conforto do modelo relacional: isto, como mencionei, amplia os nossos horizontes, faz com que vejamos outras possibilidades além de tabelas para armazenar nossos dados. Fico assustado quando topo com desenvolvedores que só conseguem desenvolver algo que envolva tabelas, colunas e registros. Aliás, a grande vantagem que vejo nesta “moda” de modelos noSQL é justamente esta: a exposição de “novos” paradigmas a um mundo dominado pelo modelo relacional, que só considero ruim quando tomado como a única alternativa viável pela maior parte das pessoas.

Este post é fundamental para que eu possa partir para os próximos, nos quais exporei como usar o MongoDB e, ainda mais importante, como aplicá-lo com Groovy e Java. Grande abraço!

Ah, quer baixar o MongoDB? Este é o site oficial: http://www.mongodb.org

78 comentários em “Introdução ao MongoDB: um banco de dados NoSQL”

  1. Parabéns pelo post!! Assunto interessante e bem escrito. Não conhecia o MongoDB e vou ler mais a respeito. Abração .

    1. hahahahahahahahahahhahhaha, “A melhor maneira de se ter um feeling do que quero dizer é ver o bicho.”

      “o desenvolvedor precisa ficar esperto para que suas bases de dados não virem um “samba do criolo doido””
      ri muito .. ahahaha.. q isso gente.
      Bom summary.

          1. Kico (Henrique Lobo Weissmann)

            Oi Andressa, me desculpe pelo mal jeito. É que realmente na hora (estava exausto) não havia entendido o seu comentário.
            Mil desculpas: realmente não queria soar grosseiro de forma alguma.

  2. Excelente post!
    É bom ver que podemos ampliar nossos horizontes e experimentar algo novo sem medo de sermos mais eficiente!
    Parabéns!

  3. Olá, essas características não se apresente somente ao MondoDB, mas a qualquer um dos NoSQL que são armazenados como documentos (CouchDB e Apache Cassandra).

    :)

    1. Oi Cairo,

      mas isto está claro no texto, não? A diferença é que estou aplicando estes conhecimentos a um SGBD específico. :)

  4. Incrível como isso me faz lembrar XML e suas marcações. Mas o melhor de tudo é que é “palpável” aos olhos cada linha que você lê. Sem abstração para conseguir entender e enxergar o que há numa base de dados.

    1. Eu também tenho o mesmo sentimento Daniel. E não é a toa, porque o que estamos vendo é um formato de intercambio de informações assim como o XML né?

      Eu sinceramente acho o XML uma das maiores invenções de todos os tempos. É uma pena que o mal uso do mesmo tenha queimado tanto o seu filme entre os desenvolvedores, porque na minha opinião, é uma tecnologia simplesmente fantástica

  5. Pessoal, o único ponto que realmente me deixa desconfortável é a questão da redundância, mas vendo no dia-a-dia como os projetos de TI se desenrolam (ou melhor se enrolam) no ambiente corporativo uma solução como essa nos daria a flexibilidade exigida pela instabilidade dos requisitos com que temos que lidar.

  6. Fazer um sistema de log usando um NoSQL faria bastante sentido, inclusão e apenas consulta.

    Vou fazer alguns testes para ver suas vantagens e desvantagens em uma aplicação do tipo.

    1. Mas ai só se for um log ultra complexo né? Porque arquivo texto pra coisas simples ainda é imbatível não? Qual a vantagem em usar um banco de dados ao invés de arquivos simples para log?

      Da uma olhada nisto: http://www.splunk.com – desconfio que é exatamente o que você está procurando. :)

  7. Roberto Amorim

    Muito bom artigo. Ele expõe de maneira prática o que é esse “alienígena” que chega derrubando algumas “leis fundamentais” sobre bancos de dados. O legal disso é que inova em uma área na qual a ortodoxia estava ganhando rumos assustadores. Se o mundo real não pudesse adaptar-se ao “schema” e aos “roles” certos, o mundo real estaria errado.
    Parabéns pelo artigo com sua linguagem clara e objetiva.

  8. Mas o que seria o kicodb?
    Um documento que devo criar manualmente ou existe um comando para isso?
    Estou iniciando o estudo.
    Obrigado.

    1. Oi Jr,

      kicodb é o nome do banco de dados. No MongoDB, quando você executa um comando como por exemplo db.[nome do banco].save(), caso o banco de dados ainda não exista, ele é criado automáticamente.

      No caso, eu estava salvando/mandando criar um banco de dados chamado kicodb.

  9. Parabéns! Gostei do Post, bem explicado, quem já viu XML tem mais facilidade de entender. Gostei das vantagens e não gostei das desvantagens, hehe! Ter que mudar um-a-um os valores de campos “atributos” que são iguais deve dar um trabalhinho, no mais, gostei muito.

  10. Pingback: Brincando com o MongoDB | Márcio Fábio Althmann

  11. Muito bom o post, realmente não conhecia este DB. Mas só refletindo sobre o que você disse sobre performance, isso funciona para cadastramento, mas quando se pensa em relatórios, onde ao invés de extrair apenas as colunas que interessam de cada join, e de forma indexada, nós teríamos que extrair todo o documento antes, e tratar caso a caso, teríamos uma relação inversa de performance. Sem falar que para manter índices, acredito que seja necessário voltar ao conceito do DBase… até fico pensando se a abordagem deste DB não seria idêntica à do Tamino, que é baseado em XML.
    Abraço!

    1. Oi Rodrigo,

      fico feliz que você tenha gostado. Sabe, você tem razão: eu também não sei como seria o uso do MongoDB para a geração de relatórios tradicionais como os que fazemos com SGBDs relacionais.

      É aquele negócio né? Cada macaco no seu galho. A gente deve usar estes bancos NoSQL para alguns casos (tabelas MUITO esparsas é um bom indício de que você deve usar) e relacionais para outros.

      Na prática, eu acredito inclusive na sinergia entre os dois modelos, usando um quando o outro não atende e vice-versa.

  12. Muito bom! Por vezes o modelo relacional me sufoca, literalmente falando, com toda essa preocupação com normalização, redundância e tudo. Se bobear, a menor das preocupações é em representar o mundo real… Mas enfim, isso não é uma crítica ao paradigma relacional (ele ainda é meu ganha pão!), é mais um desabafo – um desabafo alegre ao ler essa novidade do post. Minha cabeça já ferve com as possibilidades!

    E falando em relatórios, vamos deixar um pensamento no ar. Quando dizemos que esse modelo não é prático para relatórios, talvez estejamos pensando em relação a eles tão tradicionalmente quanto o próprio modelo relacional… ;)

    1. Oi Daniel, fico feliz que tenha gostado.

      E cara… seu último comentário vai DIRETO ao ponto! MUITO bem observado. Não havia pensado nisto ainda. Acho alta (99%) a probabilidade de você ter razão. :)

  13. Parabens pelo ótimo post. Estou começando a estudar banco NoSQL e minha duvida é sobre: Se usar um banco convencional (sql) onde foi definido que as tabelas não possuem relacionamento, ou seja, a tabela possui campos: cidade, estado, etc. em uma consulta não terá a mesma performance do banco NoSql já que não é necessário unir várias tabelas?

    1. Oi Ed, valeu!

      Cada caso é um caso, mas eu costumo observar o seguinte fato ao fazer minhas escolhas: minhas tabelas estão ficando muito esparsas, isto é, há muitas colunas que raramente estão sendo preenchidas? Se a resposta for sim, ai é sinal de que algo NoSQL pode ser uma alternativa interessante.

      No caso que você falou, de uma tabela sem relacionamentos, de fato: você tá certo. A performance seria a mesma ou, no máximo, muito próxima. Além do quê, é uma situação ideal para SGBDs relacionais né? E neste caso, os bichinhos são 100% otimizados pra isto.

      Aliás, neste caso, nem teria muito porquê usar um banco NoSQL se trata-se de algo que fácilmente pode ser representado no modelo tabular né?

      Outro fator que uso como indicador: meu objeto de domínio consegue ser 100% representado em uma metáfora bidimensional como uma tabela? Se sim, banco relacional é uma excelente opção. Se não, e eu tiver tabelas esparsas ou relacionamentos MUITO complexos, NoSQL começa a se mostrar viável.

      1. Ola,
        O que seria esse complexo que vc diz ? … ou seja.. pra vc quando que os joins começam a ficar complexos ?

        1. Kico (Henrique Lobo Weissmann)

          Oi Diego,

          sua pergunta é excelente e vai ser o assunto de um post futuro meu.

          Vamos lá: muitas vezes você se depara com situações nas quais precisa fazer uma série de joins em suas tabelas no banco de dados relacional. Quando redundância de dados é um problema para você, ou seja, quando precisa ter apenas um registro para representar uma entidade, o modelo relacional É o que você deve adotar.

          No entanto, há situações nas quais você não liga para o fato de haver redundância de dados, como é o caso do MongoDB. Nestes casos, o join acaba dando lugar aos documentos embarcados, cuja obtenção a partir do MongoDB acaba se tornando muito mais simples e eficiente.

          Este é o ponto então: unicidade dos registros? Modelo relacional. Não precisam ser únicos? documental talvez te atenda.

          E digo mais: se você observar que precisa o tempo inteiro ficar fazendo referências entre documentos, é sinal de que deve adotar uma base de dados relacional o quanto antes. O maior erro que vejo na adoção do banco de dados documental é tentar recriar o modelo relacional neste.

  14. karen.mikaela

    Parabéns pelo post, estou iniciando meus estudos com NoSql e gostei muito da introdução aqui apresentada. abraços.

  15. Otimo Post, porém gostaria de saber com identificar um documento neste tipo de banco, tentando uma semelhança a PK do banco relacional.

  16. Oi Wilian, que bom que gostou. Valeu!

    Depende da sua estratégia, pode ser por ObjectID ou por algum atributo específico também.

  17. Olá Kico,

    Fino no grão teu post, excelente cara meus parabéns!
    Achei muito interessante a abordagem do MongoDB me parece bem simples utilizar vou realizar alguns testes.

  18. Poxa Kiko, você fez tudo parecer fácil. :) Obrigado mesmo pelo post. Para um desenvolvedor front-ender como eu, fica bem mais fácil quando está tudo bem escrito e explicado de forma simples.
    Continue o bom trabalho!

    um abraço

  19. Adorei o tópico gostaria de saber se para games? se esse banco seria mais adequado e como ele se comporta na nuvem ?

  20. Parabéns pelo post. Mas olha….Ufaaa!!! Realmente da um nó, mas é excelente poder ver novas formas de desenvolver. Já estou fazendo alguns testes em C#.NET e Java, estou gostando dos resultados, apesar de ter que pensar diferente, é muito empolgante! É uma grande quebra de paradigma, perspectiva nova. Vale muito a pena entender esse modelo de BD.

  21. Anderson V.

    Muito bom o post, talvez eu tenha pego o bonde andando, mas acho que vale ainda um comentário.

    Veja bem, eu gostei muito quando em um dos comentários acima você falou que em usar um SGBD relacional juntamente com um orientado a documentos. Isso sim sería realmente “revolucionário” no meu ponto de vista.

    Entendo que resumir o mundo em tabelas relacionadas seja uma forma pobre para esse processo, porém há de se observar que ainda que você trabalhe com nosql vc irá necessitar de exatidão, precisão, consistência, certeza! O sistema não pode errar.

    JSON, na prática é um array. Então para que eu quero uma coleção de arrays completamente distintos? Vamos supor que vc queira criar uma collection em um db relacional. Faremos assim:

    table: test_collections
    field: json_code

    Pra ficar mais claro…

    INSERT INTO test_collections( json_code) VALUES (‘{nome: “anderson”, cidade: “recife”}’);

    Então dentro de um relacional e com poucos algorítimos sería possível eliminar a necessidade real de um db orientado a documento. Claro, óbvio, que existe a questão do desempenho, onde o Mongo é MUITO melhor que o MySQL, por exemplo, em quase todos os quesitos.

    Então, realmente, se não for por questões de desempenho, eu não vejo muita ultilidade no NoSQL. Me fala que eu to errado, por favor! hehehehe

    Abraço e parabéns pelo artigo!

    Realmente, não acho que os nosql da vida irão “derrubar” os relacionais de forma nenhuma. Talvez eu esteja sendo alienado, não sei. Você não acha que o mongo e outros nosql são inferiores aos relacionais?

  22. Carlos Daniel

    Realmente é uma nova proposta, mas tenho grande dificuldade de ver a vantagem sobre o modelo relacional quanto estou trabalhando por exemplo com diferentes tabelas, a exemplo saber o saldo de compras dos clientes por estado. Pelo que soube não hã “join” nos NoSQL e a questão do banco validar dados, a exemplo um cadastro que não aceita menor de idade, no Firebird que uso posso por exemplo criar uma regra onde ele confronta o valor do dado já considerando a data no servidor… em outras palavras o SGBD por ter as tantas regras e formalidade me permite passar à ele as validações, reduzindo assim a demanda de processamento nos terminais.

    Bom enfim, entendo que o NoSQL é para ser usando em situações tipicas como blogs, mas dificil, pelo menos agora, ver ele em um ERP onde padrões e formalidade são necessidades que evitam redundância de dados e inconsistência nos relacionamentos.

    Abraços aos amigos

    1. Kico (Henrique Lobo Weissmann)

      Oi Carlos, eu concordo com você. Na realidade, até hoje, encontrei poucas situações que justificassem o uso do MongoDB: basicamente apenas em situações nas quais eu topava com tabelas muito esparsas ou casos em que os atributos variassem demais de registro para registro.

      Tirando isto, o modelo relacional resolve bem os nossos problemas: de fato, se eu quero fazer um relatório gerencial, o formato tabular vêm bem mais a calhar do que o documental.

      Acho que a melhor alternativa é mesclar os dois mesmo: relacional para uma parte, documental ou gráfico para outra.

  23. Pingback: Iniciando a vida com BigData – mongoDB | JOSÉ LUCIANO DA SILVA

  24. Marcio Vinicius

    Parabéns pelo artigo, você me ajudou bastante agora que estou começando com o MongoDB.

    Como você mesmo disse: É assustador e MARAVILHOSO ao mesmo tempo. Simplesmente estou adorando.

    Valeu!

    1. Kico (Henrique Lobo Weissmann)

      Opa, bacana que tenha gostado.
      Mas uma dica: opte por um modelo de persistência misto.
      Coloque a parte que requeira relacionamentos fora do mongodb.

      1. Marcio Vinicius

        Opa valeu pela dica, muito interessante.

        Abraços estou acompanhando seu site.

  25. Fernando sousa

    Estou começando com Banco de dados NoSql e gostaria de saber onde encontrar uma base de dados para testes no MongoDB sendo que esta base como ja sabemos deve ter um grande volume e variabilidade….obrigado pessoal.

    1. Kico (Henrique Lobo Weissmann)

      Oi Fernando,

      sinceramente não sei viu. Talvez o melhor a fazer seja você mesmo criar esta base de dados usando algum script ou algo similar. Nunca vi alguém fornecendo uma base assim para download.

  26. Oi Kiko, me diz uma coisa, HOJE como você vê a adoção do MongoDB para sistemas ERP por exemplo.

    Relacionamento entre registros? (Hoje faço “manualmente”)
    Uma coisa que eu não sei se é vantagem ou desvantagem

    imagine um registro onde temos 1-n (Cliente e Contatos), sendo que contatos fica como emmbeded, blz, se eu trouxer um cliente ele já retorna o contato, mas se eu quiser trazer uma lista de todos os clientes? ai vai retornar todos os contatos, fico na dúvida se compensa adotar ele no projeto novo ou modelo relacional, problema do modelo relacional é atualização de squema (hoje temos migrations) mas fantástico mesmo é o schema free

    i ai, o que você acha nos dias de hoje, levando em consideração que já se foi mais de 4 anos desse post!

    1. Kico (Henrique Lobo Weissmann)

      Oi Rodrigo,

      bom: eu sempre fui a favor de uma abordagem mista. Se você pensa em documentos se relacionando, MongoDB não é uma boa opção para você, mas sim o modelo relacional.

      Ano passado escrevi algumas coisas sobre isto: https://devkico.itexto.com.br/?p=1621

  27. Leandro Gomes Machado

    Excelente post!!

    Realmente tirou minhas dúvidas a respeito do MongoDB e vou procurar mais artigos e livros sobre esse SGBD NoSQL.

    Parabéns.

  28. É bem iteressante para quem nao preciso de ACID:
    Atomicidade
    Consistência
    Isolamento
    Durabilidade
    Aplicaçoezinhas futeis vai ser muito bom. Ja para um aplicacao onde os dados sejam importante como as para grandes impressas isso é um piada.

  29. Pingback: NoSQL é tão problemático quanto parece? - banco-de-dados nosql - Perguntas e Respostas

Deixe uma resposta

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.

Rolar para cima