NoSQL no PHP usando ArangoDB — Parte 1
Aposto que você, como a maioria das pessoas, pensa em mongoDB quando ouve falar sobre NoSQL. Embora eu soubesse que existe vida além do Mongo, sempre senti falta de ter uma opção declarativa para manipular dados quando o SQL não era uma opção. Então algum tempo atrás conheci o ArangoDB e a sua especificação de linguagem de gerenciamento conhecida como AQL. Vamos entender um pouco mais porque isso pode mudar um pouco as perspectivas sobre a adoção do NoSQL e o que muda com as possibilidades que a AQL abre.
A importância de um banco de dados para uma aplicação
Como desenvolvedor aprendi que a fonte de dados que você escolhe para sua aplicação é muito importante. Com o tempo vamos ganhando experiência e depois de ver projetos falharem por não terem escolhido as ferramentas certas para sua construção ficamos muito cautelosos em relação à isso.
Depois de fazer chover com SQL é assustador não contar com esse recurso em um projeto.
Para quem tem experiência com SQL, abrir mão de uma linguagem declarativa para manipular sua base de dados é um pouco preocupante. Como a maioria dos bancos NoSQL tem uma interface imperativa não é incomum a resistência ao uso dessas tecnologias para gerenciamentos de bancos de dados.
A imagem acima mostra como uma instrução SELECT pode ser usada no MongoDB e a revela as diferenças entre a abordagem imperativa e a declarativa.
Linguagem Imperativa vs Declarativa
Quando estamos programando temos à nossa disposição alguns tipos de programação como a imperativa e a declarativa.
Resumidamente uma linguagem que permite o uso de uma abordagem imperativa é usada através de comandos que são instruções diretas para o seu objetivo. Por outro lado uma linguagem declarativa é aquela que irá processar seus comandos internamente. Note abaixo dois exemplos de comandos:
O echo é um comando imperativo e o desenvolvedor espera que quando o interpretador passe por aquela instrução imediatamente faça uma impressão. Seguindo o exemplo, um pouco mais abaixo há uma chamada imperativa para invocar de forma declarativa que o banco de dados execute o comando SQL esperado.
Note que quando usamos um comando SQL não sabemos exatamente qual o resultado que será retornado. Depois de declaradas, as instruções serão submetidas ao interpretador do motor do banco de dados escolhido e lá é que o comando será resolvido.
E afinal de contas o que é NoSQL?
A definição da Wikipedia é: “NoSQL (às vezes interpretado como Not Only SQL — Não Somente SQL) é um termo genérico para uma classe definida de banco de dados não-relacionais que rompe uma longa história de banco de dados relacionais com propriedades ACID (Atomicity, Consistency, Isolation, Durability). Outros termos equivalentes para esta categoria de bancos é NF², N1NF (non first normal form), nested relational, dimensional, multivalue, free-form, schemaless, document database e MRNN (Modelo Relacional Não Normalizado).” (https://pt.wikipedia.org/wiki/NoSQL visitado em 02/06/2017)
Já, segundo a Amazon: “NoSQL é um termo usado para descrever bancos de dados não relacionais de alto desempenho. Os bancos de dados NoSQL usam diversos modelos de dados, incluindo documentos, grafos, chave-valor e colunares. Bancos de dados NoSQL são amplamente reconhecidos pela facilidade de desenvolvimento, desempenho escalável, alta disponibilidade e resiliência. Veja abaixo vários recursos para ajudar você a começar a usar bancos de dados No SQL.” (https://aws.amazon.com/pt/nosql visitando em 03/06/2017)
Certo, mas e como isso nos ajuda? Estou imaginando que como eu você está acostumado ao mundo relacional e entende bem o que são tabelas; no mundo relacional temos as tabelas rígidas e algumas vezes acabamos querendo romper isso e já vi em algumas situações o JSON sendo usado dentro de uma coluna para poder subverter essa rigidez. Talvez quando esse momento surge você esteja precisando pensar em NoSQL.
Existe uma certa analogia entre o tradicional SQL e as soluções NoSQL conhecidas. Contudo essas tabelas são apenas uma referência singela. Uma Collection não tem nada a ver com uma Table; a semelhança é apenas hierárquica. O mesmo será com uma Row e um Document.
Sendo assim NoSQL é basicamente uma estratégia de armazenamento que foge a regra da nossa estrutura tradicional de tabelas e que pretende resolver questões para as quais o mundo relacional não foi feito. É um universo heterogêneo e praticamente abrange tudo o que não é SQL.
Certo, e o tal do AQL que você disse lá em cima?
A AQL é uma linguagem declarativa que pode ser usada para passar instruções de forma declarativa para o banco de dados. Isto pode amenizar os impactos gerados pela ausência do SQL na ferramenta que está sendo usada para manter o banco de dados do projeto.
O pessoal do Arango fez um resumão aqui comparando SQL e AQL.
Aplicações Práticas
“Se eu já sei tudo sobre relacional para que eu preciso do NoSQL?” — é uma das primeiras coisas que pode vir à mente dos desenvolvedores.
É cada vez mais comum termos que manter conjuntos de dados assimétricos e usando bancos relacionais somos “obrigados” à criar tabelas com (dezenas de) colunas que na verdade não importam muito e ficam vazias ou até com valores nulos.
Usando um banco NoSQL, geralmente, você pode ter registros com estruturas heterogêneas. E, se eu bem conheço o povo da TI, você deve estar pensando agora: “Como eu vou fazer aquelas consultas do meu relatório se com NoSQL eu não tenho como usar SQL?” — É ai que o AQL entra.
Usando AQL você poderá usar uma linguagem declarativa e manter sua estrutura salva de forma heterogênea.
Mão na massa
Pra ajudar à explicar o que estou querendo demonstrar, vamos ver brevemente como executar alguns comandos em AQL que estamos acostumados a fazer com SQL.
Iniciando o servidor ArangoDB
Na Docker Hub temos uma imagem bem apropriada para rodar o ArangoDB. Vamos usá-la para poder fazermos nossa introdução ao uso da AQL.
Usando o comando acima você vai iniciar um container Docker do Arango mapeando a porta 8529 no seu host. A saída será algo como o que vemos abaixo.
Note na imagem acima o trecho “GENERATED ROOT PASSWORD”. Copie a senha que foi gerada para usar na tela que se abre quando você acessar o endereço “http://localhost:8529” no seu navegador.
Preencha os campos acima com o usuário “root” e a senha que estava ao lado do texto “GENERATED ROOT PASSWORD” na saída do seu terminal.
Confirme o banco em que vai se conectar (provavelmente só terá essa opção “_system” mesmo) e você verá em seguida uma tela de dashboard. Essa interface é chama de ArangoDB Web UI e é uma forma de ver e gerenciar seus bancos (numa analogia desconfortável para mim, seria algo parecido com o phpMyAdmin no PHP + MySQL)
Esta é a visão que temos assim que entramos na interface web do ArangoDB.
Criando uma coleção
Uma coleção é como se fosse uma tabela no mundo relacional. Nela poderemos criar nossos documentos que serão as linhas de registro persistidas. Para criar uma nova coleção, basta ir até o menu “COLLECTIONS” do menu lateral esquerdo, clicar no botão “Add Collection” e informar o nome dela. No meu exemplo estou criando com o nome “users”.
Ao clicar em “Save” você verá algo parecido com a tela abaixo.
Manipulando alguns dados
Para podermos rodar nossos comandos AQL vamos agora para o menu “QUERIES”. Nele será possível ver um editor onde podemos informar nossas instruções.
Esta é apenas uma pequena demonstração do AQL, para ver mais sobre a ferramenta recomendo dar uma visitada em sua documentação e no cookbook.
A sintaxe para um insert é “INSERT document IN collection options”. Partindo desse preceito, podemos combinar o operator INSERT com o FOR e gerar vários registros de uma vez (adaptado à partir daqui). O comando abaixo vai criar 1000 registros (documentos) na nossa coleção “users” criada agora à pouco.
Depois de criados os documentos podemos usar o FOR (algo parecido com o que faz um SELECT no SQL) para listar os dados das coleções. Note na saída abaixo que as propriedade _key, _id e _rev foram criadas automaticamente pela engine e poderíamos usar as funções relacionadas aos documentos para determinar a visibilidade delas em uma query.
A linguagem AQL entrega vários comandos básicos para um banco de dados que se preze como excluir, atualizar, contar, entre outros, além de permitir o “bind” de parâmetros parar as instruções e conseguir gerenciar com facilidade o offset dos documentos. Também é possível usar agregações e combinações bem interessantes com os documentos. No exemplo a seguir agrupei os usuários por status e mostrei a quantidade de usuários em cada grupo.
E como usar isso com PHP?
Nessa primeira parte do artigo deu para ter uma ideia do funcionamento do ArangoDB e da AQL. Legal né? No próximo artigo vamos ver de forma prática como usar um Object-Document Manager (ODM) para rodar nossos comandos AQL direto do PHP. Vamos construir pequenas classes para gerenciar dados usando o Arango e a interessante linguagem declarativa que pode ser usada com ele.
<SPOILERS>Se quiser já ir adiantando o assunto, a biblioteca base que vamos usar é esta que está abaixo que é mantida pelo próprio ArangoDB.
</SPOILERS>
Conclusão
Com recursos interessantes o ArangoDB, demonstra ser bem versátil e pode inclusive ser configurado para receber instruções via HTTP. Ainda não tenho muita experiência com ele, mas tem me agradado até o momento.
Em tempos de GraphQL o Arango pode parecer pouco poderoso, mas seria um engano pensar assim. Mantenha-o no seu cinto de utilidades e sinta-se à vontade para experimentar logo que puder : )
Esta é a primeira de duas partes deste artigo.
Quer trocar mais ideia sobre o assunto? Deixa um comentário ou me chama nas redes sociais.