NoSQL: Saiba quais são os tipos e suas características
O Fantástico Mundo do NoSQL
| by Alexandre Silva
Os Bancos de Dados Relacionais dominam a maior parcela do mercado nas grandes organizações, e por uma boa razão. Além de atenderem as necessidades das regras de negócios, existe um leque gigantesco de ferramentas que apoiam esse modelo e milhares de profissionais qualificados para implementar e manter esses sistemas.
Mas se os bancos de dados relacionais dão conta do recado, por que existe todo esse hype para cima dos bancos chamados no cycle ou "NoSQL" ou simplesmente non-relational databases (Banco de Dados Não Relacionais)?
Bem, devemos isso graça a alguns pontos: A galera das Metodologias Ágeis de Desenvolvimento; A necessidade de criar aplicações flexíveis e escaláveis horizontalmente; Os Bancos de dados não normalizados e o descontentamento com a primeira resposta certa.
Primeira resposta certa?
Para cada pergunta/ação na construção de um sistema, existem diversas respostas certas (tecnologias) que atendem a solução naquele momento. Contudo, a primeira resposta certa — que normalmente é a modelagem em um banco relacional — é dada como a resposta final pelos tomadores de decisão. E quando as empresas necessitam abusar do volume absurdo de dados capturados hoje em dia, para criar aplicações gigantescas, descentralizadas, escaláveis, baratas e acessíveis em qualquer lugar do mundo, elas acabam se esbarrando na limitação da tecnologia escolhida inicialmente (e é muito caro e/ou complexo escalar um banco relacional). Antigamente uma tabela de 1 milhão de dados já era considerado uma tabela muito grande. Hoje em dia o Facebook possui 2 bilhões de usuários, e amanhã só temos uma certeza: teremos mais e mais dados para armazenar.
Não se contente com a primeira resposta certa!!!
Mas caro leitor, meu objetivo aqui não é definir para você o que é NoSQL (até por que a criação do nome foi uma brincadeira que gerou um baita marketing) e muito menos dizer que NoSQL é melhor que Banco de Dados Relacionais (cada um no seu quadrado). O que eu quero aqui é ajudar a você a se interessar nos diversos tipos de bancos NoSQL, citando algumas características interessantes e dando alguns exemplos de casos de uso, para que no futuro você possa se aprofundar mais neste fantástico mundo.
A principal diferença entre os bancos relacionais e os bancos não relacionais são os tipos de dados. Embora haja dezenas de bancos de dados não-relacionais, eles se enquadram em uma das seguintes categorias:
Baseados em Documentos (Document Model)
Enquanto os bancos de dados relacionais armazenam dados em linhas e colunas, os bancos baseados em documentos armazenam dados em forma de documentos. Esses documentos tipicamente usam uma estrutura parecida com o JSON (JavaScript Object Notation). Desta forma um Documento é bastante alinhado com a programação orientada a objetos, pois cada Documento é efetivamente um objeto. Cada documento contém um ou mais campos, que podem armazenar um conteúdo tipado (como uma string, uma data, um inteiro, um array, etc).
Uma das vantagens dos bancos orientados a documentos é a flexibilidade da modelagem: Cada documento pode possuir campos diferentes. Isso pode ajudar muito na modelagem de dados polimórficos (um e-commerce por exemplo, onde eu possuo diversos produtos com características diferentes).
Exemplos: MongoDB e CouchDB
Baseados em Grafos (Graph Model)
Banco de dados baseados em Grafos utiliza uma estrutura de Grafos contendo arestas, vértices e propriedades para representar um dado. Na essência, esses bancos são modelados como uma rede de relacionamentos entre elementos específicos. Embora o modelo de Grafo ser contra intuitivo e ter uma curva de aprendizagem maior, pode ser útil para aplicações bastante especificas, como quando informações sobre a inter-conectivadade ou a topologia dos dados são mais importantes, ou tão importante quantos os dados propriamentemente ditos. Cabe ressaltar que quando você precisa de uma flexibilidade para modificar os dados no futuro, é mais fácil modificar a estrutura em uma Grafo do que nos outros modelos.
Exemplos: Neo4j e Giraph
Baseados em Chave-Valor (Key-Value Model or Wide Columns Stores)
Considerada a modelagem mais básica de todos os tipos. Cada item armazenado no banco de dados possui um atributo (ou chave) e seu respectivo valor. O valor só pode ser obtido através de sua chave. Esses tipos de Bancos são ótimos quando a consulta por um dado só necessita de uma Chave simples, o que o torna bastante otimizado e escalável.
Dentro dessa categoria, ainda se encontram os Wide Columns Stores (ou mais conhecido como Matriz Esparsas — Excel é um ótimo exemplo disso). Esses bancos são mais interessantes para processamento analítico online (OLAP).
Exemplos: Riak e Redis (Key-Value) e Cassandra e BigTable da Google (Wide Column).
Consultas dos Dados
Cada aplicação possui uma particularidade e suas regras de negócios para realizar as inserções, atualizações e consultas nos bancos de dados. E isso é um fator muito importante para a tomada de decisão. E a maior diferença entre os Bancos relacionais e não relacionais está na capacidade de consultar os dados de forma eficiente.
Bancos baseados em documentos possuem uma flexibilidade imensa para consultas em qualquer campo do documento, e utilizam sistemas de indexação bastante robustos para otimizar as consultas. O MongoDB, por exemplo, possui indexador de funções geométricas e de texto. As consultas em bancos como MongoDB ou CoachDB não fazem você ficar com saudade do bom e velho SQL (desde que o modelo esteja bem construído).
Os bancos de Chave e Valor são bastante otimizados em relação a consultas, mas são bastante limitados em sua essência para consultar os dados e pode causar um esforço a mais de desenvolvimento para montar sua regra de negócio. Possuem um custo bastante elevado para atualizações também (pois eles tem uma característica de sempre inserir o dado indexado).
Imagina você em um banco relacional realizar a seguinte pergunta: Quais cidades foram visitadas anteriormente por pessoas que viajaram para o Cascavel (No Paraná! Não no Mato Grosso do Sul!)? Seria uma consulta muito complexa devido a necessidade de múltiplas junções, o que pode acarretar uma diminuição no desempenho da aplicação. Porém, por meio dos relacionamentos inerentes aos grafos, estas consultas tornam-se mais simples e diretas.
O Tradeoff Arquitetural
Um banco de dados relacional se baseia em um conjunto de propriedades chamada ACID (Atomicidade, Consistência, Isolamento e Durabilidade). De maneira simplificada, podemos dizer que este conjunto de propriedades garantem confiabilidade nas transações a fim de garantir a integridade do dado.
Já os bancos NoSQL seguem o padrão BASE (Basically Available, Soft-State e Eventually Consistent). Resumindo: Uma aplicação funciona basicamente todo o tempo, não tem de ser consistente todo o tempo (Estado Leve) e o sistema torna-se consistente no momento devido (Eventualmente Consistente).
Mas como comparar o tradeoff (o que vamos ganhar e o que vamos perder) arquitetural em uma escolha de um banco relacional e um banco NoSQL? Dr. Eric Brewer mostra isso com o Teorema do CAP. Ele afirma que é impossível que o armazenamento de dados distribuído (o escalonamento horizontal do NoSQL) forneça simultaneamente mais de duas das três garantias seguintes:
Consistency (Consistência): Um sistema é considerado consistente se depois da atualização de um dado, todos os usuários que tem acesso a esse dado, possam acessá-lo em tempo real;
Availability (Disponibilidade): Se é assegurado que o sistema permanece ativo durante um determinado período de tempo;
Partition Tolerance (Tolerância ao Particionamento): A capacidade de um sistema continuar operando mesmo depois de uma falha na rede.
Segundo o Teorema do CAP, é possível existir três tipos de sistemas:
Sistemas CA: Sistemas com consistência forte e alta disponibilidade não sabem lidar com a possível falha de uma partição, caso ocorra, o sistema inteiro pode ficar indisponível. Os bancos de dados relacionais se encontram nesta categoria Exemplos: PostgreSQL, MySQL, Etc;
Sistemas CP: Sistemas que precisam da consistência forte e tolerância a particionamento é necessário abrir a mão da disponibilidade (um pouco). Exemplos são BigTable, MongoDB, etc;
Sistemas AP: Sistemas que jamais podem ficar off-line, portanto não desejam sacrificar a disponibilidade. E para ter disponibilidade com uma tolerância a particionamento é preciso prejudicar a consistência. Exemplos: Cassandra, Voldemort, etc.
Aderindo a um banco de dados não relacional, muita da responsabilidade de cuidar dos dados fica a cargo da aplicação. É ela que define como funcionam e como se relacionam os documentos. O banco fica com certeza mais simples, escalável e rápido, mas perdemos as conhecidas garantias dos bancos relacionais. Algumas aplicações usam bancos de dados não relacionais para uma leitura e escrita temporária, atualizando um banco relacional de tempos em tempos, tirando vantagem das duas estratégias (o que eu particularmente acho o ideal).
Mas o CAP cumpriu seu propósito e é hora de seguir em frente… Vem ai o Teorema do PIE que vamos mostrar na Parte 2 deste artigo!
Graduado em Ciência da Computação e com MBA em Gerenciamento de Projetos pela FGV, atua como desenvolvedor Java na Objective. Entusiasta da tecnologia, adora encarar desafios independente da linguagem (embora tenha um carinho especial por Java e Kotlin).