Parte 2 – Dando Superpoderes aos Seus Dados com Neo4J e Grafos

novembro de 2021

Autor: Lucas Humberto Cabrera Santos

Grafos 

Grafos são um conceito extremamente antigo (a primeira menção a isso remonta a Leonhard Euler em 1736) de armazenamento e visualização de dados e suas relações. Basicamente um Grafo é composto de duas partes básicas: 

  • : O nó é o representante de uma entidade do sistema, por exemplo, um usuário, um Role, um Scope 
  • Arestas: As arestas são os relacionamentos em si 

Este é o exemplo de um Grafo simples: 

Aqui temos dois nós, 1 e 2 que estão conectados através de uma relação de “FOLLOWS”, que possui uma propriedade Since que diz desde quando aquela pessoa 1 segue a pessoa 2. Perceba que os nós também podem ter propriedades e além disso, também podemos definir Labels para cada um dos nós. Então, como estamos falando de pessoas, poderíamos ter um nó Alice: Person, onde Alice seria o identificador do nó e Person seria a categoria, ou a Label desse nó. Então podemos montar um Grafo simples como o do exemplo a seguir: 

Ou então um Grafo mais complexo como o do próximo exemplo: 

Para dar uma noção da importância de grafos, hoje, principalmente, eles são muito utilizados em diversas aplicações reais, principalmente em logística e até mesmo na Internet, que se pensarmos bem, é um Grafo gigante, roteadores também utilizam algoritmos de menor caminho (como Dijkstra) para encontrar o menor caminho entre outros roteadores até o IP de destino. 

Com esses dois conceitos básicos nós já podemos mudar a forma como armazenamos os nossos dados de forma radical, isso porque nós estamos dando muita enfase para os relacionamentos, e não só para os dados que temos. 

Neo4J 

Durante muito tempo tivemos o conceito de Grafos, mas não aplicamos ele a tecnologia na forma de armazenamento ou de definição de dados. Até que criamos os chamados os bancos de dados orientados a Grafos. Esses bancos de dados armazenam fisicamente não só os dados, mas também suas relações, de forma que se tornam muito mais rápidos e muito mais eficientes do que um banco de dados relacional normal. 

O Neo4J é um de muitos exemplos de bancos de dados orientados à Grafos, criado em 2007, ele se tornou rapidamente o banco mais utilizado no seguimento e também um dos mais rápidos. Isso se dá por conta de que o Neo4J é o que chamamos de “Grafo Nativo”, ou seja, fisicamente, na memória, os nós e relacionamentos apontam uns para os outros, isso cria o que é chamado de Adjacência Livre de Índices (Index-free Adjacency), dessa forma os sistemas de Grafos Nativos, como o Neo4J, podem fazer uma query através de travessias de Grafos, pulando de um endereço para outro na memória de forma absurdamente rápida, na verdade, o chamado Pointer Hoping é a forma mais rápida de um computador acessar um dado relacionado, você pode ver mais detalhes sobre esse tema nesse artigo

O outro tipo de banco orientado a Grafos é o chamado “Grafo Não Nativo”, os grafos não nativos se apoiam sobre bancos de dados relacionais ou não relacionas já existentes para que possam gerenciar seus relacionamentos. Em outras palavras, eles tem uma representação de um Grafo em forma de tabelas ou documentos.  

O que torna eles cerca de 1.000 vezes mais lento do que um Grafo Nativo e somente pelo fato de que a maioria dos dados que precisamos acessar não está diretamente carregado na memória. 

Por que Grafos? 

Naturalmente você deve estar pensando: “Por que eu deveria usar Grafos se eu já tenho meu banco de dados aqui?”. Além da velocidade de execução das Queries (no site do Neo4J, é dito que uma Query demora “o tempo de um Tweet“), a flexibilidade e a facilidade de modelagem são muito maiores do que um banco tradicional. 

Você deve estar pensando “Flexibilidade? Facilidade de modelagem?”, justamente, um banco de Grafos é muito mais flexível porque você pode mudar o Schema todo do banco ou então alterar qualquer atributo ou valor que você precise de fato alterar os dados existentes, porque cada relacionamento e nó é único e separado. Agora em termos de facilidade de modelagem, pense o seguinte: Vamos modelar uma rede social igual ao Twitter. 

Primeiramente, temos a relação inicial, a mais fundamental de todas: “Um usuário pode seguir outro usuário e ser seguido”, agora imagine esse relacionamento na sua cabeça. Você pensou em um Grafo, não é mesmo? Um pequeno círculo apontando para outro círculo com uma Label “Segue” entre eles, pois é, naturalmente, o cérebro humano pensa em termos de relacionamentos entre coisas, então é muito mais simples você modelar um Grafo, porque você pode simplesmente pensar no que você quer e ele já estará modelado! 

Além disso, qualquer dado pode ser modelado em termos de Grafos, de forma que você poderia também utilizá-lo para tarefas mais corriqueiras como armazenamento de usuários ou outras funcionalidades que teríamos delegado a um Banco Relacional ou Não Relacional logo de cara, então por que não fazemos isso? 

Prós e Contras 

Acredito que os prós foram muito explicados nos parágrafos anteriores, certo? Temos velocidade, flexibilidade, facilidade de modelagem e além disso temos uma agilidade bastante incomum para bancos relacionais em queries, pois elas executam absurdamente rápido em um ambiente onde tudo já está carregado na memória. 

Infelizmente, por não ser ainda um modelo muito difundido, os bancos de Grafos não contam com bibliotecas ou suportes muito grandes. Apesar de o Neo4J, por exemplo, ter bibliotecas para a maioria das linguagens mais utilizadas, essas bibliotecas ainda precisam de alguns ajustes finos, principalmente no que diz respeito a Queries.  

Além disso, não existem hoje boas ou excelentes ferramentas de visualização para esse tipo de Grafo que possam ser distribuídas em larga escala para o Front-end sem divulgar dados sensíveis como usuários e senhas do banco. Isso porque a maioria das bibliotecas boas (como o NeoVis.js) precisam das credenciais do banco para montar o Canvas com um Grafo, e outras como o D3.js e libs de charting mais genéricas tem uma API bastante controversa para manipulação desse tipo de dado, porém dado que a exibição de um Grafo em forma de Grafo é somente para visualização e, raramente, apresenta algum valor analítico, então estamos bem com a representação em forma de JSON ou tabelas que o Neo4J também nos proporciona. 

Em suma, os prós ultrapassam os contras, principalmente quando falamos de escala, pois um Grafo “grande” no Neo4J é considerado um Grafo com mais de 2 bilhões de nós, ou seja, esse modelo de Grafos pode escalar muito se você tiver infraestrutura para suportá-lo. 

Conclusão 

Para que esse artigo não fique muito extenso, vou dividi-lo em várias partes, no próximo artigo irei explicar como podemos iniciar com Neo4J, instalando e começando a inserindo dados e criando um Grafo. 


Compartilhe nas redes sociais Compartilhe nas redes.