Flexibilidade em bancos NoSQL na prática

Alexandre Neukirchen
Data Hackers
Published in
7 min readNov 22, 2020

Vamos ver a diferença entre bancos de dados com esquema rígido e flexível.

Diferenças entre SQL x NoSQL

Antes de aprofundar o conceito de flexibilidade, gostaria de registrar que em meu ponto de vista ambas as tecnologias SQL e NoSQL não são concorrentes e sim complementares. De forma geral, SQL (Structured Query Language) foi criada no início dos anos 70 pela IBM com o objetivo de manipular e recuperar dados, sua primeira versão foi chamada de SEQUEL, seu propósito é trabalhar com dados tabulares. Enquanto que a sua irmã mais nova NoSQL surgiu de forma conceitual em 1998 e somente em 2009 ganhou popularidade, o propósito desta é trabalhar com dados não tabulares.

NoSQL (Not Only SQL) — Não somente por que alguns bancos fornecem algum tipo de suporte a linguagem SQL.

Referente as diferenças entre as duas tecnologias, vamos ver alguns itens da tabela de comparação disponibilizada pelo site do MongoDB.

  • Modelo de Armazenagem: SQL trabalha com tabelas, linhas e colunas fixas. NoSQL possui bancos de documentos, chave-valor, colunas e grafos.
  • Esquema: SQL funciona com esquema rígido enquanto que NoSQL funciona de forma flexível por que possui esquema dinâmico. Cassandra e Redis também possuem essa propriedade.
  • Dimensionamento: SQL trabalha verticalmente (aumento de escala com um servidor maior), NoSQL funciona horizontalmente (escala horizontal em servidores comuns).
  • Joins: Com SQL é normalmente exigido, com a sua irmã mais nova não é exigido.
  • Transações ACID: SQL suporta, alguns bancos NoSQL também suportam.

Tendo em mente essas diferenças vamos aprofundar no esquema e ver como podemos tirar proveito dessa flexibilidade. Faremos uma breve comparação entre Mongo e Postgre, aplicando a mesma regra de negócio, analisando cada abordagem. Vale lembrar que a ideia da comparação não é avaliar quem é melhor ou pior e sim avaliar as diferenças entre elas.

Bora lá?

Estudo de Caso

Inicialmente aviso que todos os scripts aqui utilizados ficaram disponíveis para download no final desse post.

Este estudo de caso foi realizado com o Windows 10. Iremos utilizar o PostgreSQL disponível para download nesse link e também utilizaremos o MongDB disponível nesse link; para esse é necessário realizar o login com uma conta Google ou informar alguns dados básicos para ser redirecionado para a página de download. Também será necessário a utilização de uma ferramenta para a visualização dos dados no mongo, você pode baixar o Robo 3T nesse link, selecione a opção Robo 3T: Simple GUI for beginners.

Criando os bancos

Vamos lá, baixe e instale o PostgreSQL, crie um banco e rode esse script (qualquer dúvida ou dificuldade me mande um e-mail: aneuk3@gmail.com), com isso a parte tabular inicial está pronta. Agora vamos ao não tabular. Baixe e instale o MongoDB, baixe e instale o Robo 3T, crie um banco e adicione esses itens ao banco.

Se tudo correu bem até aqui nós teremos diferentes estruturas de dados mas com os mesmos dados. A primeira diferença é que o modelo tabular ou relacional possui três tabelas — Receita, Ingrediente e ReceitaIngrediente — uma tabela é utilizada somente para fazer o relacionamento. Enquanto que o modelo não tabular ou não relacional criou uma coleção de documentos receita, onde cada receita possui uma lista com subdocumentos ingrediente.

Execute a consulta abaixo, explore as tabelas consultando-as individualmente e uma dica muito importante entenda a lógica de relacionamento aplicada (talvez não seja a melhor mas funciona), faça a mesma coisa com os documentos, explore as receitas e os ingredientes.

Consulta de todas as receitas e seus ingredientes — PostgreSQL
Consulta de todas as receitas e seus ingredientes — MongoDB

Flexibilidade e Esquema Dinâmico

Para exemplificar como essas propriedades funcionam e para entender a diferença entre elas, precisamos imaginar o seguinte cenário:

Existe uma aplicação chamada “Livro de Receitas” (que utiliza as estruturas de dados acima), nela são listadas as receitas bem como seus ingredientes. Agora vamos adicionar novas regras de negócio nessa aplicação.

Regra 1: A primeira regra é adicionar o modo de preparo da receita.

Regra 2: A segunda é adicionar o tipo do alimento; exemplo: feijão preto, branco carioca e por aí vai.

Vamos dividir para conquistar, primeiro faremos as alterações nas duas estruturas de dados, após uma comparação entre as operações feitas em cada uma e por fim avaliar qual senário cada abordagem melhor se encaixa.

Implementação no PostgreSQL

Para atender a primeira regra de negócio vamos criar uma nova tabela com o nome ReceitaModoPreparo, ela irá conter os seguintes campos código, código da receita, ordem e descrição. O campo código da receita é chave-estrangeira com a tabela Receita. Nesse link explico um pouco sobre esse tipo de chave.

Script para criar a tabela ReceitaModoPreparo

A segunda regra pode ser feita de duas formas, adicionando o campo tipo na tabela Ingrediente, ou criar uma nova tabela IngredienteTipo. Cada abordagem tem suas implicações. Se adicionarmos o campo tipo, simplifica o trabalho por um lado (se comparado com a inclusão da tabela), porém dessa forma ocorre redundância de dados, a informação “feijão” se repete, vejo como ficaria nesse caso:

Adicionando a coluna Tipo ocorre redundância de dados na coluna Nome

Para evitar o problema acima vamos criar uma nova tabela, dessa forma teremos mais trabalho mas eliminamos a redundância. A nova tabela terá três campos o código, código do ingrediente e a descrição.

Script para criar a tabela IngredienteTipo

Após criar a tabela vamos adicionar alguns registros e realizar uma consulta e analisar os dados. Repare que nessa consulta as informações estão repetidas, mas isso ocorre apenas em tempo de execução.

Consulta nas tabelas Ingrediente e IngredienteTipo

Para finalizar temos que adicionar uma nova coluna codigo_ingrediente_tipo na tabela ReceitaIngrediente.

Adicionado a coluna para armazenar o tipo do ingrediente

Nessa mesma coluna vamos adicionar uma chave estrangeira, fazendo referência a tabela IngredienteTipo indicando na receita qual o tipo do ingrediente.

Adicionado a chave-estrangeira entre ReceitaIngrediente e IngredienteTipo

Além de adicionar a coluna e a chave estrangeira é preciso adicionar valores nessa coluna referente ao código de cada tipo de ingrediente da tabela IngredienteTipo.

Script para atualizar alguns registros do novo campo recém criado

O resultado final das duas regras deve parecer como segue abaixo:

Consulta das receitas, ingredientes e tipo do ingrediente
Consulta das receitas e seu modo de preparo

Podemos dizer que não foi tão trivial aplicar as duas novas regras de negócio em uma estrutura SQL.

Implementação no MongoDB

Bancos que possuem esquema dinâmico também são conhecidos por serem schema-free, ou seja livres de esquema, dessa forma a estrutura do banco pode ser alterada em tempo de execução sem a necessidade de nenhuma pré-alteração. Com base nessas propriedades temos a vantagem de mudar a regra de negócio sem precisar fazer alterações diretamente na estrutura do banco, o único trabalho a ser realizado será na aplicação, ou seja, é na aplicação que ocorre todas as tratativas referente a adequação das regras de negócio e não no banco de dados.

Como resultado a aplicação vai gerar a nova estrutura de dados para atender as duas novas regras de negócio, uma forma possível de armazenar as novas informações é mostrada abaixo. Repare na simplicidade como é adicionado o novo campo “tipo” ao ingrediente sem que ocorra redundância de dados e a mesma facilidade ocorre para incluir os passos do modo de preparo da receita.

Consulta da receita com as novas regras — tipo do ingrediente e o modo de preparo

Conclusão

Importante salientar que em ambos os cenários existe a necessidade de realizar a customização na aplicação. A diferença é que quando utilizamos um banco NoSQL alteramos somente a aplicação, não sendo necessário alterar a estrutura do banco, enquanto que em uma abordagem relacional é necessário alterar o banco e customizar a aplicação.

Então devemos sempre utilizar NoSQL? Não! É recomendado utilizar quando a complexidade não é alta e quando seus dados não estão estruturados, ou quando você precisa armazenar dados mas não consegue definir o esquema; sistemas como ERP, CRM, SCM e BI necessitam de um banco SQL devido a alta complexidade de relacionamentos entre as tabelas, enquanto que os bancos NoSQL ganharam espaço com startups onde as regras de negócio não são extremamente complexas — como os sistemas acima citados — , e seus modelos de dados mudam constantemente em virtude de novas regras de negócio e testes de novas ideias.

Para finalizar gostaria de agradecer a você que chegou até aqui e pedir para deixar sua crítica, sugestão ou dúvida, segue meu e-mail abaixo, pode me escrever terei prazer em responder!

--

--

Alexandre Neukirchen
Data Hackers

Senior Software Engineering | Estudante de Data Science e Machine Learning