Sei sulla pagina 1di 147

Bancos de Dados NOSQL

Bootcamp: Analista de Banco de Dados

Charles Fortes
Gustavo Aguilar

2020
Bancos de Dados NOSQL
Bootcamp: Analista de Banco de Dados
Charles Fortes
Gustavo Aguilar
© Copyright do Instituto de Gestão e Tecnologia da Informação.
Todos os direitos reservados.

Bootcamp Analista de Banco de Dados – Página 2 de 147


Sumário

Capítulo 1. Introdução ........................................................................................... 6

1.1. Conceitos ......................................................................................................... 6

1.2. Relacional vs não relacional ............................................................................ 8

1.3. Diferenças e similaridades ............................................................................. 11

1.4. ACID vs BASE ............................................................................................... 15

Resumo do capítulo .............................................................................................. 18

Material complementar.......................................................................................... 19

Capítulo 2. Categorias de Bancos de Dados Não Relacionais ............................ 21

2.1. Chave / Valor - Conceituação ........................................................................ 21

2.2. Chave / Valor - Aplicações ............................................................................. 23

2.3. Documentos - Conceituação .......................................................................... 24

2.4. Documentos – Aplicações.............................................................................. 26

2.5. Colunar – Conceituação................................................................................. 26

2.6. Colunar – Aplicações ..................................................................................... 28

2.7. Grafos – Conceituação .................................................................................. 28

2.8. Grafos - Aplicações e casos de uso ............................................................... 29

Resumo do capítulo .............................................................................................. 30

Material complementar.......................................................................................... 30

Capítulo 3. Adoção da Tecnologia....................................................................... 32

3.1. Considerações ao escolher um banco de dados NOSQL .............................. 32

3.2. Erros comuns ao adotar a tecnologia............................................................. 34

3.3. Persistência poliglota ..................................................................................... 36

Resumo do capítulo .............................................................................................. 39

Material complementar.......................................................................................... 40

Bootcamp Analista de Banco de Dados – Página 3 de 147


Capítulo 4. O uso de NOSQL em produção ........................................................ 41

4.1. Escalabilidade ................................................................................................ 41

4.2. Manutenção e backup .................................................................................... 42

Resumo do capítulo .............................................................................................. 44

Material complementar.......................................................................................... 44

Capítulo 5. MongoDB .......................................................................................... 45

5.1. Introdução ao MongoDB ................................................................................ 45

5.2. Conceitos básicos e arquitetura do MongoDB ............................................... 48

5.3. Replica Set e Sharding .................................................................................. 53

5.4. Instalação e configuração do MongoDB ........................................................ 62

5.5. Definindo e criando um banco de dados MongoDB ....................................... 74

5.6. Trabalhando com bancos de dados MongoDB .............................................. 81

Capítulo 6. Banco de Dados em Tempo Real (Real-Time Database) ................. 84

6.1. Introdução à Banco de Dados em Tempo Real ............................................. 84

6.2. Introdução ao Firebase Realtime Database ................................................... 86

6.3. Instalação e configuração do Firebase no JavaScript .................................... 88

6.4. Trabalhando com os dados no Firebase Realtime Database ........................ 94

6.5. Overview das regras do Firebase Realtime Database ................................... 97

6.6. Escalonamento no Firebase Realtime Database ......................................... 100

Capítulo 7. Pesquisa Indexada em Bases Não Estruturadas ............................ 102

7.1. Introdução à pesquisa indexada .................................................................. 102

7.2. Introdução ao Elastic Stack.......................................................................... 106

7.3. Conceitos Básicos e Arquitetura do Elastic Search ..................................... 109

7.4. Instalação e configuração do Elasticsearch e do Kibana ............................. 118

7.5. Definindo e administrando índices no Elastic Search .................................. 126

Bootcamp Analista de Banco de Dados – Página 4 de 147


7.6. Trabalhando com documentos no Elastic Search ........................................ 129

7.7. Overview de agregações no Elastic Search ................................................. 137

7.8. Overview de Mapping .................................................................................. 138

Capítulo 8. Considerações finais ....................................................................... 140

9.1. O papel dos DBAs ....................................................................................... 140

9.2. O dia a dia de um DBA que atua com NOSQL ............................................ 143

Resumo do capítulo ............................................................................................ 144

Material complementar........................................................................................ 144

Referências………. ................................................................................................ 146

Bootcamp Analista de Banco de Dados – Página 5 de 147


Capítulo 1. Introdução

Este capítulo tem como objetivo estabelecer e resgatar alguns conceitos


básicos em relação a persistência de dados, sua história e evolução. Entenderemos
as diferentes necessidades que surgiram com os avanços tecnológicos, e
analisaremos as diferenças e similaridades entre os modelos computacionais de
persistência da atualidade.

1.1. Conceitos

O conceito de persistência de dados está relacionado ao armazenamento


destes dados em local não volátil, de forma que eles possam ser recuperados
posteriormente para consulta e análise. Isso significa armazenar estes dados em um
local que possa garantir a integridade dos dados por um período de tempo
indeterminado, até que eles sejam atualizados ou descartados propositalmente.

Meios de armazenamento voláteis são aqueles com capacidade de guardar


uma informação apenas pelo curto período de tempo no qual o meio está ativo, como
a memória RAM de um computador, que ao ser desligado é completamente
descartada pelo sistema.

Os meios de armazenamento não voláteis são dos mais variados e têm


evoluído muito no decorrer das eras de acordo com o crescimento do volume e do
fluxo de informações.

Conforme a necessidade de reter informação com precisão foi aumentando,


os meios não voláteis de armazenamento foram evoluindo de forma a permitir um
maior volume de informação armazenada no menor espaço possível. Com isso, a
humanidade saiu do armazenamento em tábuas de pedra/barro da antiga suméria até
a era moderna, passando desde os cartões perfurados usados há algumas décadas
atrás, até os atuais armazenamentos em estado sólido, como as unidades SSD.

Bootcamp Analista de Banco de Dados – Página 6 de 147


Figura 1 – Tipos de armazenamentos não voláteis ao longo dos anos.

A procura por alternativas de armazenamento de grandes volumes de dados


em meios que ocupem pequenos espaços e necessitem de pouca manutenção vem
acompanhando o volume de informações geradas através dos anos.

Segundo Eric Schmidt, CEO do Google em 2010, naquele ano, a cada dois
dias a humanidade gerava tanta informação quanto toda a humanidade desde a
existência das civilizações até o ano de 2003, o que equivaleria a aproximadamente
5 exabytes de dados (1 exabyte equivale a 1.152.921.504.606.846.976 bytes, pouco
mais de 1 milhão de terabytes).

Segundo um estudo de 2016 da Northeastern University nos Estados Unidos,


o total de dados gerados por toda a humanidade até 2013 estava na casa de 4.4
zettabytes (mais de 4 bilhões de terabytes), e até o ano de 2020 já teríamos passado
dos 40 zettabytes.

Figura 2 – Volume de informação gerada ao longo dos anos.

Esse volume crescente de dados é gerado principalmente pelos cada vez


mais crescentes recursos conectados à internet que possuímos, que vão desde as

Bootcamp Analista de Banco de Dados – Página 7 de 147


redes sociais, fotos, áudios, vídeos e cada vez mais dispositivos inteligentes
conectados à internet (IoT).

A internet movimenta um volume cada vez maior de dados originados das


mais diversas fontes e nos mais diversos formatos. Informações sobre
comportamento, sensores e informações geradas livremente por qualquer um, criam
uma enorme onda de dados para serem armazenados e tratados nos dispositivos
pessoais de cada um e na nuvem.

Devido a este comportamento cada vez mais agressivo na geração de dados,


assim como a necessidade massiva de agilidade para interpretação e acesso dessas
informações, fomos levados a evoluir e repensar a forma como os bancos de dados
atuais lidam com a escrita e a leitura desses dados. Os dados que antes eram
armazenados sobre o modelo matemático relacional de conjuntos, sobre uma série
de estruturas que garantiam integridade relacional para as entidades, vêm ganhando
novos parceiros e abordagens para atender aos requisitos de despenho de acesso à
informação.

Nos próximos tópicos, vamos conceituar e relacionar estes modelos de


persistência de dados, entendendo as diferentes propostas e aplicações a que eles
se propõem.

1.2. Relacional vs não relacional

O modelo mais comum de armazenamento de dados que predominou nas


últimas décadas foi o relacional.

Este modelo, que é baseado na matemática relacional de conjuntos, não foi


o primeiro e nem é o único modelo de persistência de dados que foi usado pela
comutação, porém sua temática que aborda os indivíduos de um determinado
conjunto e seus relacionamentos com outros indivíduos, permitindo operações de
junção, união, retorno seletivo de dados e diversas outras operações matemáticas,

Bootcamp Analista de Banco de Dados – Página 8 de 147


possibilitaram a extração de informações complexas e relevantes para os sistemas
computacionais, principalmente os ligados a operações corporativas.

Figura 3 – Relação entre conjuntos.

Fonte: https://chasqueweb.ufrgs.br/~paul.fisher/apostilas/basdad/unimar/index.htm.

Essas informações são agrupadas em esquemas que representam uma


determinada entidade ou unidade da operação de um sistema, como um cliente, um
produto e uma venda. E uma vez mapeadas as características de um determinado
esquema e seus relacionamentos, cada tupla (linha da tabela) passava a representar
uma ocorrência consistente dessa operação que ocorreu no mundo real; e juntando
informações fracionadas e condicionais de cada um dos relacionamentos, chegavam-
se à análises e informações complexas sobre o funcionamento daquele domínio de
negócio, como por exemplo a volumetria de vendas em uma determinada região, o
público-alvo de um determinado produto, a sazonalidade de demanda de um
determinado serviço etc.

Estávamos vivendo até então um cenário em que a necessidade de


armazenamento e análise estavam relacionados a dados estruturados, normalizados
e padronizados, que eram obtidos por fontes sistêmicas e controladas como sistemas
de vendas, CRM’s, dentre outros. Porém, com o avanço da internet e tudo que vem
atrelado a ela, surgiu a necessidade de reter e armazenar outros tipos de dados,
vindos das mais diversas fontes e sob os mais diversos formatos.

Bootcamp Analista de Banco de Dados – Página 9 de 147


O volume de informação que é gerado entorno de um usuário hoje é muito
grande, e a informação extraída destes dados tem tanto ou até mais valor corporativo
do que as informações de compras, vendas ou inputs manuais feitos por uma equipe
de relacionamento com o cliente.

As informações transacionais normalizadas das operações realizadas por um


usuário nos revelam algo sobre o comportamento desse usuário durante a interação
dele com a empresa, como em uma contratação de um serviço. Porém, a análise dos
dados gerados pelo seu perfil de busca, navegação, preferências, crenças,
relacionamentos, meios socioculturais e tudo mais que o cerca pode permitir
realmente entender as necessidades de um cliente ou usuário. Desta forma, permite
que serviços e produtos sejam oferecidos antecipadamente, que informações
relevantes sejam preparadas para atendê-lo com maior agilidade e prontidão,
melhorando sua experiência de navegação e sugerindo comodidades e confortos
baseados em seu padrão de vida.

O problema de tentar tratar estas informações novas com o modelo relacional


é que essas informações possuem diferentes origens e formatos, podendo até mesmo
um mesmo tipo de informação ser recebido com diferentes dados, fazendo com que
não consigamos definir um esquema claro ou normalizado para estes dados, que são
os dois principais requisitos para termos um bom funcionamento e desempenho em
um banco de dados relacional.

O surgimento dos bancos de dados que trabalham com o armazenamento


não relacional da informação, veio suprir principalmente essa necessidade,
armazenar um grande volume de informação não normalizada, garantindo o
funcionamento da aplicação dentro de parâmetros de desempenho muito exigentes.
Não apenas respondendo rapidamente às requisições, mas possibilitando um
crescimento natural das bases de dados.

Com o passar do tempo, estes bancos de dados não relacionais acabaram


sendo conhecidos pelo acrônimo NOSQL, que significa Not Only SQL (não somente
SQL, em tradução livre), em uma alusão a ideia e um movimento que prega que nem
todos os cenários de dados são adequados ao uso de bancos de dados relacionais,

Bootcamp Analista de Banco de Dados – Página 10 de 147


ou mais especificamente ao uso da linguagem de consulta e manipulação destes
bancos de dados chamada SQL (Structured Query Language – Linguem Estruturada
de Consulta, em tradução livre).

Desta mesma forma, o acrônimo SQL passou a se referir também em


diversas esferas ao banco de dados relacional propriamente dito, de forma que
passou a ser comum encontrar a designação SQL para tratar do modelo relacional e
NOSQL para tratar o modelo não relacional.

1.3. Diferenças e similaridades

Quando analisamos as particularidades de cada um dos modelos, podemos


destacar um conjunto de características únicas, que fazem com que cada um dos
modelos atenda a cenários diferentes com maior ou menor eficácia.

Podemos destacar nos bancos de dados relacionais:

▪ Atomicidade das transações: a principal característica de um banco de


dados relacional está na sua capacidade nativa e natural de trabalhar
transações, fazendo com que a persistência de um determinado conjunto de
dados seja tratada como uma única unidade de trabalho, de forma que, caso
ocorra falha em qualquer uma das operações com os dados, todo o conjunto
de alterações seja rejeitado, garantindo assim a integridade relacional do
conjunto de dados.

▪ Log transacional: os bancos de dados relacionais tipicamente são


preparados e configurados para armazenar um log operacional das
transações efetuadas. Apesar desta característica poder ser alterada através
das configurações dos bancos de dados, ela permite que sejam feitas
análises sobre as operações realizadas em um determinado dado, e até
mesmo que uma determinada operação seja desfeita no banco de dados sem
a necessidade de uma restauração completa a partir de um backup.

Bootcamp Analista de Banco de Dados – Página 11 de 147


▪ Programabilidade: os bancos de dados relacionais tipicamente fornecem
uma série de estruturas de programação como gatilhos, funções e
procedimentos criados pelo administrador do banco de dados, estendendo as
capacidades desse banco. Apesar de alguns bancos de dados não
relacionais fornecerem mecanismos para a criação de tipos e funções
personalizadas, as aplicações nos dois modelos diferem em objetivos,
ficando estas opções de programação dos bancos de dados relacionais mais
voltadas para atalhos e garantia adicional da integridade e regras de domínio;
enquanto o modelo não relacional está mais vinculado a uma operação sobre
os dados, apesar de isso não ser necessariamente uma regra.

▪ Visões analíticas de dados: o uso de instruções SQL permite a criação de


visões complexas de dados, envolvendo diversas entidades e subconjuntos
de dados, permitindo que estas consultas sejam armazenadas em views que
se comportam como tabelas, podendo ser consultadas sempre que
necessário. Apesar da criação de visões predefinidas de dados não ser uma
característica exclusiva do modelo relacional, o desempenho e a facilidade
que as instruções SQL trazem para o modelo são inúmeras.

Essas características específicas dos bancos de dados relacionais os tornam


muito confiáveis e práticos para lidar com diversas partes de um sistema corporativo,
principalmente quando lidamos com informações críticas. Porém, para garantir essas
operações, esse tipo de banco de dados apresenta menor desempenho de leitura e
escrita, pois depende de uma série de redundâncias e tratativas adicionais dos dados.

Além disso, apesar da maioria destes bancos de dados fornecerem


mecanismos para distribuição horizontal dos dados em cluster, via regras de
particionamento dos dados ou replicação, sua escala é feita principalmente de forma
vertical, com a adição de mais recursos de memória, processamento ou
armazenamento. Além disso, nenhuma operação de aumento de capacidade é
facilmente aplicada sem uma parada total dos sistemas.

Já os bancos de dados não relacionais destacam-se, principalmente, por:

Bootcamp Analista de Banco de Dados – Página 12 de 147


▪ Sempre estarem acessíveis: esse tipo de banco de dados é projetado para
sempre responder a uma requisição de leitura ou escrita, mesmo que um ou
vários de seus nós estejam ausentes, ou que a informação esteja incompleta.
Sua prioridade é responder à aplicação.

▪ Poderem ter seus dados parcialmente disponíveis: os dados retornados


não necessariamente são todos os dados disponíveis para uma consulta. Isso
pode ocorrer devido a um atraso na replicação de um dado ou pela
indisponibilidade momentânea de um dos nós do cluster.

▪ Terem uma estratégia e abordagem para cada cenário: devido aos


diferentes tipos de aplicações possíveis para um banco de dados não
relacional, diferentes tipos de implementação e abordagem podem ser
encontradas, cada uma delas adequada a um diferente cenário.

▪ Custo do suporte: normalmente bem mais reduzido que o custo dos SGBDs
relacionais, quando não, gratuitos com as edições community.

▪ Ausência de Esquema (Schema Less) ou Esquema Flexível (Dinâmico):


as estruturas de armazenamento de dados não possuem uma estrutura fixa
para todos os registros. Isso quer dizer que, em uma mesma estrutura, pode
existir registros que possuam um determinado campo, enquanto outros não o
possuem (não estamos nos referindo ao valor do campo, e sim à definição do
campo). Além disso, as estruturas de dados não precisam ser pré-criadas, ou
seja, podem ser definidas em tempo de inserção dos dados (ao invés do
tradicional CREATE TABLE prévio dos bancos relacionais, para depois realizar
o INSERT).

▪ API de Acesso Simples: o foco de um SGBD NOSQL está em como recuperar


os dados de forma eficiente, e não em como armazená-los em estruturas
complexas e robustas, como ocorre nos bancos relacionais.

▪ Suporte Nativo a Replicação: com a replicação dos dados, dando um caráter


de banco de dados distribuídos, provê-se alta disponibilidade, uma vez que os
dados ficam disponíveis em mais de um local.

Bootcamp Analista de Banco de Dados – Página 13 de 147


▪ Suporte Nativo a Sharding: com a fragmentação (particionamento horizontal)
dos dados, ganha-se alto poder de processamento paralelo e distribuição da
carga de processamento, aproveitando-se de todo o power dos servidores do
ambiente.

▪ Escalabilidade Horizontal: adição de mais servidores no ambiente, de forma


rápida e segura, permitindo que a infraestrutura do banco de dados cresça de
acordo com o crescimento das cargas de processamento e consulta dos
dados.

▪ Escalabilidade Vertical: com uma topologia de cluster, em ambientes


configurados com replicação, é possível também escalar um servidor
isoladamente, retirando-o do cluster temporariamente, de forma transparente,
para adicionar mais memória RAM ou CPU.

▪ Controle de Concorrência Multiversão (MVCC - Multiversion Concurrency


Control): um controle mais flexível para as transações, permitindo que
operações de leitura ocorram em paralelo com as operações de escrita.

Estas características permitem que os bancos de dados não relacionais


trabalhem a manipulação de um grande volume de dados, tanto na escrita quanto na
leitura. Além disso, este tipo de banco de dados é projetado para ser escalado
horizontalmente, de forma fácil e transparente para a aplicação, bastando adicionar
um novo nó ao cluster que irá trabalhar a modificação, sem parada no sistema.

A principal desvantagem desse modelo está na dificuldade de trabalhar


consultas complexas e que exijam um alto grau de relacionamento entre diferentes
dados. Essa dificuldade não está relacionada apenas com a forma como os dados
são armazenados internamente dentro do banco de dados, mas também com
possível inconsistência temporária que os dados podem sofrer.

Desta forma, um ponto importante ao se trabalhar com bancos de dados


NOSQL escaláveis e, portanto, distribuídos, é compreender o Teorema de CAP
(Consistency, Availability, Partition tolerance). Esse teorema, criado por Eric Brewer

Bootcamp Analista de Banco de Dados – Página 14 de 147


em 2000, diz que existem três principais requisitos sistêmicos em um ambiente
distribuído:

▪ Consistência: cada usuário deve ter uma visão consistente ou igual dos
dados, ou seja, todos os nós dentro de um cluster veem os mesmos dados.

▪ Disponibilidade: o sistema está disponível quando solicitado,


independentemente de ter ocorrido uma falha física ou lógica em alguns dos
servidores.

▪ Tolerância à Partição: o sistema continua a operar como esperado, mesmo


sob circunstâncias de perda de conexão entre os nós ou perda de dados em
um determinado nó.

A conclusão do Teorema de CAP é que um sistema distribuído pode garantir


apenas dois desses requisitos, e ignorar isso pode ter resultados catastróficos, que
incluem a possibilidade de, em determinada situação, nenhum dos três requisitos
serem contemplados.

1.4. ACID vs BASE

As propriedades ACID de um bando de dados relacional, dizem respeito às


suas capacidades, em relação à:

▪ Atomicidade: todas as operações só serão aplicadas e persistidas se – e


somente se – todo o conjunto de alterações for concluído com sucesso.

▪ Consistência: os dados estarão sempre consistentes e completos,


respeitando as regras de integridade, relacionamentos e restrições
configuradas no banco.

▪ Isolamento: a manipulação dos dados é realizada de forma isolada,


garantindo que não haja interferência externa por outra transação, sendo

Bootcamp Analista de Banco de Dados – Página 15 de 147


realizada no mesmo instante. Desta forma, uma transação deve aguardar
que a outra termine para poder acessar e manipular os dados.

▪ Durabilidade: uma vez que o banco de dados retornou a informação de que


o dado está salvo, ele não será mais perdido.

As limitações colocadas pelo Teorema CAP, acerca da confiabilidade do


banco de dados, trouxeram consequências significantes para os SGBDs não
relacionais distribuídos de grande escala. Como eles miravam na disponibilidade e
tolerância à partição, deixavam a consistência em segundo plano, o que fazia com
que as propriedades ACID não fossem aplicáveis em sua totalidade.

Para contornar isso, foi proposto um modelo alternativo de consistência


denominado BASE (Basically Available, Soft state, Eventual consistency).

▪ Basicamente disponível (Basically Available): essa restrição afirma que o


sistema garante a disponibilidade dos dados no que diz respeito ao Teorema
de CAP, ou seja, haverá uma resposta a qualquer solicitação. Entretanto,
pode retornar uma “falha” para obter os dados solicitados, ou os dados
podem estar em um estado inconsistente ou em transição.

Isso permite, por exemplo, que uma rede social receba sempre sua
atualização, mesmo que leve tempo até ser replicada em todos os bancos de dados
ligados a ela, e irá retornar os dados da linha do tempo para seus amigos, mesmo
sem a sua atualização, que poderá ser exibida em um momento diferente.

▪ Estado não rígido (Soft State): o estado do sistema pode mudar ao longo do
tempo, mesmo durante momentos sem entrada de dados, o que é necessário
para a consistência eventual (dados sendo replicados assincronamente para
os outros nós).

▪ Consistência Eventual (Eventual Consistency): os dados são propagados


para todos os nós, mais cedo ou mais tarde, ou seja, assincronamente.
Entretanto, o sistema continuará a receber dados e não estará verificando a

Bootcamp Analista de Banco de Dados – Página 16 de 147


consistência de todas as transações, antes de passar para a próxima
transação.

Com esse novo modelo de consistência no processamento das transações,


permitiu-se uma clareza maior acerca do nível de confiabilidade de cada SGBD
NOSQL. Além disso, foi possível um dimensionamento horizontal mais eficiente em
termos financeiros, pois verificar a consistência dos dados, a cada transação, sempre
acarretou em custos de processamento enormes em sistemas que realizam milhões
de transações concorrentes.

Figura 4 – Teorema CAP e as Propriedades ACID e BASE.

Fonte: Hatoutdoor (2019).

A consistência eventual teve papel fundamental no mundo computacional,


pois trouxe à organizações como Google, Twitter e Facebook, a capacidade de
suportar milhões de usuários espalhados ao redor do mundo, milhares de transações
por segundo, com a disponibilidade e tolerância a falhas necessárias, ao mesmo
tempo em que mantiveram seus custos baixos, sem prejuízos aos dados das suas
soluções.

Obviamente que o mundo perfeito seria conseguir consistência total dos


dados sempre, juntamente com alta disponibilidade e tolerância à partição, mas como
Dan Pritchett expôs em seu artigo “BASE: Uma Alternativa Ácida”, para atender ao

Bootcamp Analista de Banco de Dados – Página 17 de 147


crescimento exponencial de dados devido à era da IOT (Internet das Coisas), redes
sociais, computação em nuvem e projetos de Big Data, eram necessárias mudanças
de paradigmas para se aceitar certa consistência eventual dos dados, em detrimento
dos outros benefícios. E foi nesse nicho que os SGBDs NOSQL foram empregados e
proliferaram com grande facilidade, sendo até necessária uma certa segmentação
acerca dos tipos de modelos implementados por cada um, as chamadas Famílias de
Bancos de Dados NOSQL, ou categorias, que veremos no capítulo 2.

Resumo do capítulo

No decorrer deste capítulo, vimos como o volume de dados gerados vem


crescendo em função da internet. Se armazenarmos todo o volume de informação
gerada pela humanidade desde os primórdios das civilizações até o ano de 2003,
teremos aproximadamente 5 exabytes de informações armazenadas, o mesmo
volume de dados gerados em apenas dois dias no ano de 2010.

Armazenar e analisar estes dados pode trazer um grande diferencial para as


organizações modernas, que passam a entender e descobrir padrões e
comportamentos até então inimagináveis. Para lidar com este volume de informações
e as necessidades de crescimento rápido, vimos o surgimento de diferentes tipos de
bancos de dados não relacionais, que armazenam e tratam os dados em diferentes
formatos, para atender a diferentes cenários de utilização.

Enquanto os modelos relacionais garantem uma série de tratativas e


linearidades através das características ACID de seus gerenciadores de dados, os
bancos de dados não relacionais apresentam maior flexibilidade no tratamento da
informação, empregando as características BASE em seu modelo de
armazenamento, focando na disponibilidade do sistema e não necessariamente na
consistência integral dos dados armazenados.

Cada um dos dois modelos apresenta particularidades relevantes para


diferentes pontos da aplicação, sem que necessariamente um seja melhor ou pior que
o outro.

Bootcamp Analista de Banco de Dados – Página 18 de 147


Material complementar

▪ CAMPOS, Douglas. Escalando sistemas com soluções NoSQL. In: Caelum


Blog, 2010. Disponível em: <http://blog.caelum.com.br/escalando-sistemas-
com-solucoes-NOSQL/>. Acesso em: 17 set. 2020.

▪ COTI INFORMÁTICA – Escola de Nerds. Cursos. Disponível em:


<https://www.cotiinformatica.com.br/cursos>. Acesso em: 17 set. 2020.

▪ DATASTAX. Datastax for Developers. Disponível em:


<https://academy.datastax.com/planet-cassandra/what-is-NOSQL>. Acesso
em: 17 set. 2020.

▪ DEVMEDIA. NoSQL para Programadores. Disponível em:


<https://www.devmedia.com.br/guia/nosql-e-mongodb/34482>. Acesso em: 17
set. 2020.

▪ __________. Busca DevMedia – NOSQL. Disponível em:


<http://www.devmedia.com.br/busca/?txtsearch=NOSQL&tipo=15&site=0>.
Acesso em: 17 set. 2020.

▪ EMC. Executive Summary. Disponível em:


<https://www.emc.com/leadership/digital-universe/2014iview/executive-
summary.htm>. Acesso em: 17 set. 2020.

▪ NORTHEASTERN UNIVERSITY. How Much Data is Produced Every Day?


2016. Disponível em: <http://www.northeastern.edu/levelblog/2016/05/13/how-
much-data-produced-every-day>. Acesso em: 17 set. 2020.

▪ SPARKS, Robert. FAQ: What does “Soft-State” mean? In: Way Back Machine,
2009. Disponível em:
<http://web.archive.org/web/20120630030359/http://www.tekelec.com/tekelec
-blog/index.php/2009/07/faq-what-does-soft-state-mean/>. Acesso em: 17 set.
2020.

Bootcamp Analista de Banco de Dados – Página 19 de 147


▪ STEPPAT, Nico. Banco de dados não relacionais e o movimento NoSQL. In:
Caelum Blog, 2009. Disponível em: <http://blog.caelum.com.br/bancos-de-
dados-nao-relacionais-e-o-movimento-NOSQL/>. Acesso em: 17 set. 2020.

▪ _____________. NoSQL – Do teorema CAP para P? (A|C): (C|L). In: Caelum


Blog, 2011. Disponível em: <http://blog.caelum.com.br/NOSQL-do-teorema-
cap-para-paccl/>. Acesso em: 17 set. 2020.

Bootcamp Analista de Banco de Dados – Página 20 de 147


Capítulo 2. Categorias de Bancos de Dados Não Relacionais

Devido aos diferentes cenários nos quais os bancos de dados não relacionais
são necessários, diferentes tipos de soluções e abordagens foram criadas e
disponibilizadas para o mercado.

Durante este capítulo, vamos abordar os quarto tipos principais de bancos de


dados não relacionais mais reconhecidos, abordando sua aplicação, vantagens e
desvantagens. Ao final, como material complementar, serão sugeridos vários casos
de usos que visam ilustrar como grandes organizações vêm adotando este tipo de
soluções, e qual o ganho que elas estão obtendo.

2.1. Chave / Valor - Conceituação

O modelo mais simples, tanto em termos de funcionamento quanto de


entendimento, são os bancos de dados do tipo Chave/Valor.

Neste modelo, os dados (valor) são armazenados em uma estrutura que


possui uma chave vinculada para possibilitar a recuperação da informação. Estas
chaves podem ser tratadas de forma literal ou armazenadas como hashs por parte
dos bancos de dados, e os valores tipicamente são tratados como sequenciais
binários, não sendo interpretados ou trados pelo banco de dados.

Bootcamp Analista de Banco de Dados – Página 21 de 147


Figura 5 – Armazenamento de chave/valor típico.

Fonte: http://amanbinny.blogspot.com.br/2014/11/introduction-about-NOSQL-data-
models.html.

Ao realizar a inserção de uma informação, é fornecida uma chave única que


permite que esta informação seja recuperada em um momento futuro, porém não é
possível realizar uma consulta baseando-se em alguma informação do valor
armazenado. A recuperação, por fim, utiliza a mesma chave como acesso ao dado
armazenado.

Esse tipo de tratamento da informação fornece um meio de acesso muito


rápido, no qual a informação é recuperada diretamente de seu endereço de memória
e nenhuma estrutura complexa é usada no processo.

Opcionalmente, estes bancos de dados fornecem mecanismos de expiração


das chaves, garantindo que não sejam guardados em memória dados que, por
ventura, não tenham sido requisitados após um determinado período de tempo, como
acontecem em sessões de usuário em uma aplicação web por exemplo. Após um

Bootcamp Analista de Banco de Dados – Página 22 de 147


tempo de inatividade, a sessão simplesmente expira e os dados são descartados da
memória, necessitando que o usuário realize uma nova autenticação.

O ponto de observação no uso deste modelo é a necessidade de modelar


chaves significativas para tratar o volume de dados requisitados, o que pode se tornar
complexo, dependendo do volume de dados trafegados. Além disto, seu uso em
cenários onde o estado do dado armazenado no valor tenha relevância, como critério
de recuperação da informação, é impraticável neste cenário, sendo indicados para
isso outros modelos de bancos não relacionais.

2.2. Chave / Valor - Aplicações

Devido a suas características de armazenamento e acesso à informação, o


uso mais típico para os bancos de dados do tipo chave/valor é para armazenamento
de cache, sessões, contadores de desempenho, filas de processamento e gestão de
eventos dentro de uma aplicação.

O armazenamento de cache distribuído pode permitir que informações pré-


processadas sejam disponibilizadas a um conjunto maior de usuários que requisitam
essa determinada informação. Esse armazenamento pode representar desde
entidades de negócios sendo requisitadas por diversas fontes, quanto para retornar,
por exemplo, documentos html pré-compilados, imagens, scripts e qualquer outra
informação que tenha grande demanda de leitura e pouca alteração dentro do ciclo
de vida da aplicação.

O mesmo serve para sessões de usuários ou qualquer outra informação


pertinente a um ciclo de uso restrito a um contexto que tende a expirar após um tempo
de inatividade.

Além disso, a velocidade de acesso à informação na memória torna esse


modelo de armazenamento muito utilizado para gerenciar contadores de performance
para análise em painéis de tempo real, como por exemplo o número de requisições a

Bootcamp Analista de Banco de Dados – Página 23 de 147


uma determinada funcionalidade ou o total de vendas realizadas de uma determinada
localização.

2.3. Documentos - Conceituação

Bancos de dados do tipo documento possuem um modelo de armazenamento


parecido com tipo chave/valor, porém os dados armazenados são subestruturados e
relevantes para o contexto do banco de dados, que passa a fornecer mecanismos de
consultas baseados nestas informações.

Figura 6 – Modelo de armazenamento em documentos.

Fonte: https://dzone.com/articles/a-primer-on-open-source-NOSQL-databases.

Surgiram basicamente da necessidade de se recuperar uma estrutura de


dados por sua chave, mas que permitisse uma navegação em níveis e até um filtro
condicional simplificado para coleções.

Apesar da relevância do dado armazenado para o contexto do banco de


dados, diferente do que acontece em um banco de dados relacional, não existe a
necessidade de um esquema previamente definido ou uma normalização dos dados
persistidos, podendo diversos documentos dentro de um único conjunto de dados
possuírem diferentes composições de dados.

Bootcamp Analista de Banco de Dados – Página 24 de 147


Sendo assim, os dados são armazenados muitas vezes em estruturas como
o JSON (Javascript Object Notation) ou XML, e se aproximam muito do modelo usado
no desenvolvimento de aplicativos, principalmente sob o paradigma orientado a
objetos, fazendo com que haja um grande conforto e familiaridade por parte do
programador ao adotar esse tipo de banco de dados.

As entidades são armazenadas de forma autocontida, juntamente com suas


composições. Os relacionamentos e as agregações são representados pela chave de
acesso ao objeto em sua própria estrutura de armazenamento, e não há uma
navegação direta para o objeto.

Figura 7 – Navegação entre documentos.

Fonte: https://www.slideshare.net/fabiofumarola1/9-document-oriented-databases.

As consultas e os filtros podem ser realizados em qualquer nível da hierarquia


de armazenamento, porém, consultas muito complexas ou profundas podem
representar uma grande perda de desempenho, requisitando muitas vezes muita
memória e muito processamento por parte do gerenciador de banco de dados.

Apesar de várias soluções de mercado permitirem a criação de índices que


melhoram o desempenho destas consultas consideravelmente, a própria natureza da
forma como os dados são armazenados e a falta de relacionamento real entre as
entidades tornam a realização de consultas complexas, não recomendadas para esse
modelo de banco de dados não relacional.

Bootcamp Analista de Banco de Dados – Página 25 de 147


2.4. Documentos – Aplicações

A possibilidade de possuir um esquema flexível na composição dos dados,


permitindo que sejam aplicados filtros nos valores retornados, torna esse tipo de
banco de dados ideal para cenários que reflitam uma grande granularidade de dados,
como em um catálogo de produtos, conteúdo informativo ou inteligência operacional.

Esse é o típico cenário de um e-commerce ou um catálogo de locação por


exemplo, em que um determinado produto possui um conjunto relevante de dados,
que podem não ser compartilhados entre todos os produtos.

Informações como descrição, valor, disponibilidade e fabricante podem ser


comuns a todos os produtos, porém requisitos técnicos e operacionais são muito
particulares, e podem muitas vezes apresentar diferenças mesmo dentro de um único
produto. Para uma TV com recursos Smart, o número de processadores lógicos,
sistema operacional e informações de conectividade são tão relevantes quanto para
um smartphone ou um computador, porém TVs convencionais não possuem
necessidade da análise de tais requisitos, e mesmo assim o usuário pode querer que
sejam retornados em sua consulta, ambos os tipos de televisores para decidir sua
compra.

Esses cenários de granularidade de informações e de filtros simples são os


ideais para a utilização de bancos de dados do tipo documento, principalmente
quando envolvem a necessidade de um esquema flexível e dinâmico, que permita
que novas estruturas de dados sejam armazenadas sem a necessidade de se alterar
o banco de dados ou de migrar os dados antigos.

2.5. Colunar – Conceituação

Os bancos de dados colunares ou baseado em famílias de colunas são os


tipos de bancos de dados não relacionais mais próximos do conceito de tabelas
apresentado no modelo relacional.

Bootcamp Analista de Banco de Dados – Página 26 de 147


Eles foram um dos primeiros modelos de bancos de dados a surgir, com o
objetivo de tratarem a não normalização de dados, usados especialmente para
cenários em que um cenário relacional teríamos cada uma das tuplas com apenas
um determinado conjunto de dados populados.

Desta forma, o banco de dados do tipo colunar apresenta um incontável


número de linhas, porém cada uma dessas linhas utiliza apenas uma fração das
colunas disponíveis na tabela.

Figura 8 – Modelo de armazenamento colunar.

Fonte: https://stackoverflow.com/questions/19519688/differences-between-NOSQL-
databases.

Sua principal vantagem sobre o modelo relacional está no fato de podermos


associar um registro a novas colunas, sem a necessidade de alteração do esquema
de dados e sem migração da linha atual. Além disso, uma única coluna pode ser
usada como agrupador de diversas outras colunas, atuando como um mapa de
colunas para os dados.

Este modelo propicia principalmente a disponibilidade e a replicação dos


dados, dando grande flexibilidade para trabalhar grandes volumes de informações.
Dos modelos de bancos de dados não relacionais, é o que apresenta maior
complexidade na modelagem e organização dos dados, apesar de trabalhar em um
contexto mais próximo do relacional.

Bootcamp Analista de Banco de Dados – Página 27 de 147


2.6. Colunar – Aplicações

Esse modelo de banco de dados possui uma arquitetura especial para tratar
e armazenar grandes volumes de dados distribuídos geograficamente. Além disso,
ele é preparado para estar sempre disponível para escrita, uma vez que a replicação
e o balanceamento dos dados entre os nós do cluster são realizados de forma
transparente e automática.

São recomendados e adequados para serem conectados a ferramentas de


extração e análises de dados, capazes de tratar e identificar padrões e correlação de
dados.

2.7. Grafos – Conceituação

Os bancos de dados para armazenamento de estruturas de grafos são


especializados em armazenar de forma autocontida toda a estrutura de
relacionamentos entre diferentes entidades de um determinado domínio, sem se
preocupar com referências cíclicas e autorrelacionamentos.

Os relacionamentos são representados na forma de navegações, e o tipo de


relacionamento entre duas diferentes entidades é tão importante para o banco de
dados quanto os dados propriamente ditos.

Bootcamp Analista de Banco de Dados – Página 28 de 147


Figura 9 – Modelo de armazenamento em grafos.

Fonte: https://neo4j.com/developer/guide-build-a-recommendation-engine/.

2.8. Grafos - Aplicações e casos de uso

Neste modelo de banco de dados, consultas podem ser realizadas baseadas


em um determinado atributo da entidade ou na forma como ela se relaciona com
outras entidades.

Este modelo de dados é muito usado em sistemas de relacionamentos sociais


e em e-commerce para sugestão de produtos.

Consultas como “atores que participaram do filme ABC”, “Produtos


visualizados por XYZ” ou “amigos de Fulano que também moram no Brasil”, permitem
recuperar informações baseadas em um determinado contexto de relacionamento de
forma natural e com grande desempenho.

Bootcamp Analista de Banco de Dados – Página 29 de 147


Resumo do capítulo

As diferentes necessidades de armazenamento de dados não relacionais


levaram ao aparecimento de diferentes soluções de banco de dados: Chave/Valor,
Documentos, Colunar e Grafos.

Os bancos de dados do tipo chave/valor fornecem um mecanismo de


armazenamento e recuperação de informações através de uma chave única, porém
não permitem o tratamento das informações contidas no valor armazenado.

Já os bancos de dados do tipo documentos, levam em consideração os dados


armazenados como valores como parte da entidade principal, são muito próximos dos
modelos de desenvolvimento, principalmente o modelo orientado a objetos. Porém,
apesar de permitirem consultas com filtros de dados, eles podem apresentar perda
de desempenho em consultas muito complexas.

Bancos de dados colunares, também como conhecidos como “famílias de


colunas”, apresentam uma estrutura próxima do esquema tabular dos bancos de
dados relacionais tradicionais, sendo muito usados para análises de grandes volumes
de dados.

Por fim, os bancos de dados orientados a grafos abrem a possibilidade de


trabalhar a informação além dos estados dos atributos de uma entidade, navegando
pelos relacionamentos entre os dados.

Material complementar

▪ AMAZON. Amazon DynamonDB. Disponível em:


<https://aws.amazon.com/dynamodb/>. Acesso em: 17 set. 2020.

▪ KERZNER, Mark; MANIYAM, Sujee. Chapter 10. Hadoop Use Cases and Case
Studies. In: Hadoop Illuminated. Hadoop Illuminated Alpha, 2016. Disponível
em:

Bootcamp Analista de Banco de Dados – Página 30 de 147


<http://hadoopilluminated.com/hadoop_illuminated/Hadoop_Use_Cases.html>
. Acesso em: 17 set. 2020.

▪ MONGODB. Use Cases. Disponível em:


<https://docs.mongodb.com/ecosystem/use-cases/>. Acesso em: 17 set. 2020.

▪ Neo4j. The World of Graphs – Powered by Neo4j. Disponível em:


<https://neo4j.com/customers/>. Acesso em: 17 set. 2020.

▪ NoSQL. Disponível em: <http://NOSQL-database.org/>. Acesso em: 17 set.


2020.

▪ POPESCU, Alex; BACALU, Ana-Maria. 3 CouchDB Case Studies. In:


MyNoSQL homepage, 2010. Disponível em:
<http://NOSQL.mypopescu.com/post/746667801/3-couchdb-case-studies>.
Acesso em: 17 set. 2020.

▪ SADALAGE, Pramod. NoSQL Databases: Na Overview. In: ThoughtWorks


Blogs, 2014. Disponível em:
<https://www.thoughtworks.com/insights/blog/nosql-databases-overview>.
Acesso em: 17 set. 2020.

▪ WOOD, John. CouchDB: A Case Study. In: John P. Wood collection of


thoughts, 2009. Disponível em: <http://johnpwood.net/2009/06/15/couchdb-a-
case-study/>. Acesso em: 17 set. 2020.

Bootcamp Analista de Banco de Dados – Página 31 de 147


Capítulo 3. Adoção da Tecnologia

Quando estudamos a adoção de uma nova tecnologia, principalmente no


meio corporativo, devemos sempre analisar com critério as opções e não nos
apegarmos à adoção tendenciosa de tecnologia, motivados por algum fator se não o
do ganho real para a aplicação, os negócios e principalmente para o usuário final.

Neste capítulo vamos abordar alguns fatores a serem considerados quando


formos adotar um banco de dados NOSQL, os erros mais comuns para quem está
iniciando essa transição e falar um pouco do modelo misto de uso de bancos de
dados.

3.1. Considerações ao escolher um banco de dados NOSQL

O primeiro passo antes de realizar a adoção de um banco de dados, seja ele


relacional ou não, é ter uma visão bem clara sobre qual tipo de dado será persistido,
como ele será consumido e qual seu cenário de aplicação.

Uma vez que conseguimos separar os repositórios de dados conforme seu


uso dentro da aplicação, precisamos definir e entender a volumetria de dados que
será trabalhada neste banco. Qual o volume de leituras e escritas serão necessários,
nível de concorrência e origem destes dados, de forma que possamos desenhar um
cenário de distribuição e replicação adequado a sua utilização.

Feito isso, seremos capazes de decidir sobre qual modelo de banco de dados
iremos adotar, seja ele relacional ou não relacional, e no caso deste último, qual tipo
de banco de dados não relacional usar em cada um dos diferentes repositórios da
aplicação.

Tendo definido qual o tipo de banco de dados a ser usado, o próximo passo
é analisar alguns fatores relevantes quanto aos modelos disponíveis dentro desta
categoria, analisando características relacionadas aos fornecedores, aos modelos,
quanto ao perfil da sua empresa e quanto à qualidade do produto a ser adotado.

Bootcamp Analista de Banco de Dados – Página 32 de 147


▪ Fornecedores:

Ao adotarmos um sistema de banco de dados, atenção quanto aos


fornecedores é uma das principais preocupações que devemos ter, uma vez que a
troca de tecnologia de persistência pode muitas vezes ser muito dispendiosa e até
inviável do ponto de vista financeiro e arquitetural.

Por isso precisamos ter atenção quanto ao nível de atuação e atenção do


fornecedor da tecnologia, mesmo que este seja mantido pela comunidade.

Um bom fornecedor deve ser transparente e fornecer um bom suporte ao


produto, além de uma documentação devidamente atualizada e consistente, fornecer
conteúdo de treinamento e tutoriais, assim como um ambiente seguro de testes e
homologação do produto.

Verifique sempre a frequência de atualização do produto e analise as chances


de ele ser descontinuado.

▪ Modelos:

Sobre o banco de dados em si, devem ser verificadas as ferramentas de


administração disponíveis, o desempenho diante da volumetria medida e a forma de
licenciamento do produto.

▪ Perfil da empresa:

Devemos ter em mente o quanto a empresa está disposta a investir em


infraestrutura e mão de obra qualificada para suportar a operação com este tipo de
banco de dados. A adoção sem as devidas preparações e sem atender aos requisitos
de infraestrutura, definidos pelo fornecedor da solução, pode acarretar no fracasso do
processo de adoção da ferramenta.

Além disso, é necessário levar em consideração o papel do time de TI dentro


da empresa e o nível de inovação da empresa, uma vez que esses fatores passam a
ser fundamentais para a adoção de uma tecnologia de bancos de dados não
relacionais.

Bootcamp Analista de Banco de Dados – Página 33 de 147


▪ Qualidade:

Por fim, devemos nos atentar aos fatores de robustez, confiabilidade e


recuperação de falhas que a solução nos fornece.

O banco de dados deve conseguir suportar quedas e recuperações


automáticas, garantindo a integridade da informação dentro dos níveis esperados e
tolerados pelo negócio da empresa.

Além disso, a recuperação de falhas deve ser possível de forma rápida


descomplicada, mantendo o menor downtime possível.

3.2. Erros comuns ao adotar a tecnologia

Dentre os erros mais comuns encontrados pelas pessoas que estão


começando a adotar tecnologias NOSQL, podemos destacar cinco:

1. Tentar substituir seu banco de dados SQL por um banco de dados


NOSQL.

Muitas pessoas, quando estão iniciando suas pesquisas dentro do universo


dos bancos de dados não relacionais, tentam simplesmente trocar toda a sua camada
de persistência por bancos de dados não relacionais, muitas vezes inclusive sem um
critério claro para a adoção de uma determinada tecnologia.

Como foi visto até aqui, cada banco de dados possui um cenário ideal de
aplicação, e muitas vezes uma única solução envolve vários destes cenários de
dados. O principal cuidado neste ponto está em saber quando e qual banco de dados
adotar dentro da sua aplicação, e entender principalmente que alguns cenários
simplesmente não são adequados ao uso de bancos de dados NOSQL.

2. Adotar o banco de dados NOSQL do momento.

Outro erro comum para quem está experimentando novas tecnologias, é


adotar aquele produto que está em evidência na comunidade por algum motivo. É

Bootcamp Analista de Banco de Dados – Página 34 de 147


necessário sim uma atenção aos bancos de dados que estão em destaque no
momento, mas sempre sem deixar de lado a análise dos itens que discutimos no item
anterior desta apostila.

3. Tentar lidar com novas tecnologias, usando velhos processos e


paradigmas.

Adotar uma nova tecnologia exige que saibamos abrir mão de velhos
conceitos e velhos paradigmas. Principalmente quando lidamos com o modelo
NOSQL, no qual há uma quebra grande de conceitos em relação ao modelo
relacional. Temos que nos desapegar de velhas práticas e entender que as mudanças
de desenho e arquitetura serão inevitáveis e necessárias.

4. Pensar nos bancos de dados NOSQL apenas pelo fator de escalabilidade.

Não podemos adotar um banco de dados NOSQL esperando apenas poder


escalar nossa aplicação horizontalmente. Existem uma série de fatores a serem
analisados e cenários a serem considerados, não penas sobre qual banco de dados
adotar, mas também sobre qual o benefício que ele irá trazer para a aplicação e para
o usuário.

5. Achar que o processo de persistência será trivial e transparente.

Muitas pessoas buscam as tecnologias NOSQL acreditando que a


distribuição e replicação dos dados se dará de forma transparente e sem a
necessidade de uma estruturação e conhecimento técnico aprofundado sobre o
assunto. Porém, apesar dos bancos de dados NOSQL terem estas características
nativamente, ainda assim é necessário um trabalho de preparação, estruturação e
configuração deste ambiente. Estas operações são sim muito mais fáceis e de baixo
impacto quando comparadas às alternativas relacionais, porém ainda assim não são
triviais.

Bootcamp Analista de Banco de Dados – Página 35 de 147


3.3. Persistência poliglota

Um único software possui diferentes necessidades de persistência e


recuperação de dados, que devem saber trabalhar juntas para promover o melhor
desempenho para a aplicação.

Um movimento que vem tomando força é o uso da chamada persistência


poliglota, que busca aproveitar para os diferentes cenários da aplicação adotar o
melhor cenário de banco de dados, seja ele relacional ou não relacional.

Figura 10 – Exemplo de persistência poliglota.

Fonte: https://pt.slideshare.net/gscheibel/no-sql-poliglotav2.

Para ilustrar melhor a ideia, vamos adotar como exemplo um site de consulta
de preços online. Na adaptação deste cenário, vamos imaginar que este site tem
como papel acessar diversos outros sites de e-commerce, catalogar os diferentes
produtos e preços e permitir ao usuário comparar as diferentes opções de compra.

O nosso site tem como primeiro problema a questão de desempenho, pois


estando o usuário autenticado ou não, há uma série de produtos e dados de
fornecedores que são estáticos e apresentam pouca ou nenhuma mudança durante

Bootcamp Analista de Banco de Dados – Página 36 de 147


o decorrer do dia; no máximo atualizações programadas de preço e condições de
pagamento.

Além disso, diferentes sites de e-commerce podem adicionar diferentes


informações técnicas e características de um produto.

Todos os dados de navegação e auditoria do sistema são persistidos para


melhorar a experiência do usuário e, posteriormente, serem oferecidas sugestões e
promoções futuras a partir do perfil de interesse do usuário.

Por fim, nosso site ainda possui um recurso de programa de fidelidade que
fornece pontos que podem ser usados como tíquetes de desconto ou até mesmo
serem resgatados como dinheiro.

Analisando então esse cenário, vamos começar a mapear os tipos de bancos


de dados que podemos utilizar:

▪ Sessão e autenticação.

A parte de sessão armazena os dados da navegação atual do cliente no site,


podendo inclusive interagir com os dados salvos em cookies para contextualizar um
usuário não logado.

Essa informação necessita de uma resposta muito rápida, pois todas as


requisições realizadas no site passarão por ela, que armazena informações de
contexto da pesquisa do usuário, seus dados, permissões e outros itens relevantes
para o fluxo de navegação do usuário no site.

Para este cenário, um banco de dados do tipo chave/valor, como o Redis,


atende perfeitamente ao cenário, uma vez que fornece acesso rápido à chave de
registro, que retorna o objeto de contexto do usuário, não sendo necessária nenhuma
pesquisa ou consulta ao conteúdo.

Bootcamp Analista de Banco de Dados – Página 37 de 147


▪ Cache.

Vários objetos recebem poucas alterações, porém tendem a sofrer muitas


consultas, seja do próprio usuário quando está indeciso, seja de muitos outros,
principalmente quando há alguma promoção anunciada.

Neste caso, o uso de um banco de dados que também armazene estes


objetos em cache, como um banco de dados de chave/valor, pode trazer um grande
desempenho; outra coisa é armazenar também as páginas pré-compiladas em cache,
caso a plataforma de desenvolvimento escolhida não faça isso nativamente.

▪ Catálogo de produtos.

O catálogo de produtos é o cenário ideal para os bancos de dados do tipo


documento, pois permitem diferentes estruturas de dados que podem ser
pesquisados juntos sem qualquer malabarismo, aceitando ainda filtros baseados em
características que podem ou não existir.

▪ Programa de fidelidade.

O programa de fidelidade necessita de um banco de dados relacional


convencional, como o SQLServer, Oracle, MySQL ou Postgress, uma vez que deve
garantir isolamento e integridade relacional na computação, consulta e consumo de
pontos.

▪ Análise de navegação e log de auditoria.

As informações de navegação do usuário e auditoria de sistema ficam


delegadas a bancos de dados colunares como o Cassandra, que podem receber um
grande volume de informações para serem analisadas e para extrairmos informações
de sugestão ao usuário. Estas informações serão condensadas e armazenadas em
um bando de dados de grafos.

Bootcamp Analista de Banco de Dados – Página 38 de 147


▪ Sugestão de compras.

Uma vez que processamos as informações, as condensamos e


armazenamos em termos de relacionamento em um banco de dados de grafos, para
que possamos identificar e sugerir possíveis combinações e promoções para o
usuário, baseado em seus interesses.

Quando ele navegar pelo site, teremos as informações sobre quais tipos de
produtos ele pesquisa, como por exemplo jogos, se esses jogos possuem
plataformas, gêneros e estilos. Baseado nisso, podemos analisar quais jogos ele
visualizou e não comprou, ou até mesmo quais gêneros ele mais pesquisa, ou ainda
o que outras pessoas que pesquisaram os mesmos produtos, compraram.

Veja que neste cenário o tipo de relacionamento entre as entidades apresenta


grande relevância para o resultado da consulta.

Resumo do capítulo

A migração para tecnologias NOSQL requer uma análise profunda do cenário


de utilização dos dados, desde como eles serão capturados, quando serão usados e
qual o volume de informações será coletada.

Devemos escolher com cuidado fornecedores que garantam suporte e


continuidade ao produto, focando nos produtos que melhor se adequam a realidade
da empresa.

Feito isso, devemos trabalhar com o pensamento de utilizar uma arquitetura


de persistência mista, onde os diferentes tipos de bancos de dados trabalham juntos
para compor um cenário completo para a aplicação.

Bootcamp Analista de Banco de Dados – Página 39 de 147


Material complementar

▪ PRITCHETT, Dan. Base: An Acid Alternative. In: Queue, n.3, v.6. 2008.
Disponível em: <http://queue.acm.org/detail.cfm?id=1394128>. Acesso em: 17
set. 2020.

Bootcamp Analista de Banco de Dados – Página 40 de 147


Capítulo 4. O uso de NOSQL em produção

O uso de bancos de dados em produção sempre exige uma série de cuidados


e atenções devido a criticidade das operações. Algumas medidas como a
necessidade de manutenções periódicas, backups e testes de recuperação de
desastres são características que não dependem de qual tipo de banco de dados
usamos.

Este capítulo tem o intuito de esclarecer os pontos fundamentais sobre as


operações de escalabilidade e rotinas de recuperação necessárias para se manter o
funcionamento do banco de dados em produção.

4.1. Escalabilidade

Na era dos bancos de dados relacionais, sempre que falávamos em escalar


o servidor já vinha à mente a necessidade de efetuar paradas programadas no
sistema. Quando pensamos na escalabilidade desses sistemas, muitas vezes
pensamos em termos de escala vertical, na qual ocorre o aumento dos recursos
computacionais do servidor, sejam eles memória, disco ou processador. Neste
cenário, mesmo que haja suporte, a hot swap em equipamentos físicos ou máquinas
virtualizadas tem a necessidade de algum procedimento em relação ao banco de
dados, para que ele reconheça as novas modificações aplicadas. E, na grande
maioria dos sistemas, isso implica em um tempo de indisponibilidade das aplicações.

Opcionalmente, os sistemas gerenciadores de bancos de dados fornecem


mecanismos de distribuição e espelhamento de dados horizontais, em que servidores
conectados a uma mesma rede, trabalham em um cluster para suportar a aplicação.
Porém, essas configurações não são simples e requerem às vezes procedimentos
complexos para a inclusão de novos nós e a manutenção dos mesmos, sem falar que
em alguns cenários de configuração, a troca de nós, por motivo de failover, não ocorre
de forma transparente, havendo também uma indisponibilidade momentânea no
processo.

Bootcamp Analista de Banco de Dados – Página 41 de 147


A principal diferença em relação aos bancos de dados não relacionais, em
termos de escalabilidade, é a facilidade com que ela pode ser configurada e a
transparência com que isso ocorre.

Na maioria dos sistemas NOSQL, o procedimento de inclusão de um novo nó


no cluster é realizado de forma muito simples, e não acarretam em parada de sistema.
Isso porque ele já é arquiteturalmente projetado para trabalhar com diversos nós com
menor poder de hardware, nativamente distribuindo o processamento na maioria dos
modelos.

4.2. Manutenção e backup

Todas os gerenciadores de bancos de dados NOSQL fornecem recursos


equivalentes para backup ou despejo dos dados, além de restauração sobre
demanda, como acontece com os bancos de dados relacionais tradicionais. Alguns
modelos como o Cassandra, fornecem opção de backup incremental dos dados.

O principal diferencial é que nos bancos de dados não relacionais, os


intervalos e scripts de backup são criados usando os recursos do sistema operacional,
usando seus agendadores de tarefas nativas para agendar e executar scripts
localmente.

Por boa prática, é recomendado que se planeje um tempo de retenção dos


backups. Você deve planejar para que os backups relativos a períodos temporais
próximos sejam armazenados em maior conjunto e por um curto período de tempo.
Você pode, por exemplo, guardar por até uma semana os backups diários, e, antes
do expurgo desses backups, guardar o backup do último dia da semana por pelo
menos um mês, de forma que dentro de um mês você tenha um backup para cada
semana de trabalho. Ao final de um ano, o ideal é que você tenha no mínimo o backup
referente ao último dia de cada mês trabalhado, e que tenha sempre no mínimo um
backup dos anos anteriores guardados.

Veja o exemplo abaixo, representando três anos de operações:

Bootcamp Analista de Banco de Dados – Página 42 de 147


Data do Backup Backup Tipo Retenção
31/12/2029 bkp_1 Último Backup dos anos seguintes Indefinida
Ano

31/12/2030 bkp_365 Último Backup dos anos seguintes Indefinida


30/06/2031 bkp_530 Último Backup do mês 1 Ano
30/07/2031 bkp_560 Último Backup do mês 1 Ano
30/08/2031 bkp_590 Último Backup do mês 1 Ano
30/09/2031 bkp_620 Último Backup do mês 1 Ano
30/10/2031 bkp_650 Último Backup do mês 1 Ano
30/11/2031 bkp_680 Último Backup do mês 1 Ano
Mês

31/12/2031 bkp_710 Último Backup do mês 1 Ano


Último Backup do mês (último do
30/01/2032* bkp_740 ano) Indefinida
28/02/2032 bkp_770 Último Backup do mês 1 Ano
30/03/2032 bkp_800 Último Backup do mês 1 Ano
30/04/2032 bkp_830 Último Backup do mês 1 Ano
28/05/2032 bkp_860 Último Backup do mês 1 Ano
03/06/2032 bkp_867 Último dia da Semana 1 Mês
Semana

10/06/2032 bkp_874 Último dia da Semana 1 Mês


17/06/2032 bkp_881 Último dia da Semana 1 Mês
24/06/2032* bkp_888 Backup do dia (último da semana) 1 Mês
25/06/2032 bkp_889 Backup do dia 1 Semana
26/06/2032 bkp_890 Backup do dia 1 Semana
27/06/2032 bkp_891 Backup do dia 1 Semana
Dia

28/06/2032 bkp_892 Backup do dia 1 Semana


29/06/2032 bkp_893 Backup do dia 1 Semana
30/06/2032* bkp_894 Backup do dia (último do mês) 1 Ano

Além disso, tenha sempre os backups armazenados em pelo menos três


mídias e locais distintos, de forma que uma delas permita a restauração imediata em
caso de problema pontual. Este pode ser um local de rede. Tenha também um
segundo backup em uma mídia removível, armazenada em uma caixa cofre resistente

Bootcamp Analista de Banco de Dados – Página 43 de 147


a desastres naturais e interferências ambientais, que permita a restauração em caso
de dano generalizado. E, por último, um backup em nuvem, que permita download e
recuperação em caso de catástrofe.

Por fim, sempre programe e teste restaurações em ambientes de


homologação para garantir que os dados estejam íntegros e aceitáveis.

Resumo do capítulo

As operações de manutenção e escala de bancos de dados não relacionais


não diferem muito em termos de boas práticas, quando comparadas a bancos de
dados relacionais. As principais diferenças estão nas facilidades e ferramentas
disponíveis para a manutenção dos mesmos.

Material complementar

▪ TAPADAR, Shahjahan. Cassandra – The Right Data Store for Scalability,


Performance, Availability and Maintainability. In: RapidValue, 2015. Disponível
em: <http://www.rapidvaluesolutions.com/tech_blog/cassandra-the-right-data-
store-for-scalability-performance-availability-and-maintainability/>. Acesso em:
17 set. 2020.

Bootcamp Analista de Banco de Dados – Página 44 de 147


Capítulo 5. MongoDB

5.1. Introdução ao MongoDB

O MongoDB é um sistema gerenciador de banco de dados NOSQL, escrito


em C++ e baseado em documentos. É multiplataforma, gratuito e open source.
É, por natureza, um SGBD distribuído, possuindo nativamente, em seu core, recursos
para prover alta disponibilidade, escalabilidade horizontal e distribuição
geográfica dos dados.

Figura 11 – Alta Disponibilidade, Escalabilidade Horizontal e Distribuição de


Dados no MongoDB.

Fonte: MongoDB Inc. (2019).

Armazena os dados em documentos no formato JSON, que fornecem um


esquema dinâmico, onde campos podem variar de documento para documento e a
estrutura de dados pode ser alterada ao longo do tempo (polimorfismo fluente).

Bootcamp Analista de Banco de Dados – Página 45 de 147


Figura 12 – Representação Relacional x NOSQL JSON.

Fonte: Gustavo (2019).

O desenvolvimento do MongoDB teve início em outubro de 2007, pela 10gen


(atual MongoDB Inc.), e sua primeira versão pública foi lançada em fevereiro de
2009.

O nome MongoDB é uma contração de Mongo DataBase, sendo que a


palavra Mongo foi inspirada na palavra de origem inglesa Humongous, que em uma
tradução popular, significa gigantesco. No site do fabricante, informa que os seus
criadores (Dwight Merriman, Kevin P. Ryan e Eliot Horowitz) foram também
fundadores de grandes empresas de internet, como por exemplo a DoubleClick. Já
nesse passado não tão longínquo, enfrentaram bastantes problemas para armazenar
e manipular as grandes massas de dados geradas por essas empresas, com as
tecnologias disponíveis na época. Isso os levaram à criação do MongoDB, com o
propósito principal de ser um SGBD capaz de gerenciar bases de dados gigantescas,
de forma altamente escalável e performática.

Além desse propósito, os seus criadores expressaram, na própria logo do


produto, uma outra filosofia que trouxeram como bagagem das experiências que
tiveram nessas empresas de desenvolvimento que fundaram anteriormente,
acreditando que codificar tem que ser algo natural. Dessa forma, eles esperam que
a experiência de programar ou administrar o MongoDB seja natural e simples como
uma folha de uma árvore.

Bootcamp Analista de Banco de Dados – Página 46 de 147


No market share referente ao mercado de bancos de dados NOSQL, o
MongoDB é um dos grandes líderes, e, no quadrante mágico de sistemas
gerenciadores de bancos de dados do Gartner, vem se aproximando dos líderes,
como mostrado na divulgação de 2018 abaixo:

Figura 13 – Quadrante Mágico de SGBDs.

Fonte: Gartner (2018).

A popularização do MongoDB entre os desenvolvedores e administradores


de bancos de dados, além, é claro, da sua facilidade de uso, qualidade e utilidade, se
deveu também à Universidade MongoDB online que foi criada
(https://university.mongodb.com). Com cursos em inglês totalmente gratuitos, muito
bem formatados com vídeos, exercícios e certificado de conclusão, abrange desde o
nível iniciante até o nível avançado para administradores do produto, além de ter uma
trilha para desenvolvedores Java, Python e JavaScript que desejem utilizar o
MongoDB para persistir os dados.

Bootcamp Analista de Banco de Dados – Página 47 de 147


5.2. Conceitos básicos e arquitetura do MongoDB

O MongoDB, em termos de arquitetura básica, possui a organização


hierárquica tradicional servidor → instância → banco de dados, similar à dos
SGBDs relacionais. Um servidor pode conter várias instâncias, com cada uma delas
respondendo em uma porta diferente, sendo a 27017, a padrão. Dentro de cada
instância, podem existir diversos bancos de dados, independentes entre si.

Um banco de dado MongoDB, uma vez que possui pouquíssimas


propriedades e parâmetros (não tem, por exemplo, um parâmetro de tamanho
máximo do banco), serve mais como um container, chamado de name space, para
organização lógica e/ou física, e para controle de segurança de acesso.

Para armazenar os documentos dentro de um banco de dados, o MongoDB


usa o conceito de Collection. Um banco de dados pode ter inúmeras collections,
sendo a quantidade limitada pelo número de arquivos permitidos pelo sistema
operacional em um diretório, ou pelo número de arquivos que podem ser abertos e
manipulados. Pelo mesmo motivo dos bancos de dados, uma collection serve como
uma organização lógica e física dos dados, bem como para controle de segurança de
acesso aos documentos que ela armazena.

Dessa forma, uma collection pode ter inúmeros documentos, que por sua
vez é o local onde os dados (registros) são armazenados, como mostrado no
esquema a seguir:

Bootcamp Analista de Banco de Dados – Página 48 de 147


Figura 14 – Visão geral da arquitetura do MongoDB.

Fonte: Gustavo Aguilar (2018).

Um documento no MongoDB é um registro (conceito similar ao de tupla do


mundo relacional), composto por pares de campos (fields) e valores (values), como
mostrado no exemplo abaixo:

Figura 15 – Campos e valores em um documento.

Fonte: MongoDB (2018).

Esses documentos possuem o formato JSON, mas internamente são


armazenados como documentos BSON. O BSON trata-se de um formato binário que
expande os tipos de dados padrões existentes na representação JSON,
disponibilizando outros tipos de dados, como int, long, date, floating point e
decimal128. Cada documento possui um tamanho máximo de 16 MB, mas esse
limite pode ser expandido usando um recurso do MongoDB chamado GridFS.

Fazendo uma analogia desses conceitos iniciais do MongoDB que foram


apresentados com as terminologias do mundo relacional, teríamos a correspondência
mostrada abaixo:

Bootcamp Analista de Banco de Dados – Página 49 de 147


Figura 16 – Conceitos NOSQL x Relacional.

Termos / Conceitos Relacionais Termos / Conceitos MongoDB

Fonte: Gustavo Aguilar (2018).

Para gerenciar como os dados são armazenados, o MongoDB disponibiliza,


nativamente, três mecanismos, chamados de engines, com cada um deles
apresentando um desempenho diferente para cargas de trabalho específicas:

▪ WiredTiger: é o mecanismo de armazenamento padrão a partir da versão


3.2 do MongoDB. É adequado para a maioria das cargas de trabalho e é
recomendado para novas implementações. Fornece controle de concorrência
a nível de documento, checkpoint, compactação, dentre outros recursos. No
MongoDB Enterprise, o WiredTiger também suporta criptografia.

▪ In-Memory: disponível no MongoDB Enterprise, ao invés de armazenar


documentos no disco, esse mecanismo os retém na memória para redução
da latência de leitura / escrita.

▪ MMAPv1: é o mecanismo de armazenamento padrão para a versão 3.0 e


anteriores do MongoDB, e foi descontinuado a partir da versão 4.0.

Além das engines acima, o MongoDB possibilita a utilização de mecanismos


de armazenamento externos e de terceiros (pluggable storage engines), para os
usuários se beneficiarem de novos recursos e configurações ideais para arquiteturas
específicas de hardwares.

Na parte de autenticação e segurança de acesso, para permitir que os


usuários se conectem na instância e manipulem os documentos das collections dentro
dos bancos de dados, o MongoDB fornece dois tipos de autenticação:

Bootcamp Analista de Banco de Dados – Página 50 de 147


▪ Autenticação local: feita usando-se um login interno do MongoDB, cujo
nome e senha são armazenados internamente, no banco de dados de
sistema.

▪ Autenticação integrada: feita usando-se um login externo ao MongoDB,


integrado à um dos sistemas de autenticação compatíveis: SCRAM, x.509
Certificates, LDAP* ou Kerberos*. (*somente na edição enterprise)

No quesito acesso aos recursos e dados, o MongoDB figura-se como


totalmente aderente ao controle orientado a role, o chamado RBAC (Role-Based
Access Control). Esse tipo de controle obriga que privilégios em objetos ou
funcionalidades sejam concedidos apenas para roles, ou seja, não podem ser
concedidos diretamente para um usuário. Dessa forma, as roles recebem os
privilégios (actions) nos recursos (resources), e são atribuídas aos usuários.

Para os usuários realizarem as atividades de configuração, administração e


utilização do MongoDB, existem várias ferramentas client de mercado, mas as
oficiais, desenvolvidas pelo próprio fabricante, são:

▪ Mongo Shell: ferramenta de linha de comando que possui todos os comandos


existentes para se configurar e interagir com o MongoDB.

Figura 17 – Mongo Shell.

Fonte: Gustavo Aguilar (2019).

Bootcamp Analista de Banco de Dados – Página 51 de 147


▪ MongoDB Compass: ferramenta gráfica client, que possui funcionalidades
para criar bancos de dados e coleções, bem como para manipulação de dados,
mas não para configurar o MongoDB. É uma ferramenta gratuita e pode ser
baixada direto do site do fabricante.

Figura 18 – Compass.

Fonte: Gustavo Aguilar (2019).

O Compass possui também um dashboard útil, com informações de


performance em tempo real acerca das coleções mais acessadas, operações mais
lentas, quantidade de operações nos documentos, uso da rede e de memória, como
mostrado no exemplo abaixo:

Figura 19 – Dashboard de Performance do Compass.

Bootcamp Analista de Banco de Dados – Página 52 de 147


5.3. Replica Set e Sharding

O MongoDB, em termos de arquitetura básica, possui a organização


hierárquica tradicional servidor → instância → banco de dados, similar à dos
SGBDs relacionais.

Como dito inicialmente, o MongoDB é um sistema gerenciador de banco de


dados distribuído nativo, e além dessa arquitetura básica, fornece recursos de alta
disponibilidade, particionamento de dados e replicação. Na implementação mais
simples para prover alta disponibilidade, usa-se o recurso de replica set do
MongoDB, que em linhas gerais, é um cluster de servidores com os dados sendo
replicados entre eles, de acordo com o fator de replicação configurado.

Nessa abordagem, as operações de escrita são feitas apenas no servidor


primário (primary). Entretanto, pode-se fazer operações de leituras nas réplicas
secundárias (secondary), para onde os dados são replicados de forma assíncrona,
através da replicação do oplog (arquivo contendo as transações feitas na réplica
primária). Dessa forma, o MongoDB se mostra como um SGBD distribuído do tipo
hierárquico quanto à topologia (hierarquia single-master) e assíncrono quanto à
consistência dos dados lidos.

Figura 20 – Replica Set.

Fonte: MongoDB (2018).

É com esse recurso que o MongoDB possibilita a distribuição de dados global,


comentada inicialmente nesse capítulo, uma vez que não há restrições para a
localização física das réplicas e cada cluster pode ter até 50 membros.

Bootcamp Analista de Banco de Dados – Página 53 de 147


Figura 21 – Distribuição Global de Dados com Replica Set.

Fonte: MongoDB (2018)

Como o MongoDB permite leituras nas réplicas secundárias de um cluster


replica set, é possível implementar a distribuição de cargas de leituras de forma
bem simples e nativa, permitindo a coexistência de workloads distintos no mesmo
ambiente, como mostrado no exemplo abaixo.

Figura 22 – Workloads distintos em um replica set.

Fonte: MongoDB (2018).

Para fornecer a alta disponibilidade e ter tolerância à falhas de hardware, caso


haja um problema com o servidor primário atual, o MongoDB implementa o
mecanismo de eleição de uma nova réplica primária. Através dele, é disparada

Bootcamp Analista de Banco de Dados – Página 54 de 147


uma votação para se eleger um novo servidor primário, caso ocorra um problema ou
indisponibilidade no servidor primário em voga.

Figura 23 – Eleição de novo secundário.

Fonte: Gustavo Aguilar (2018).

Uma consideração importante, para que não aconteça empate nas votações
em um cluster replica set, é sempre montar o replica set com número ímpar de
servidores votantes, ou então usar um servidor árbitro para dar o voto de
desempate, e que não fará parte do conjunto de réplicas (o árbitro não armazena os
dados que são replicados).

Figura 24 – Replica Set com árbitro.

Fonte: MongoDB (2018).

Bootcamp Analista de Banco de Dados – Página 55 de 147


Com todos esses recursos apresentados de forma macro, fica fácil vislumbrar
que o conceito de replica set também pode ser usado em cenários que requeiram a
implementação de ambientes de disaster recovey (DR), uma vez que não há
restrições quanto à localização dos servidores que compõem o cluster, como
mostrado no esboço a seguir.

Figura 25 – DR com Replica Set.

Fonte: MongoDB (2018).

Além de todos esses benefícios, ambientes com replica set também permitem
que haja escalabilidade vertical com o mínimo de impacto possível. Usando-se a
técnica de escalar um servidor por vez, e começando de um servidor secundário, é
possível adicionar memória RAM, disco, expandir CPU e rede retirando esse servidor
do cluster e depois inserindo-o novamente. Dessa forma, a indisponibilidade gerada
será apenas no momento de chavear a réplica primária para um servidor que já tenha
sido escalado.

Figura 26 – Escalabilidade Vertical com Replica Set.

Fonte: Gustavo Aguilar (2018).

Bootcamp Analista de Banco de Dados – Página 56 de 147


Em uma implementação mais refinada, usando-se o recurso de sharding do
MongoDB, os dados são particionados de forma horizontal e armazenados, de forma
distribuída, nos servidores do cluster. Usada em conjunto com o replica set, é
possível, além dos benefícios de um replica set, beneficiar-se de uma topologia multi-
master, que permite leituras e escritas em todos os servidores, bem como
escalabilidade horizontal.

Figura 27 – Sharding e Replica Set.

Fonte: MongoDB (2018).

No sharding, as collections selecionadas e configuradas para serem


particionadas (sharded collections), são divididas em fragmentos (shards) com base
em um campo, denominado shard key (chave de particionamento).

Bootcamp Analista de Banco de Dados – Página 57 de 147


Figura 28 – Sharded Collection x Non-Sharded Collection.

Fonte: MongoDB (2018).

A shard key, que nada mais é que um campo de uma collection, pode ser do
tipo hash (valores gerados e gerenciados pela própria engine do MongoDB) ou do
tipo range, onde é permitido definir os limites de valores (faixas) para cada shard. A
escolha do tipo de shard key a ser utilizado, deve ser muito pensada, pois escolhas
não apropriadas podem causar um desbalanceamento do cluster. Em linhas gerais,
quando se conhece muito bem a cardinalidade dos dados e/ou sabe-se que ela é
baixa (poucos valores diferentes), pode-se adotar uma shard key do tipo range. Por
outro lado, quando não se conhece a cardinalidade dos dados, é melhor usar o tipo
hash, pois terá menos probabilidade de um desbalanceamento constante.

Bootcamp Analista de Banco de Dados – Página 58 de 147


Figura 29 – Ranged Sharding x Hashed Sarding.

Fonte: MongoDB (2018).

Um cluster MongoDB implementado somente com Sharding, ou seja, sem


replica set, consegue continuar executando operações de leitura / gravação parciais,
mesmo que um ou mais shards não estejam disponíveis. Embora o subconjunto de
documentos nos shards não disponíveis não possa ser acessado durante essa
indisponibilidade, as leituras ou gravações direcionadas aos shards disponíveis são
efetivadas. A partir do MongoDB 3.2, pode-se implantar um cluster sharded junto com
replica set, de forma que, em caso de falhas em um ou mais shards, sempre é
possível continuar a processar leituras e gravações, desde que existam réplicas
disponíveis.

Outro recurso muito útil relacionado ao particionamento de dados e, presente


nativamente no MongoDB, são as zonas (zones). Uma zona é um subconjunto de
dados (faixas) que podem ser especificadas com base na shard key. Cada zona pode
ser associada à um ou mais shards do cluster, e um shard pode se associar a
qualquer número de zonas.

Bootcamp Analista de Banco de Dados – Página 59 de 147


Figura 30 – Shard Zones.

Fonte: MongoDB (2018).

Com esse recurso, são possíveis várias topologias interessantes, como por
exemplo:

▪ Disaster recovery para continuidade do negócio:

Figura 31 – DR com Replica Set + Sharding + Zonas.

Fonte: MongoDB (2018).

▪ Dados mais relevantes em shards que estão mais próximos geograficamente


ou que são mais estratégicos, e distribuição de carga entre data centers:

Bootcamp Analista de Banco de Dados – Página 60 de 147


Figura 32 – Replica Set + Sharding + Zonas.

Fonte: Gustavo Aguilar (2018).

▪ Otimização / Segmentação do Uso de Hardware: shards menos


importantes ou de histórico, em zonas cujo hardware não precisa ser tão
performático.

Figura 33 – Otimização / Segmentação de hardware.

Fonte: MongoDB (2018).

▪ Archive automático: isolar automaticamente dados pouco acessados ou que


não possuem requisitos de tempo de resposta baixo.

Bootcamp Analista de Banco de Dados – Página 61 de 147


Figura 34 – Archive Automático.

Fonte: MongoDB (2018).

5.4. Instalação e configuração do MongoDB

Atualmente, na versão 4.4, o MongoDB é disponibilizado nas edições


Community (gratuita) e na Enterprise (paga e com mais recursos), além da edição
nas nuvens, o MongoDB Atlas.

O MongoDB tem suporte para as plataformas x86_64, ARM64, PPC64LE


(somente a edição Enterprise) e s390x, sendo que desde a versão 3.2 não suporta
mais a plataforma 32-bits x86.

Em termos de sistema operacional, pode ser instalado no Linux, em


praticamente quase todas as distribuições (Amazon Linux, Debian, Red Hat, CentOS,
Suse, Solaris e Ubuntu), bem como no macOS e Windows. Para a edição Enterprise,
é possível também a instalação em Docker. Maiores detalhes acerca das plataformas
suportadas, sistemas operacionais e versões, podem ser encontrados no site do
fabricante, em https://docs.mongodb.com/manual/installation.

Independentemente da topologia definida (Stand Alone, Replica Set ou


Sharding), inicialmente a instalação do MongoDB é feita stand alone, para depois
realizar a configuração em replica set ou sharding, caso necessário. Para efeitos de
aprendizado desse curso, será dado foco na instalação do MongoDB 4.0 em um
servidor Linux x86_64, com sistema operacional Red Hat 7. Entretanto, instruções

Bootcamp Analista de Banco de Dados – Página 62 de 147


detalhas para instalação do MongoDB nos sistemas operacionais macOS e Windows,
podem ser encontradas no site do fabricante em, respectivamente,
https://docs.mongodb.com/manual/tutorial/install-mongodb-on-os-x e
https://docs.mongodb.com/manual/tutorial/install-mongodb-on-windows.

Com o sistema operacional instalado, antes de iniciar a instalação do


MongoDB, devem ser providenciados alguns pré-requisitos e configurações de boas
práticas, como os listados a seguir:

▪ Desabilitar o SELinux.

vi /etc/sysconfig/selinux

Alterar o valor SELINUXTYPE para disabled.

▪ Desativar o parâmetro de transparent hugepages e persistir para o próximo


restart. Para isso, os comandos abaixo precisam ser configurados para
executar no /etc/rc.local:

if test -f /sys/kernel/mm/transparent_hugepage/enabled; then


echo never > /sys/kernel/mm/transparent_hugepage/enabled
fi
if test -f /sys/kernel/mm/transparent_hugepage/defrag; then
echo never > /sys/kernel/mm/transparent_hugepage/defrag
fi

Após reiniciar o servidor, as configurações podem ser verificadas com os


comandos abaixo:

cat /sys/kernel/mm/transparent_hugepage/enabled
➔ always madvise [never]
cat /sys/kernel/mm/transparent_hugepage/defrag
➔ always madvise [never]

Bootcamp Analista de Banco de Dados – Página 63 de 147


▪ Por default, o serviço do MongoDB roda com o usuário mongod. Se esse
usuário já existir e não estiver no grupo mongod, o usuário deve ser removido
antes de instalar o MongoDB, ou incluído no grupo em questão, pois a
instalação faz a criação do usuário e do grupo, automaticamente.

Verificar se o usuário mongod existe ➔ id mongod

Verificar se o usuário mongod está no grupo mongo ➔ cat /etc/group |


grep mongo

▪ Criação dos diretórios para separar os arquivos de sistema, dos arquivos dos
bancos de dados, índices, log e jornal (usado como um log write ahead para
garantir a durabilidade das operações de escrita), como no exemplo mostrado
abaixo.

mkdir /mongodb
mkdir /mongodb/data/
mkdir//mongodb/log/
mkdir /mongodb/data/journal

O tipo de file system recomendado para o MongoDB é o XFS, e a opção


noatime deve ser setada.

Obs.: Pode-se também criar os pontos de montagens nesses diretórios, de


forma a separar esses arquivos em discos diferentes.

▪ Permissão de root para o usuário que realizará a instalação do MongoDB.

cat /etc/sudoers | grep su –

Obs.: a permissão de root não é necessária para administrar o MongoDB,


bastando permissão de sudo para o usuário mongod, com as configurações abaixo:

/bin/su - mongod -s /bin/bash


/bin/vi /etc/yum.repos.d/mongodb-org-*.*.repo
/bin/rm /etc/yum.repos.d/mongodb-org-*.*.repo

Bootcamp Analista de Banco de Dados – Página 64 de 147


/bin/vi /etc/yum.conf
/bin/yum * mongodb-org*
/bin/vi /etc/mongo*.conf
/bin/journalctl -xe
/sbin/service mongo* *
/bin/systemctl * mongo*

Com as configurações e pré-requisitos concluídos, pode-se iniciar a


instalação, que em sistemas operacionais Linux, pode ser feita através de packages
.rpm ou usando Tarballs. Para o nosso exemplo em questão, será feita a instalação
usando packages RPM, sendo necessária comunicação do servidor onde o MongoDB
será instalado, com o repositório de packages do MongoDB.

O processo de instalação em si é muito simples, bastando seguir os passos


mostrados a seguir:

▪ Logar no servidor via Putty ou qualquer outro terminal shell.

▪ Fazer sudo para root ➔ sudo su.

▪ Como root, criar o arquivo /etc/yum.repos.d/mongodb-org-4.0.repo e


adicionar as linhas abaixo no mesmo:

[mongodb-org-4.0]
name=MongoDB Repository
baseurl= https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.0/x86_64/
gpgcheck=1
enabled=1
gpgkey= https://www.mongodb.org/static/pgp/server-4.0.asc

Com isso, foi configurado o repositório de packages RPM de forma a instalar


a versão 4.0. Esse repositório é composto pelas packages abaixo, que podem ser
instaladas separadamente.

Bootcamp Analista de Banco de Dados – Página 65 de 147


▪ mongodb-org-server: contém o serviço da engine de banco de dados, scripts
de inicialização e o arquivo de configuração do MongoDB (configuration file),
que por padrão é criado em /etc/mongod.conf.

▪ mongodb-org-mongos: contém o serviço mongos, um serviço de roteamento


para cenários com sharding, incumbido de processar consultas, determinando
o local desses dados no cluster.

▪ mongodb-org-shell: contém o mongo shell.

▪ mongodb-org-tools: contém ferramentas úteis para se trabalhar com o


MongoDB, como mongoimport, bsondump, mongodump, mongoexport,
mongofiles, mongorestore, mongostat, and mongotop.

▪ mongodb-org: package que instalará automaticamente, todos os components


dos pacotes acima.

a) Como root, instalar o MongoDB com o comando yum install mongodb-org.

Com esse comando, será instalada a versão contida na URL inserida no


arquivo de configuração do repositório (/etc/yum.repos.d/mongodb-org-4.0.repo).

Caso deseje instalar a última versão, use o comando yum install -y mongodb-
org.

Para instalar uma versão específica, sem usar o arquivo de configuração do


repositório, deve-se especificar a versão desejada para cada package de cada
componente, como mostrado no exemplo abaixo:

yum install -y mongodb-org-4.0.6 mongodb-org-server-4.0.6 mongodb-org-


shell-4

b) Ao final, verificar se a versão instalada está coerente com o desejado,


usando o comando mongod –version.

Bootcamp Analista de Banco de Dados – Página 66 de 147


c) Ajustar o owner dos file systems do MongoDB para o usuário mongod:

chown -R mongod:mongod /mongodb

d) Conferir se o ajuste do owner foi feito com sucesso com o comando ll


/mongo*:

e) Subir o serviço do MongoDB com o comando sudo service mongod start.

f) Verificar se o serviço subiu com o comando systemctl status mongod.

Bootcamp Analista de Banco de Dados – Página 67 de 147


Figura 121 – Serviço do MongoDB em Execução.

Fonte: Gustavo Aguilar (2019).

g) Opcionalmente, configurar para que o serviço do MongoDB inicie


automaticamente após um restart do servidor, com o comando sudo
chkconfig mongod on.

h) Por default, o serviço do MongoDB é configurado para rodar na porta


27017 e com o controle de acesso desabilitado, permitindo a qualquer
usuário, localmente, logar na instância. Para isso, basta executar o
comando mongo para iniciar o mongo shell e logar na instância;

Figura 35 – Shell do MongoDB.

Fonte: Gustavo Aguilar (2019).

Bootcamp Analista de Banco de Dados – Página 68 de 147


i) Para sair do shell, basta digitar exit na linha de comando.

j) O próximo passo é configurar os parâmetros de inicialização do MongoDB


de forma apropriada. Esses parâmetros ficam no arquivo mongod.conf,
localizado no diretório /etc.

Figura 36 – Arquivo mongod.conf default.

Fonte: Gustavo Aguilar (2019).

k) Para editá-lo, executar o comando vi /etc/mongod.conf, configurá-lo como


mostrado abaixo.

# where to write logging data.

#Configuração do destino e local do log do MongoDB


systemLog:
destination: file

Bootcamp Analista de Banco de Dados – Página 69 de 147


logAppend: true
path: /mongodb/log/mongod.log

# Where and how to store data.

#Configuração do local dos dados armazenados


storage:
dbPath: /mongodb/data

#Configuração do journal
journal:
enabled: true

#Configuração para separar os bancos em diretórios


directoryPerDB: true

#Configuração para armazenar os índices em diretório separado dos


#dados
wiredTiger.engineConfig.directoryForIndexes: true

#Configuração da engine a ser utilizada (wiredTiger é a default)


#engine:
#mmapv1:
#wiredTiger:

# how the process runs

#Configurações do processo do MongoDB


processManagement:
fork: true # fork and run in background
pidFilePath: /var/run/mongodb/mongod.pid # location of pidfile
timeZoneInfo: /usr/share/zoneinfo

Bootcamp Analista de Banco de Dados – Página 70 de 147


# network interfaces

net:

#Configurações da porta de execução da instância


port: 27017

#Configuração das interfaces aceitas (localmente apenas ou não)


bindIp: 127.0.0.1 # Listen to local interface only, comment to listen on
all interfaces.

#security:

#Configuração do controle de acesso à instância (deve ficar


#desabilitado até se criar o usuário administrador)
# authorization: enabled

l) Salvar o arquivo e reiniciar o serviço do MongoDB com o comando


systemctl restart mongod (alternativamente, pode-se fazer em duas etapas,
parando o serviço do MongoDB com o comando systemctl stop mongod e
iniciando-o na sequência com o comando systemctl start mongod.

m) Após o restart, o path de dados estará com os bancos separados em


diretórios, e em cada diretório, as coleções (dados) também separadas dos
índices em diretórios.

Bootcamp Analista de Banco de Dados – Página 71 de 147


Figura 37 – Diretórios com dados e índices separados.

Fonte: Gustavo (2019).

n) Logar no MongoDB com o comando mongo.

o) No mongo shell, criar um usuário administrador (DBA), com o script abaixo,


colocando o nome (user) e a senha (pwd) desejada.

use admin

db.createUser(
{
user: "mongoadmin",
pwd: "s3nha",
roles:["root"]
})

p) Conferir se o usuário foi criado com o comando show users.

Bootcamp Analista de Banco de Dados – Página 72 de 147


Figura 38 – Evidência da criação de usuário.

Fonte: Gustavo Aguilar (2019).

q) Editar o arquivo /etc/mongod.conf para habilitar o controle de segurança do


MongoDB, incluindo as linhas abaixo. Após isso, será necessário usuário e
senha para logar no MongoDB.

security:
authorization: enabled

r) Alterar no arquivo /etc/mongod.conf o parâmetro bindip de 127.0.0.1 para


0.0.0.0, de forma a permitir conexões client-server.

s) Reiniciar o serviço do MongoDB com o comando systemctl restart mongod.

t) Feito isso, é possível acessar o MongoDB de forma remota usando o


comando abaixo, desde que se tenha um usuário, senha e o shell.

mongo -host NOME_SERVIDOR: PORTA -u USUARIO -p SENHA

Figura 39 – Logando no MongoDB.

Fonte: Gustavo Aguilar (2019).

Bootcamp Analista de Banco de Dados – Página 73 de 147


Nesse ponto, a instalação stand alone do MongoDB já está pronta para ser
utilizada (assunto do próximo tópico). Instruções detalhadas da instalação do
MongoDB em outros sistemas operacionais Linux ou em cluster replica set / sharded
cluster, podem ser encontradas no site do fabricante, em
https://docs.mongodb.com/manual.

5.5. Definindo e criando um banco de dados MongoDB

Como visto anteriormente em sua arquitetura de armazenamento, o


MongoDB armazena os dados (registros) em documentos JSON, no formato BSON.
Esses documentos, por sua vez, são armazenados em collections (coleções), que
residem dentro de um banco de dados.

Primeiramente, antes de criar essas estruturas de armazenamento, é preciso


garantir que as permissões estejam adequadas. O MongoDB, nesse ponto, é 100%
Role-Based Access Control (RBAC), somente permitindo conceder permissões
(actions) para os usuários, através de roles, sendo que um usuário pode ter uma ou
mais roles em quantos bancos for necessário.

Como boa prática, recomenda-se o gerenciamento centralizado dos usuários,


realizando a criação dos mesmos somente no banco admin e concedendo as roles
adequadas para esses usuários nos bancos necessários. Para listar os usuários, usa-
se o comando show users. Para listar as roles (predefinidas ou personalizadas), usa-
se o comando show roles.

As principais roles predefinidas são as listadas abaixo, mas pode-se criar


novas roles e personalizá-las da forma como o usuário achar melhor.

▪ root: privilégios para administração da instância (todos os bancos).

▪ readAnyDatabase: leitura em todos os bancos da instância.

▪ readWriteAnyDatabase: leitura e escrita em todos os bancos.

▪ read: privilégio de leitura no banco.

Bootcamp Analista de Banco de Dados – Página 74 de 147


▪ readWrite: privilégio de leitura e escrita no banco.

▪ dbAdmin: privilégios para tarefas administrativas no banco.

▪ userAdmin: para gerenciar usuários e permissões no banco.

▪ dbOwner: readWrite + dbAdmin + userAdmin.

▪ backup.

▪ restore.

Estando com as permissões necessárias, para listar os bancos de dados


existentes deve-se utilizar o comando show dbs, quando conectado em uma
instância MongoDB. Para utilizar um banco de dados, basta executar o comando use
NOME_BANCO. Para exibir qual banco a sessão está utilizando, executa-se o
comando db.

Figura 40 – Comandos úteis em bancos mongoDB.

Fonte: Gustavo Aguilar (2019).

Bootcamp Analista de Banco de Dados – Página 75 de 147


Se um banco de dados não existir, o MongoDB
criará o banco de dados quando se armazenar dados
nesse banco pela primeira vez. Devido a isso, pode-se
alternar para um banco de dados inexistente, como
mostrado no exemplo ao lado, mesmo antes de tê-lo
criado.

Já para as collections, o
MongoDB disponibiliza um comando
explícito para a criação
(db.createCollection()), mas se a
collection não existir, ele também a
criará quando se armazenar dados
na mesma pela primeira vez, ou
quando criar um índice nela.

Para listar as collections existentes, usa-se o comando show collections.

Figura 41 – Comandos úteis para collections.

Fonte: Gustavo Aguilar (2019).

Bootcamp Analista de Banco de Dados – Página 76 de 147


Um tipo interessante de collection que o MongoDB disponibiliza, é a Capped
Collection, que nada mais é que uma coleção com tamanho fixo, que garante e
preserva a ordem de inserção dos documentos. Dessa forma, as queries que inserem
e recuperam documentos com base na ordem de inserção, não precisam de um índice
para essas operações ordenadas, o que resulta em operações de alto throughput.
Essas colletions funcionam de maneira semelhante a um buffer circular, com o
conceito FIFO (First In First Out): quando uma coleção chega no seu tamanho
máximo, ela disponibiliza espaço para novos documentos, sobrescrevendo os
documentos mais antigos da coleção.

São criadas com o comando db.createCollection, como por exemplo:

db.createCollection( "Exemplo_Col_Capped", { capped: true, size: 100000 } )

Adicionalmente, você pode especificar também um número máximo de


documentos para a coleção, usando a opção max. Independentemente disso, o
parâmetro de tamanho máximo é sempre necessário, mesmo quando você especifica
o número máximo de documentos. Na prática, com os dois parâmetros setados, o
MongoDB removerá documentos antigos se uma coleção atingir o limite máximo de
tamanho, antes de atingir a quantidade máxima de documentos.

db.createCollection("Exemplo_Col_Capped", {capped:true, size:10000, max:50000})

No tocante à definição das estruturas dos documentos, que serão


armazenados nas collections, vimos que eles possuem o formato JSON e são
compostos por pares de campos e valores:

{
Campo1: valor1,
Campo2: valor2,
...
CampoN: valorN
}

Bootcamp Analista de Banco de Dados – Página 77 de 147


No MongoDB, é possível criar documentos embutidos em outros documentos
(embedded documents), como mostrado no exemplo ao lado.

Figura 42 – Embedded Documents.

Fonte: MongoDB (2019).

Como os documentos JSON no MongoDB são armazenados no formato


binário BSON, há uma disponibilidade de mais tipos de dados para especificação da
natureza dos dados armazenados por cada campo, como mostrado a seguir.

Bootcamp Analista de Banco de Dados – Página 78 de 147


Figura 43 – Tipos de dados.

Fonte: MongoDB (2019).

Bootcamp Analista de Banco de Dados – Página 79 de 147


No exemplo abaixo, temos a seguinte leitura da estrutura do documento em
questão:

▪ Campo _id armazena o ObjectID, que é um valor único identificador de cada


documento, gerado automaticamente pelo MongoDB.

▪ Campo nome armazena um documento embutido, que contém dois campos


(primeiro_nome e sobrenome).

▪ Campo nascimento armazena valores do tipo data.

▪ Campo hobby armazena um array de strings.

▪ Campo conexoes armazena um valor do tipo numérico longo.

_id: ObjectId("3100805ae3c4948bd2f768254"),

nome: { primeiro_nome: "Gustavo", sobrenome: "Aguilar" },

nascimento: new Date('Jul 05, 1978'),

hobby: [ "Futebol", "Filmes", "Viagem" ],

conexoes : NumberLong(1250000)

Adicionalmente à estrutura do documento, da mesma forma que nos bancos


relacionais, pode-se definir índices em qualquer campo existente, para otimizar as
consultas. A exceção fica para o campo _id, no qual o MongoDB já cria um índice
único automaticamente.

Para criar um índice, que pode ser de apenas um campo ou de vários, usa-
se o comando db.NOME_COLLECTION.createIndex, como mostrado nos exemplos
abaixo, onde 1 significa ordenação crescente e -1 ordenação decrescente:

db.Pessoa.createIndex( { nome: 1 } )

db.Pessoa.createIndex( { conexoes: -1 } )

Bootcamp Analista de Banco de Dados – Página 80 de 147


Um tipo de índice interessante e muito útil no MongoDB é o TTL Indexes, que
são índices especiais usados para remover automaticamente documentos de uma
coleção, após um determinado período. Como essa remoção é feita em segundo
plano, sem overhead para a instância, é muito mais performática do que a execução
de um comando explícito para deletar documentos de uma coleção. Esses índices
são ideais para certos tipos de informações, como dados de eventos gerados por
máquinas, logs e informações de sessão que precisam persistir em um banco de
dados apenas por um período de tempo finito.

5.6. Trabalhando com bancos de dados MongoDB

Assim como nos bancos relacionais, o MongoDB como um banco NoSQL,


oferece várias opções para operações CRUD (Create, Read, Update e Delete) de
manipulação de dados.

Para criação de documentos (inserção de dados) em collections, o MongoDB


disponibiliza dois métodos:

▪ db.nome_da_colecao.insertOne() ➔ insere apenas um documento, como


no exemplo mostrado abaixo.

Figura 44 – Exemplo Método insertOne.

Fonte: MongoDB (2019).

Bootcamp Analista de Banco de Dados – Página 81 de 147


▪ db.nome_da_colecao.insertMany() ➔ insere vários documentos de uma
vez, como mostrado no exemplo abaixo.

Figura 45 – Exemplo Método insertMany.

Fonte: MongoDB (2019).

Já para as operações de leitura, o método a ser utilizado é o find(), que pode


ser usado com outras opções, como por exemplo um critério de busca (filtro) e um
limite da quantidade de linhas retornadas (limit), como mostrado no exemplo abaixo.

db.usuario.find ( { idade: { $gt 18 } } ).limit(5)

Além disso, pode-se usar a opção pretty(), que formata a saída de forma mais
amigável, como mostrado na comparação abaixo.

Figura 46 – Exemplo de find() com opção pretty().

Fonte: Gustavo (2019).

Bootcamp Analista de Banco de Dados – Página 82 de 147


Para as operações de atualização (update), são disponibilizados três
métodos:

▪ db.collection.updateOne() ➔ atualiza os campos do primeiro documento


que satisfaça ao critério.

▪ db.collection.updateMany() ➔ atualiza vários documentos que atendam


aos critérios, de uma só vez.

▪ db.collection.replaceOne() ➔ substitui um documento por outro.

Essas operações só podem ser feitas em uma coleção, sendo que elas são
atômicas no nível de documento. Podem ser especificados critérios (update action)
ou filtros (update filter), que identificam os documentos a serem atualizados. Esses
filtros possuem a mesma sintaxe das operações de leitura e podem usar os mesmos
operadores.

Exemplo:

Figura 47 – Exemplo de updateMany().

Fonte: MongoDB (2019).

No tocante às operações de deleção de documentos, são disponibilizados


dois métodos, para fazer deleção de apenas um documento ou de vários:

▪ db.collection.deleteOne() ➔ apaga o primeiro documento da coleção que


satisfaça aos critérios.

▪ db.collection.deleteMany() ➔ apaga todos os documentos da coleção que


satisfaçam aos critérios.

Exemplo: db.movies.deleteMany ( { ano : “2000” } )

Bootcamp Analista de Banco de Dados – Página 83 de 147


Capítulo 6. Banco de Dados em Tempo Real (Real-Time Database)

6.1. Introdução à Banco de Dados em Tempo Real

Para atender à necessidade crescente do novo paradigma de programação,


as chamadas aplicações reativas, com suas peculiaridades, como elasticidade,
resiliência e responsividade, surgiu uma nova classe de sistemas de banco de dados.
Esses bancos de dados, que são nativamente orientados à push e, portanto, com
uma promessa muito forte para facilitar o desenvolvimento de aplicativos reativos
(apps e web), são geralmente chamados de bancos de dados em tempo real. O
nome se dá ao fato dos mesmos manterem os dados, no lado do cliente, em sincronia
com o estado atual do banco de dados “em tempo real”, ou seja, imediatamente após
a alteração.

Na prática, um banco de dados em tempo real está sempre “monitorando” as


alterações no banco de dados e sempre que há um dado novo, atualizado ou
removido, o envia imediatamente para a camada cliente.

Atualmente não há uma grande quantidade de players de mercado investindo


no desenvolvimento de bancos de dados em tempo real, mas existem quatro grandes
nomes de peso: Google Firebase, Meteor, RethinkDB e Parse.

O Meteor é um framework de desenvolvimento JavaScript, voltado para


aplicativos e sites reativos. Ele usa o MongoDB como meio de armazenamento,
oferecendo duas implementações diferentes para detectar mudanças relevantes no
banco de dados: change monitoring + poll-e-diff, que combina o monitoramento das
operações de escrita e reavaliação periódica de consultas e a implementação mais
atual, que consiste em monitorar o log de transações (oplog) do MongoDB. Devido à
essa grande dependência do MongoDB, é considerado mais uma solução de banco
de dados em tempo real, do que um sistema de banco de dados real-time
propriamente dito.

Bootcamp Analista de Banco de Dados – Página 84 de 147


Figura 48 – Meteor Monitorando o Oplog.

Fonte: Wolfram Wingerath (2017).

Já o RethinkDB, é um repositório de documentos JSON com expressividade


em consultas comparável ao MongoDB, que trabalha com o conceito similar ao
Meteor, de monitoração do log de operações, para prover um banco de dados em
tempo real. Basicamente, seu componente principal, o Proxy recebe todas as
alterações feitas nos dados, e a orquestra em tempo real para a camada cliente.

Figura 49 – RethinkDB.

Fonte: Wolfram Wingerath (2017).

Bootcamp Analista de Banco de Dados – Página 85 de 147


Outro nome que se propõe a ser um framework, assim como o Meteor, é o
Parse, que também utiliza o MongoDB para armazenamento dos dados.

Da lista de players citada inicialmente, o Google Firebase é, sem dúvidas, o


mais famoso e um dos poucos que se apresenta, na íntegra, como um banco de
dados em tempo real. Para aprofundamento do conhecimento em banco de dados
real-time, ele será apresentado em maiores detalhes nos próximos itens.

6.2. Introdução ao Firebase Realtime Database

O Firebase Realtime Database é um componente da plataforma Firebase


de desenvolvimento de aplicativos para dispositivos móveis e Web, lançada
inicialmente pela Firebase Inc. em 2011 e adquirida pelo Google em 2014.

Trata-se de um serviço de banco de dados NOSQL hospedado na nuvem,


onde os dados são armazenados como uma grande árvore JSON e sincronizados em
tempo real com todos os clientes conectados à solução.

Figura 50 – Firebase Realtime Database.

Fonte: Md Munir Hossain (2017).

Esse processo de sincronização dos dados é viabilizado pelos SDKs,


disponibilizados pela plataforma para o desenvolvimento de aplicativos, garantindo

Bootcamp Analista de Banco de Dados – Página 86 de 147


que todos os clientes, ao compartilharem uma mesma instância do Firebase Realtime
Database, receberão automaticamente as atualizações com os dados mais recentes.
Mesmo off-line, os aplicativos que usam o Firebase permanecem responsivos, pois o
SDK do Firebase Realtime Database, mantém os dados em disco. Dessa forma,
quando a conectividade é restabelecida, o dispositivo cliente recebe as alterações
não recebidas e faz a sincronização com o servidor.

Figura 51 – Modo off-line do Firebase Realtime Database.

Fonte: Gustavo (2019).

Há pouco tempo, o Google lançou uma outra opção para armazenamento de


dados para projetos no Firebase, também como um serviço de banco de dados
hospedado nas nuvens, chamado Firebase Cloud Firestore. Em linhas gerais, o
Google coloca o Firebase Realtime Database como o banco de dados original do
Firebase e o Firebase Cloud Store como o novo banco de dados principal do Firebase,
oferecendo melhor performance e escalabilidade, com um modelo de dados mais
intuitivo. Algumas outras diferenças entre eles são consideráveis, como por exemplo
o armazenamento dos documentos JSON organizados em coleções e o suporte off-
line para clientes Web também (no Realtime o suporte é apenas no iOS e no Android).
Todas as diferenças entre eles podem ser encontradas no link
https://firebase.google.com/docs/database/rtdb-vs-firestore?hl=pt-br, como parte da
própria documentação do produto.

Em termos de SDK, o Firebase Realtime Database disponibiliza as seguintes


opções para integração e construção dos aplicativos:

Bootcamp Analista de Banco de Dados – Página 87 de 147


▪ API Admin (Admin SDK): linguagens Java, Node.js, Python e Go.

▪ iOS: linguagens Swift e Objective-C.

▪ Android: linguagens Java Android e Kotlin Android.

▪ Web: linguagem JavaScript.

▪ REST API: linguagens Clojure, Dart, Go, Java, Perl, PHP, Python e Ruby.

Para efeitos de aprendizado nessa disciplina, focaremos no SDK Web, para


o qual veremos mais detalhes de configuração e utilização nos próximos itens.

6.3. Instalação e configuração do Firebase no JavaScript

O pré-requisito para configurar o Firebase Realtime Database no SDK Web


JavaScript, é já ter um app JavaScript ao qual o Firebase será adicionado. No link
https://firebase.google.com/docs/samples/?hl=pt-br#web, existem vários exemplos
de início rápido, dentre eles um app para Realtime Database
(https://github.com/firebase/quickstart-js?hl=pt-br).

Para adicionar o Firebase ao app, é necessário, antes, criar um projeto do


Firebase. O projeto do Firebase deve ser criado na Console do Firebase, disponível
em https://console.firebase.google.com/?hl=pt-br, clicando na opção Adicionar
projeto. Será solicitado o nome do projeto e algumas confirmações de localização e
aceite dos termos de utilização.

Bootcamp Analista de Banco de Dados – Página 88 de 147


Figura 52 – Console do Firebase.

Fonte: Gustavo Aguilar (2019).

Com o projeto criado, a console de trabalho do Firebase fica similar à


mostrada na figura abaixo, onde é possível fazer as configurações necessárias.

Figura 53 – Console do projeto.

Fonte: Gustavo Aguilar (2019).

Nessa console, a próxima etapa é adicionar o Firebase do projeto recém-


criado ao aplicativo que está sendo desenvolvido. Clicando no ícone do tipo de app
desejado, é mostrado o código do respectivo objeto de configuração do Firebase a
ser adicionado no código do aplicativo em desenvolvimento. No exemplo em questão,

Bootcamp Analista de Banco de Dados – Página 89 de 147


usaremos um app Web (ícone ). Ao clicar nesse ícone, será exibido o código do
respectivo objeto de configuração do Firebase para aplicativo Web, com todo o código
de inicialização necessário para começar a utilizar o projeto criado.

Figura 54 – Exemplo de código de inicialização Firebase.

Fonte: Gustavo (2019).

Esse código personalizado do projeto de Firebase de exemplo, deve ser


inserido na sua página HTML antes de outras tags de script, como mostrado na figura
abaixo, de forma a inicializar o SDK Web do Firebase e poder utilizá-lo.

Figura 55 – Página HTML com inicialização do Firebase.

Fonte: Gustavo (2019).

Bootcamp Analista de Banco de Dados – Página 90 de 147


O próximo passo é configurar as regras de segurança para acesso ao
Firebase Realtime Database. Para isso, no console do projeto, deve-se clicar na
opção Database e na tela a seguir, na opção Ou escolha Realtime Database, em
Criar Banco de Dados. Feito isso, será aberta uma janela para configurar as regras
de segurança. Configure como desejado, ou com a opção abaixo, que para efeitos de
testes, permitirá a qualquer usuário utilizar o banco de dados.

Figura 56 – Criação e configuração do Realtime Database.

Fonte: Gustavo (2019).

Nesse ponto, o banco de dados já está pronto para ser utilizado e para testar
a conexão e demonstrar um exemplo simples, usaremos o código a seguir, que em
linhas gerais realiza as seguintes operações:

▪ Cria um cabeçalho nível 1 (H1) no HTML em questão e atribui um ID. Esse


cabeçalho será sincronizado toda vez que um valor for alterado no Firebase
Realtime Database;

<h1 id="CabTeste"></h1>

Bootcamp Analista de Banco de Dados – Página 91 de 147


▪ Instancia o cabeçalho pelo ID;

var CabTeste = document.getElementById('CabTeste');

▪ Cria uma referência do banco de dados inicializado previamente (no nosso


exemplo, https://demoppd-50a47.firebaseio.com/) e cria uma localização filha
à entrada ‘textoteste’;

var dbRef = firebase.database().ref().child('textoteste');

▪ Sincroniza o cabeçalho com banco de dados.

dbRef.on('value', snap => CabTeste.innerText = snap.val());

<!doctype html>

<html>

<head>

<meta charset="utf-8">

<title>Firebase Realtime Database Quickstart</title>

</head>

<body>

<h1 id="CabTeste"></h1>

<script src="https://www.gstatic.com/firebasejs/5.10.1/firebase.js"></script>

<script>

// Initialize Firebase

var config = {

apiKey: "AIzaSyB-tcS-8tzQ-Vu9iby2ElSrxOVSAEHYz1A",

authDomain: "demoppd-50a47.firebaseapp.com",

databaseURL: "https://demoppd-50a47.firebaseio.com",

projectId: "demoppd-50a47",

storageBucket: "demoppd-50a47.appspot.com",

Bootcamp Analista de Banco de Dados – Página 92 de 147


messagingSenderId: "774204272250"

};

firebase.initializeApp(config);

var CabTeste = document.getElementById('CabTeste');

var dbRef = firebase.database().ref().child('textoteste');

dbRef.on('value', snap => CabTeste.innerText = snap.val());

</script>

</body>

</html>

Dessa forma, usando o própria console do Firebase, podemos criar a entrada


“textoteste” definida no código e inserir os valores desejados, como mostrado abaixo:

Figura 57 – Exemplo de entrada de dados no Firebase.

Fonte: Gustavo (2019).

Nesse momento, qualquer alteração de valor será imediatamente enviada


para o código do aplicativo (no nosso caso, a página HTML de teste), sem que a
aplicação necessite fazer uma consulta ao Firebase Realtime Database, uma vez que
o mesmo implementa o mecanismo de push de dados.

Bootcamp Analista de Banco de Dados – Página 93 de 147


Figura 58 – Sincronização em tempo real no Firebase.

Fonte: Gustavo (2019).

6.4. Trabalhando com os dados no Firebase Realtime Database

No Firebase Realtime Database, os dados são armazenados como objetos


JSON, em uma grande árvore JSON, hospedada na nuvem. Não há collections como
nos bancos NOSQL, orientados a documentos como o MongoDB e o CouchDB, e
nem tabelas como nos bancos de dados relacionais. Dessa forma, quando se
adiciona dados ao Firebase Realtime Database, eles se tornam um nó na estrutura
JSON, com uma chave associada. Essa chave pode ser fornecida de forma
customizada pelo modelo de dados, junto ao código da aplicação, ou ser gerada
automaticamente usando push().

Nesse ínterim, para definir a estrutura dos dados no Firebase Realtime


Database, basta organizá-lo como um objeto JSON, como mostrado no exemplo
abaixo de um aplicativo de rede social.

"usuarios": {

"gustavoaagl":

Bootcamp Analista de Banco de Dados – Página 94 de 147


"nome": "Gustavo Aguilar de Araújo Gonzaga Lopes",

"conexoes": [ "julianaglaa", “giovanaglaa”, “daviglaa”]

},

" julianaglaa ":

"nome": "Juliana Gonzaga Lopes Aguilar de Araújo",

"conexoes": [ " gustavoaagl ", “giovanaglaa”, “daviglaa”]

},

" giovanaglaa":

"nome": "Giovana Gonzaga Lopes Aguilar de Araújo ",

"conexoes": [ " gustavoaagl ", “julianaglaa”, “daviglaa”]

},

" daviglaa": { ... }

}}

Para ler e gravar dados no Firebase Realtime Databse, primeiramente é


necessário instanciar o banco de dados. Isso é feito através do método
firebase.database():

▪ Usando variável: var database = firebase.database();

▪ Instanciando direto: firebase.database(). ......;

Para as operações de leitura e escrita, são disponibilizados métodos de


acordo com o SDK selecionado. No SDK Web, as operações de gravação são feitas
com o método set(), como mostrado no exemplo abaixo. Esse método substitui os
dados no local especificado da árvore JSON, incluindo também qualquer node filho
necessário.

Bootcamp Analista de Banco de Dados – Página 95 de 147


function EscreveUsuario (IDUsuario, nome, email

firebase.database().ref('usarios/' + IDUsuario).set({

nomeusuario: nome,

email: email });

Para atualizar campos específicos, deve-se usar o método update(), como


mostrado no exemplo a seguir:

Figura 59 – Código com exemplo de Update.

Fonte: Google (2019).

Para as operações de leitura, pode-se usar o método on(), que consegue


detectar automaticamente as alterações em um determinado caminho da árvore
JSON de dados, ou o método once(), que permite fazer uma leitura dos dados assim
que acionado.

O exemplo a seguir mostra um app de rede social recuperando, em tempo


real com o método on(), o número de likes de uma postagem:

var ContaLikes = firebase.database().ref('posts/' + postId + '/QtdeLikes');

Bootcamp Analista de Banco de Dados – Página 96 de 147


ContaLikes.on('value', function(snapshot) {

AtualizaLikes(postElement, snapshot.val());

});

Já no exemplo de código abaixo, para o mesmo app de rede social anterior,


o método once() é usado para carregar o perfil de um usuário assim que ele começa
a fazer um novo post:

var IDUsuario = firebase.auth().currentUser.uid;

return firebase.database().ref('/usuarios/' +
IDUsuario).once('value').then(function(snapshot)

var nomeusuario = (snapshot.val() && snapshot.val().nomeusuario) ||


'Anonymous';

// ...

});

Além desses métodos básicos vistos, o Firebase fornece inúmeras outras


possibilidades, como por exemplo a utilização de lista de dados e os respectivos
métodos para leitura e gravação, que podem ser conferidos na documentação do
produto (disponível em: https://firebase.google.com/docs/database/web/lists-of-
data?hl=pt-br).

6.5. Overview das regras do Firebase Realtime Database

A primeira etapa no desenvolvimento da camada de segurança do app é a


identificação dos usuários. Esse processo é conhecido como autenticação, e no
Firebase Realtime Database pode ser feito utilizando o Firebase Authentication. Com
esse recurso, tem-se o suporte ao drop-in em métodos comuns de autenticação,

Bootcamp Analista de Banco de Dados – Página 97 de 147


como o Google, Facebook e Twitter, além do login tradicional com e-mail e senha,
login anônimo.

Uma vez identificado o usuário, é preciso controlar o acesso (autorização)


do mesmo ao banco de dados. Com as regras do Firebase Database, você controla
o acesso de cada usuário, uma vez que elas são os recursos utilizados para
especificar e controlar quem tem permissão de leitura e gravação no banco de dados,
como os dados são validados e quais os índices existentes.

Essas regras ficam armazenadas nos servidores do Firebase e são sempre


aplicadas automaticamente, depois de configuradas, de forma que as solicitações de
leitura e gravação só são efetivadas se as regras permitirem. Por padrão, as regras
não concedem acesso ao banco de dados e, como visto no tópico de instalação e
configuração do Firebase Realtime Database, elas precisam ser configuradas para
que se possa utilizar o banco de dados.

A sintaxe das regras do Firebase Database é parecida com a do Javascript e


existem quatro tipos:

▪ .read: descreve se e quando os dados podem ser lidos pelos usuários.

▪ .write: descreve se e quando os dados podem ser gravados.

▪ .validate: define a formatação correta do valor, o tipo de dados e se o valor


tem atributos filhos.

▪ .indexOn: especifica um filho como índice, para que a ordenação e consulta


sejam possíveis.

No exemplo de regras abaixo, é permitido que qualquer pessoa leia o


caminho /usuarios/, mas não faça gravações nele:

"rules": {

"usuarios": {

Bootcamp Analista de Banco de Dados – Página 98 de 147


".read": true,

".write": false

} }}

Como as regras .read e .write são aplicadas em cascata, esse conjunto de


regras concede acesso de leitura a todos os dados do caminho /usuarios/, bem como
em níveis inferiores, como por exemplo em /usuarios/admin/gustavoaagl.

O Firebase Realtime Database não usa esquemas de bancos de dados, o


que facilita fazer alterações durante o processo de utilização. No entanto, é importante
fazer uma validação de dados mínimo, no sentido de manter a consistência dos
valores dos dados. Dessa forma, a linguagem de regras do Firebase Realtime
Database disponibiliza a regra .validate, para aplicar a lógica de validação com as
mesmas expressões usadas pelas regras .read e .write. A única diferença é que,
como as regras de validação não são aplicadas em cascata, todas as regras de
validação precisam ser avaliadas como verdadeiras, para que a gravação seja
efetivada.

No exemplo de regra de validação abaixo, os dados gravados em /usuarios/


precisam ser uma string com menos de 100 caracteres:

"rules": {

"usuarios": {

".validate": "newData.isString() && newData.val().length < 100"

} }}

No Firebase Realtime Database, é possível ordenar e consultar os dados de


várias maneiras. Para pequenos volumes de dados ou ambientes de testes, é
possível fazer consultas ad hoc no banco de dados de forma relativamente rápida,
não sendo tão imprescindível a existência de índices. Entretanto, para ambientes
produtivos ou com grande volume de dados, é essencial especificar índices para as

Bootcamp Analista de Banco de Dados – Página 99 de 147


consultas existentes, garantindo que elas continuem funcionando mesmo com o
aumento do volume de dados ou concorrência de utilização no app.

Os índices são especificados com a regra .indexOn, como mostrado no


exemplo abaixo, que indexaria os campos de nome e CPF de uma lista de usuários:

{ "rules": {

"usuarios": {

".indexOn": ["nome", "cpf"]

} } }

6.6. Escalonamento no Firebase Realtime Database

O Firebase Realtime Database possui alguns limites e restrições acerca do


armazenamento de dados e das operações no banco de dados para uma instância.
Esses limites estão especificados na documentação do produto e podem ser
encontrados no link https://firebase.google.com/docs/database/usage/limits?hl=pt-br.

Dentre eles, os mais significantes são o limite de 100.000 conexões


simultâneas e o de 1.000 operações de gravação/segundo para cada instância de
banco de dados. Em aplicações de grande porte isso pode ser um limitador, e para
contornar, o Firebase permite que sejam criadas várias instâncias (mas cada uma
delas continua com os limites conhecidos).

Esse processo, chamado de escalonamento, é implementado no Firebase


Realtime Database através da técnica de fragmentação de banco de dados com o
particionamento horizontal, sendo considerada a melhor maneira de otimizar o
desempenho.

De forma macro, o escalonamento no Firebase Realtime Database é feito


com as seguintes etapas:

Bootcamp Analista de Banco de Dados – Página 100 de 147


i. Mapeamento dos dados (criação do fragmento mestre) para vários bancos
de dados de acordo com as necessidades específicas do app;

Figura 60 – Escalonamento por tipo de aplicação.

Fonte: Firebase (2019).

ii. Criação das instâncias de banco de dados necessárias.

iii. Configuração do app para que ele se conecte à instância do Realtime


Database necessária para cada conjunto de dados.

Figura 61 – Exemplo de configuração multi-instância.

Fonte: Google (2019).

Bootcamp Analista de Banco de Dados – Página 101 de 147


Capítulo 7. Pesquisa Indexada em Bases Não Estruturadas

7.1. Introdução à pesquisa indexada

Desde os primórdios da computação, o assunto pesquisa sempre esteve em


voga, dadas as necessidades intrínsecas de consultar os dados armazenados, sejam
eles arquivos no sistema operacional, dados em um banco de dados, aplicação ou
página web.

Para acelerar essas pesquisas, vários conceitos e recursos foram sendo


introduzidos nas suas devidas camadas, como por exemplo os índices no banco de
dados, o Windows Desktop Search no sistema operacional da Microsoft, o Google
Search no âmbito Web e o Lucene na camada de aplicação.

Figura 62 – Windows Desktop Search.

Fonte: Gustavo Aguilar (2019).

Desde o início, essas ferramentas de consulta possuíam uma estrutura de


indexação por trás, com o propósito de acessar e retornar as informações de forma
mais rápida. Essa estrutura, que era alimentada pela base de dados principal onde
os dados eram armazenados, precisava ser definida previamente e sempre
atualizada, de forma que as consultas fossem rápidas e assertivas.

Bootcamp Analista de Banco de Dados – Página 102 de 147


Figura 63 – Visão geral da indexação de texto.

Fonte: Erysson (2010).

Com o aumento exponencial da quantidade de informações armazenadas, o


boom de aplicativos mobile e web, e a constante necessidade de otimizar a
velocidade de execução, transmissão e exibição dos dados, de forma a propiciar cada
vez mais uma melhor experiência para o usuário, criou-se uma lacuna a ser
preenchida.

Nessa lacuna, podemos citar, por exemplo, as seguintes necessidades ou


aplicabilidades:

▪ Projetos de Big Data / de BI: manipulação de volumes gigantescos de


dados, mudança dinâmica de regras, análises em tempo real etc.

▪ E-commerce: sugestões de produtos relacionados, recursos de


autocompletar, personalização de produtos e promoções em tempo real de
acordo com o perfil do cliente etc.

▪ Buscadores de preços: informar para um usuário quando algum produto


atingir o preço configurado por ele.

Bootcamp Analista de Banco de Dados – Página 103 de 147


▪ Tendências de mercado: prever comportamentos e desejos dos usuários,
antecipar procuras ou compras.

Dessa forma, essa lacuna, que requisitava ferramentas de pesquisa indexada


mais robustas, ágeis, escaláveis e dinâmicas, começou a ser preenchida com as
ferramentas que trouxeram, além do conceito fundamental de pesquisa indexada, a
ideia de pesquisa elástica.

Dentre os players de mercado que se lançaram nessa empreitada, os mais


conhecidos e utilizados no mercado são:

▪ Apache com o Solr:

‒ Abstração construída em cima do Lucene.

‒ API HTTP trocando dados com XML/JSON.

‒ Serviços HTTP que permitem usar a busca até mesmo sem usar a API
na linguagem de programação (Java por exemplo) e consumir o
serviço pronto pela web.

‒ Filtragem e pesquisa gerenciada (auxiliadores de busca como


sugestão).

‒ Pesquisa geoespacial.

‒ Cache com atualização incremental.

‒ Distribuição e replicação de dados.

▪ .Elastic com o Elasticsearch:

‒ Concorrente direto do Sorl, com os mesmos recursos e mais além.

‒ Mais moderno, com mais facilidades e atualização dos índices próxima


do tempo real.

Bootcamp Analista de Banco de Dados – Página 104 de 147


‒ Alta disponibilidade e capacidade para tratar grandes volumes de
dados.

‒ Pesquisas full-text, geográficas e analíticas.

‒ Disponibiliza uma API REST full.

‒ Possibilidade de implementação de clusters, sendo totalmente


escalável.

▪ Microsoft com o Azure Search:

‒ Serviço oferecido na nuvem (Microsoft Azure).

‒ Funcionalidade exposta por meio de uma API REST ou um SDK do


.NET.

‒ Integração nativa com o Azure Blob Storage (armazenamento).

‒ Pesquisa cognitiva, geográfica e análise linguística.

‒ Modelagem de relevância (pontuação) dos valores.

▪ Amazon Elasticsearch Service:

‒ Serviço gerenciado que facilita a implantação, a operação e o


dimensionamento de clusters do Elasticsearch na nuvem AWS;

‒ Recursos para dimensionar, controlar segurança, estabilidade e


integração com outros serviços, como o Amazon CloudWatch (para
monitoramento), AWS CloudTrail (para auditoria), Amazon S3
(armazenamento) e DynamoDB (banco de dados).

Para efeitos de aprendizado nessa disciplina, utilizaremos o Elasticsearch


para aprofundar os conhecimentos em pesquisa indexada.

Bootcamp Analista de Banco de Dados – Página 105 de 147


7.2. Introdução ao Elastic Stack

O Elastic Stack é um grupo de produtos de código aberto da Elastic, projetado


para ajudar os usuários a coletar dados de qualquer tipo de fonte e em qualquer
formato, pesquisar, analisar e visualizar esses dados em tempo real ou não.

O grupo de produtos, 100% open source, era conhecido inicialmente como


ELK Stack, e as letras ELK representavam as iniciais do nome dos produtos do
pacote: Elasticsearch, Logstash e Kibana.

▪ Elasticsearch (E): mecanismo de pesquisas e análises distribuído;

▪ Logstash (L): ferramenta de processamento de dados que permite coletar


dados de várias fontes, transformá-los e enviá-los para o destino desejado.
Possui filtros pré-definidos e suporte para mais de 200 plugins.

▪ Kibana (K): ferramenta de visualização e exploração de dados, oferece


gráficos interativos e fáceis de usar, agregações e filtros pré-construídos, bem
como suporte geoespacial, sendo uma das melhores ferramentas para
visualizar os dados armazenados no Elasticsearch. Alguns exemplos podem
ser encontrados no site da Elastic, no endereço:
https://demo.elastic.co/app/kibana#/dashboards?_g=(refreshInterval:(display:'
30%20seconds',pause:!f,section:1,value:30000),time:(from:now-
7d,mode:quick,to:now)).

Posteriormente, um quarto produto foi adicionado ao pacote: o Beats. Essa


ferramenta trata-se de um agente instalado nos servidores, para enviar diferentes
tipos de dados operacionais para o Elasticsearch, diretamente ou através do
Logstash, onde os dados podem ser aprimorados ou arquivados. Dessa forma, para
não adicionar mais uma letra do nome do grupo de ferramentas, o mesmo passou a
ser referenciado como Elastic Stack.

Bootcamp Analista de Banco de Dados – Página 106 de 147


Figura 64 – Elastic Stack.

Fonte: Elastic (2017).

Os produtos no Elastic Stack são projetados para serem usados juntos e os


releases são sincronizados para simplificar o processo de instalação e atualização.
Dessa forma, ao instalar o Elastic Stack, é preciso usar a mesma versão em todos os
componentes do pacote. Por exemplo, se estiver usando o Elasticsearch 7.0.1, deve-
se instalar o Beats 7.0.1, o Kibana 7.0.1 e o Logstash 7.0.1. Há também a
possibilidade da instalação isolada de somente um componente do pacote.

Há também um conjunto de produtos (X-Pack), não gratuitos, desenvolvidas


pela Elastic, que prometem agregar valor ao pipeline de dados, com recursos de
segurança, monitoração, alerta e machine learning, mostrado ao lado.

Figura 65 – Produtos pagos do Elastic Stack.

Fonte: Elastic (2019).

As ferramentas do Elastic Stack podem ser utilizadas em conjunto com


produtos de outros fornecedores, como plataformas de armazenamento de dados em

Bootcamp Analista de Banco de Dados – Página 107 de 147


memória (Redis / Kafka / RabbitMQ), para serem utilizadas como buffer ou
ferramentas de segurança, como o NGINX.

Figura 66 – Elastic Stack com outras ferramentas.

Fonte: Daniel Berman (2018).

Uma das implementações mais tradicionais é enviar eventos para o


Elasticsearch e trabalhar com agregações, para, por exemplo, visualizar de forma on-
line e em tempo real, as vendas das lojas de uma multinacional, como mostrado no
exemplo abaixo.

Figura 67 – Agregação no Elasticsearch.

Fonte: Bo Andersen (2017).

Outra implementação muito comum, é usar o Elastic Stack como uma solução
de gerenciamento de performance de aplicação (Application Performance

Bootcamp Analista de Banco de Dados – Página 108 de 147


Management – APM), que analisa logs de aplicações, banco de dados, sistema
operacional ou servidor web, para fins de acompanhamento de métricas, como
mostrado na imagem abaixo.

Figura 68 – Analisando Log com o Elastic Stack.

Fonte: Semantix (2018).

7.3. Conceitos Básicos e Arquitetura do Elastic Search

O Elastic Search, como visto anteriormente, é uma ferramenta de código


aberto (opensource) para buscas, que tem capacidade para tratar grandes volumes
de dados em tempo real e por isso, tem sido utilizada por grandes empresas como
Facebook, Google, ebay, Mercado Livre, Netflix, Netshoes, GitHub, SoundCloud,
Twitter, Uber e Verizon.

Figura 69 – Busca em Tempo Real Usando Elasticsearch.

Fonte: Bo Andersen (2017).

Bootcamp Analista de Banco de Dados – Página 109 de 147


Baseado no Apache Lucene, o Elasticsearch foi desenvolvido por Shay
Bannon, em Java, e lançado em 2010. Utilizando uma interface comum (JSON sobre
HTTP), ele possui client para as principais linguagens de programação e foi
desenvolvido do zero com o objetivo de ser escalável, ou seja, podendo ser utilizado
de forma distribuído em clusters.

No Elasticsearch, os dados são armazenados como documentos, no


formato JSON. Fazendo-se um paralelo com os bancos de dados relacionais, um
documento (document) no Elasticsearch corresponde ao conceito de linha (tupla) em
um banco relacional. Um documento contém campos (fields) e valores, que são
correspondentes ao conceito de tabela em um banco de dados relacional. Pode-se
ter por exemplo, um documento para um único cliente, outro documento para um
único produto e outro para um único pedido.

Figura 70 – Exemplo de documento no Elasticsearch.

Fonte: Bo Andersen (2017).

Cada documento possui seu ID, que nada mais é que um identificador único
do documento dentro de um índice Elasticsearch, podendo ser atribuído
automaticamente ou manualmente via código. Para além disso, um documento é uma
unidade básica de informação que pode ser indexada. Para indexar os documentos,
o Elasticsearch usa o recurso de índice (index).

Bootcamp Analista de Banco de Dados – Página 110 de 147


Os índices são o cerne da engine de armazenamento e busca do
Elasticsearch, sendo definidos conceitualmente como uma coleção de documentos
que possuem características similares. Por exemplo, pode-se ter um índice para
dados do cliente, outro para um catálogo de produtos e outro para os dados do pedido.
Para além disso, dentro de um índice, pode-se armazenar quantos documentos
desejar ou couberem no espaço reservado para o armazenamento de dados do
Elasticsearch.

Figura 71 – Exemplo de Índice no Elasticsearch.

Fonte: Bo Andersen (2017).

Os índices são identificados por um nome, que deve ser todo em letras
minúsculas, sendo esse nome usado para se referir ao índice ao executar operações
de indexação, pesquisa, atualização e exclusão de documentos contidos nele.
Fazendo-se o paralelo com um banco de dados relacional, o índice seria o
correspondente ao conceito de database.

Em termos de arquitetura, a engine do Elasticsearch gira em torno dos


recursos de nós (nodes) e cluster. Um nó é um servidor (físico ou virtual) que
armazena dados, ou seja, é uma instância do Elasticsearch, fazendo parte do que é
chamado de cluster.

Bootcamp Analista de Banco de Dados – Página 111 de 147


Já um cluster, é uma coleção de nós, ou seja, de servidores, de forma que
cada nó contém uma parte dos dados (documentos) que são adicionados ao cluster.
Assim sendo, a coleção de nós armazena e contém, portanto, o conjunto de dados
inteiro para o cluster Elasticsearch. Cada nó participa das operações de indexação e
pesquisa do cluster quando uma determinada operação envolver os dados que ele
armazena ou armazenará.

Figura 72 – Cluster no Elasticsearch.

Fonte: Bo Andersen (2017).

Obs.: é possível também, mas não muito usual, existir um ambiente com
topologia stand alone, ou seja, “um cluster” com apenas um nó, contendo todos os
dados armazenados no Elasticsearch.

Além disso, vale a pena ressaltar que qualquer nó do cluster pode manipular
solicitações HTTP para clientes que desejam enviar uma solicitação ao cluster para
realizar uma determinada operação. Isso é feito usando a REST API HTTP que o
cluster expõe. Outro ponto interessante, é que cada nó dentro do cluster possui
informações dos demais nós e é capaz de encaminhar solicitações para um
determinado nó usando uma camada interna de transporte.

Todo cluster possui um nó mestre (master), sendo que qualquer nó pode ser
designado para ser o nó mestre por padrão. O nó mestre é o nó responsável por

Bootcamp Analista de Banco de Dados – Página 112 de 147


coordenar as alterações no cluster, como adicionar ou remover nós, criar ou remover
índices etc. Ele fica incumbido de atualizar o estado do cluster, sendo o único nó a
poder realizar essa operação.

Todo cluster e nó são identificados por nomes exclusivos. Para clusters, o


nome padrão é elasticsearch, com todas as letras minúsculas. Para os nós, é um
identificador universal exclusivo, também chamado de UUID. É possível alterar
esse padrão, de forma personalizar os nomes dos nós, uma vez que é imprescindível
ter a identificação correspondente de quais máquinas físicas ou virtuais
correspondem a quais nós do Elasticsearch.

Para escalar a sua topologia em cluster, o Elasticsearch utiliza da técnica de


particionamento horizontal de dados, também conhecida como sharding. O
particionamento divide os índices em partes menores chamadas shards
(fragmentos), de maneira que um shard só conterá um subconjunto de dados de um
índice. Quando um índice é dividido, um determinado documento nesse índice será
armazenado apenas em um dos shards do cluster, ou seja, não há divisões (splits)
no nível de documentos.

Figura 73 – Exemplo de Índice no Elasticsearch.

Fonte: Bo Andersen (2017).

Bootcamp Analista de Banco de Dados – Página 113 de 147


A quantidade de shards pode ser especificada no momento da criação do
índice, mas caso não seja feita, será utilizado o padrão de 5 shards. Os shards
podem ser hospedados em qualquer nó dentro do cluster, o que faz com que os
shards de um determinado índice não estarem, necessariamente, distribuídos em
várias máquinas. No exemplo da figura anterior, foram configurados 4 shards para o
índice de 1 terabyte, mas esses shards poderiam estar distribuídos entre apenas dois
nós, como mostrado na figura abaixo.

Figura 74 – Índice de 4 Shards em Cluster de 2 Nodes.

Fonte: Bo Andersen (2017).

Dada essa flexibilidade, pode-se perceber a grande facilidade em escalar


horizontalmente um cluster Elasticsearch, adicionando novos nós ao ambiente e
aumentando a quantidade de shards dos índices*, não somente por questões de
espaço de armazenamento, mas também por questões de aumento do poder de
processamento e melhoria de desempenho, distribuindo as operações em mais nós
e aumentando dessa forma, o paralelismo.

Para saber em qual shard armazenar um novo documento e como encontra-


lo, o Elasticsearch usa, por padrão, um mecanismo automático, feito sem a percepção
e intervenção do usuário, chamado de roteamento (routing), que é determinado pela
fórmula shard = hash (routing) % total_primary_shards. Por padrão, o valor de

Bootcamp Analista de Banco de Dados – Página 114 de 147


routing será igual ao ID de um determinado documento. Esse valor é então passado
por uma função de hashing, que gera um número que será usado para a divisão. O
restante da divisão do número gerado com o número de fragmentos primários no
índice fornecerá o número do fragmento do documento em questão. Pode-se
também, especificar um valor customizado para o routing, o que fará com que se
altere a forma como os documentos serão distribuídos.

Figura 75 – Localização e Distribuição de Documentos.

Fonte: Bo Andersen (2017).

Esse mecanismo também garante a distribuição uniforme dos documentos


entre os nós do cluster, de forma a não se ter fragmentos contendo mais documentos
do que outros, o que acarretaria um cluster desbalanceado, culminando em um não
aproveitamento na íntegra da máxima performance permitida pela topologia
distribuída do Elasticsearch.

Bootcamp Analista de Banco de Dados – Página 115 de 147


Para garantir a alta disponibilidade do ambiente e dos dados, o Elasticsearch
também permite implementar a técnica de replicação de dados, de forma se ter
tolerância a falhas no cluster. Na prática, a replicação no Elasticsearch é feita
copiando os shards para outros nós do cluster. O fragmento original é chamado de
fragmento primário (primary shard) e os fragmentos replicados são chamados de
réplicas. O conjunto formado por um shard primário e suas réplicas é chamado de
grupo de replicação.

Por default, a quantidade de réplicas por shard é 1, o que quer dizer que no
final, ele terá 1 shard primário e 1 shard réplica. Dessa forma, sendo a quantidade
default de shards igual a 5, significa que, por padrão, serão adicionados 10 shards
para um índice: 5 shards primários e 5 shards réplica.

Figura 76 – Grupos de Replicação.

Fonte: Bo Andersen (2017).

Com a configuração mostrada acima, caso haja uma falha em nó ou em um


shard primário, a réplica, possuindo todos os dados do shard que falhou, assume o
papel de shard primário, garantindo a alta disponibilidade para os dados do índice em

Bootcamp Analista de Banco de Dados – Página 116 de 147


questão. Além da alta disponibilidade, a replicação traz um benefício adicional, que é
a capacidade de aumentar o desempenho das operações de pesquisa, uma vez que
elas podem ser executadas nas réplicas também.

Para manter os dados sincronizados em um cluster com replicação e


sharding, o Elasticsearch implementa técnicas da topologia de replicação
hierárquica de ambiente distribuído, ou como consta na sua documentação, um
modelo chamado backup primário (primary backup). Esse modelo consiste em
permitir e garantir que as operações que afetem o índice, como adicionar, atualizar
ou remover documentos, sejam feitas apenas no shard primário.

Nessa linha, o shard primário é responsável por validar as operações e


garantir que tudo esteja OK, estruturalmente e semanticamente falando. Quando a
operação tiver sido validada pelo shard primário, a operação será executada
localmente no próprio shard e, quando for concluída, será encaminhada para cada
um dos shards réplica no grupo de replicação em questão. Se o shard tiver várias
réplicas, a operação será executada em paralelo em cada uma das réplicas. Quando
a operação for concluída com êxito em todas as réplicas e elas responderem ao shard
primário, o shard primário retornará para o cliente que a operação foi concluída com
êxito. De forma resumida, para garantir a integridade dos dados, o Elasticsearch
utiliza a opção de replicação síncrona.

Bootcamp Analista de Banco de Dados – Página 117 de 147


Figura 77 – Replicação Síncrona.

Fonte: Bo Andersen (2017).

7.4. Instalação e configuração do Elasticsearch e do Kibana

O Elasticsearch, assim como a maioria dos componentes do Elastic Stack,


podem ser instalados em diversas plataformas com sistemas operacionais Windows,
Linux e iOS, além de containers Docker. No site da Elastic, no link
https://www.elastic.co/support/matrix, é possível encontrar uma matriz completa de
compatibilidade entre as versões dos produtos do Elastic Stack e as versões dos
sistemas operacionais.

O Elasticsearch foi construído usando Java e inclui uma versão integrada do


OpenJDK, com uma JVM empacotada e localizada no diretório jdk do diretório raiz do
Elasticsearch. Dessa forma, para o Elasticsearch funcionar, é necessário ter instalado
no servidor onde ele executará, o Java SE, disponível em
https://www.oracle.com/technetwork/java/javase/downloads/index.html.

Bootcamp Analista de Banco de Dados – Página 118 de 147


Para instalar o Elasticsearch é preciso fazer o download do produto no site
do fornecedor, em https://www.elastic.co/downloads/elasticsearch, pois ele não
oferece ainda a opção de instalar com repositório. No Windows, há também um
instalador MSI que faz toda o processo de descompactação e setup, e nos demais
sistemas operacionais, assim como no Windows, basicamente basta baixar o pacote
do produto compactado e descompactá-lo. A estrutura de diretórios,
independentemente do sistema operacional, é similar à mostrada abaixo.

Figura 78 – Estrutura de Diretórios do Elasticsearch.

Fonte: Gustavo (2019).

Nessa disciplina, para efeitos de aprendizado, vamos proceder com a


instalação stand alone, no sistema operacional Windows. Depois de baixado o pacote
de instalação (arquivo .zip) e descompactado, para executar o Elasticsearch, basta
navegar até a pasta de instalação usando o prompt do DOS, e na pasta bin, executar
elasticsearch.bat.

Bootcamp Analista de Banco de Dados – Página 119 de 147


Figura 79 – Iniciando o Elasticsearch.

Fonte: Gustavo (2019).

Depois de alguns momentos, estando tudo OK com a instalação do Java SE,


o cluster será inicializado.

Figura 80 – Elasticsearch inicializado.

Fonte: Gustavo (2019).

Para verificar se a instância do Elasticsearch está respondendo, basta abrir


um browser web e ir para o endereço http://localhost:9200/. Se tudo estive ok, o
Elasticsearch retornará um documento JSON, como o mostrado a seguir.

Bootcamp Analista de Banco de Dados – Página 120 de 147


Figura 81 – Elasticsearch Respondendo Via Rest API.

Fonte: Gustavo (2019).

Após a instalação, é possível customizar as configurações do Elasticsearch,


editando-as no arquivo elasticsearch.yml, localizado no diretório /config.

Figura 82 – Arquivo de Configuração do Elasticsearch.

Fonte: Gustavo (2019).

Bootcamp Analista de Banco de Dados – Página 121 de 147


As configurações mais utilizadas são as mostradas abaixo e para elas serem
aplicadas, basta remover o caracter “#” antes da configuração em questão, alterar
para o valor desejada após o “:” e reiniciar o Elasticsearch.

▪ cluster.name: nome descritivo do cluster Elasticsearch. Por default é


elasticsearch, como mostrado na figura 195;

▪ node.name: nome do nó (servidor) onde o Elasticsearch está rodando. Muito


útil para instalações em cluster, onde cada nó pode ter um nome mais
intuitivo;

▪ network.host: nome do host HTTP que responderá as requisições de Rest


API. Default é o localhost (ou o respectivo IP);

▪ http.port: porta HTTP onde o host receberá requisições. Default é 9200;

▪ discovery.seed_hosts: lista de nodes que compõem o cluster.

Obs.: para instalação em cluster, basta repetir o processo de instalação e


configuração em cada nó do cluster.

Falando acerca da instalação do Kibana, é preciso também baixar o pacote


de instalação, disponível em https://www.elastic.co/downloads/kibana, de acordo com
o sistema operacional desejado. Nessa disciplina, para efeitos de aprendizado, vamos
proceder com a instalação stand alone, no sistema operacional Windows.

Da mesma forma que o Elasticsearch, depois de baixado o pacote de


instalação (arquivo .zip) e descompactado, basta navegar até a pasta de instalação
usando o prompt do DOS, e na pasta bin, executar kibana. Feito isso, será iniciado
um web server no host em questão, na porta 5601, e automaticamente ele tentará
conectar com o Elasticsearch, no mesmo host e na porta 9200.

Após a instalação, é possível customizar as configurações do Kibana. Essa


configuração é feita no arquivo kibana.yml, localizado no diretório /config. As
configurações mais utilizadas são as mostradas abaixo, mas a listagem completa se
encontra em https://www.elastic.co/guide/en/kibana/current/settings.html. Para elas

Bootcamp Analista de Banco de Dados – Página 122 de 147


serem aplicadas, basta remover o caracter “#” antes da configuração em questão,
alterar para o valor desejada após o “:” e reiniciar o Kibana.

▪ server.host: nome do host HTTP que responderá as requisições de Rest


API. O default é localhost;

▪ server.port: porta HTTP do Kibana. O default é 5601;

▪ server.name: nome do nó (servidor) onde o Kibana está rodando, que pode


ser configurado para um nome mais intuitivo ou apropriado;

▪ elasticsearch.hosts: host(s) com o(s) qual(is) a interface do Kibana irá se


comunicar;

▪ kibana.index: nome do índice que o Kibana cria no Elasticsearch para o seu


funcionamento. O default é kibana.

Para começar a utilizar o Kibana, deve-se abrir um browser web e ir para o


endereço http://localhost:5601/. Se tudo estive ok, será aberta uma página similar à
mostrada a seguir.

Figura 83 – Executando o Kibana.

Fonte: Gustavo (2019).

Bootcamp Analista de Banco de Dados – Página 123 de 147


Nessa tela, deve-se selecionar se deseja importar dados de exemplo (botão
Try our sample data), ou se você mesmo inserirá os seus próprios dados para
começar a usar o Kibana. Escolha a primeira opção a título de aprendizado, e importe
os dados de exemplo que desejar (eCommerce order, Flight Data, Web Logs).

Figura 84 – Importar dados de exemplo no Kibana.

Fonte: Gustavo (2019).

Ao término da importação, será mostrada uma tela similar à abaixo, onde se


encontra toda as ferramentas do Kibana para interagir com o Elasticsearch.

Figura 85 – Página home do Kibana.

Fonte: Gustavo (2019).

Bootcamp Analista de Banco de Dados – Página 124 de 147


A mais utilizada delas para desenvolvimento é a Console do Dev Tools, cujo
botão de acesso pode ser encontrado no menu lateral esquerdo. Com essa
ferramenta client do Kibana, é possível criar e gerenciar os índices, inserir e manipular
documentos no Elasticsearch, sem se preocupar com cabeçalhos HTTP, em formatar
respostas, etc. Por outro lado, não há nada diferente na comunicação feita através da
API, que acontece via requisições HTTP, definidas por uma combinação do verbo
HTTP (GET / POST / PUT / DELETE) a requisição URI e o corpo (body) da requisição.

Figura 86 – Dev Tools do Kibana.

Fonte: Gustavo (2019).

Nessa console, há um atalho facilitador para as situações onde se estiver


trabalhando com requisições cURL. Uma vez estando a query escrita na console, no
formato aceito pelo Kibana, é possível gerar o correspondente em cURL (ex. curl -
XGET "http://localhost:9200/_search"), bastando clicar na opção mostrada na
imagem a seguir.

Bootcamp Analista de Banco de Dados – Página 125 de 147


Figura 87 – Copiar a requisição como cURL.

Fonte: Gustavo (2019).

7.5. Definindo e administrando índices no Elastic Search

Para criar índices no Elasticsearch, pode-se usar a Console do Dev Tools no


Kibana, ou a interface de linha de comando com requisições cURL. Usando a console,
a sintaxe do comando é PUT /NOME_DO_INDICE, como mostrado no exemplo
abaixo, ao criar o índice equipamento.

Figura 88 – Criando um Índice.

Fonte: Gustavo (2019).

Bootcamp Analista de Banco de Dados – Página 126 de 147


O nome do índice possui algumas limitações e regras, como as mostradas
abaixo:

▪ Apenas letras minúsculas;

▪ Não pode conter \, /, *, ?, ", <, >, |, espaço, vírgula, # ou :(a partir da 7.0);

▪ Não pode iniciar com -, _, ou +;

▪ Não pode ser somente . ou .. ;

▪ Tamanho máximo de 255 bytes (não caracteres).

Adicionalmente, pode-se informar algumas configurações a criação do índice,


como quantidade de réplicas, shards etc., como mostrado no exemplo:

PUT twitter

{ "settings" :

{ "number_of_shards" : 3,

"number_of_replicas" : 2

} }

Para verificar se um índice existe, usa-se o comando HEAD


/NOME_DO_INDICE.
Figura 89 – Verificando a existência de um índice.

Fonte: Gustavo (2019).

Bootcamp Analista de Banco de Dados – Página 127 de 147


Para listar informações e detalhes acerca de um índice, usa-se o comando
GET /NOME_DO_INDICE.

Figura 90 – Listando informações do índice.

Fonte: Gustavo (2019).

Para deletar um índice usando a console, deve-se usar a sintaxe do DELETE


/NOME_DO_INDICE, como mostrado no exemplo abaixo, ao excluir o índice
Equipamento, criado no exemplo anterior.

Figura 91 – Excluindo um Índice.

Fonte: Gustavo (2019).

Bootcamp Analista de Banco de Dados – Página 128 de 147


7.6. Trabalhando com documentos no Elastic Search

Para inserir documentos em um índice, envia-se uma requisição POST para


uma URI, formada pelo nome do índice (que não precisa estar criado previamente),
um endpoint (_doc ou _create), o ID do documento (opcional, pois caso não seja
informado, a API invocada gerará um automaticamente) e por fim, o documento JSON
com os dados do documento que deseja-se inserir. Nos exemplos abaixo, foi inserido
um documento com os campos nome, usuario.primeironome, usuario.sobrenome e
tipo no índice equipamentos. No primeiro, o ID foi especificado explicitamente. No
segundo, omitindo o ID, a API gerou um automaticamente.

Figura 92 – Inserindo documento com ID específico.

Fonte: Gustavo (2019).


Figura 93 – Inserindo documento com ID automático.

Fonte: Gustavo (2019).

Bootcamp Analista de Banco de Dados – Página 129 de 147


Outra possibilidade para inserir documentos é usar o verbo HTTP PUT, de
forma similar ao POST, com a exceção de que usando esse método, é preciso
especificar, de forma explícita, o ID do documento, como no exemplo abaixo.

Figura 94 – Inserindo documento com PUT.

Fonte: Gustavo (2019).

Obs.: desde a primeira versão até a versão 7, os endpoints podiam ter um


tipo (type), fazendo com que cada documento fosse armazenado em um índice e
atribuído à um tipo. Cada tipo era usado para representar o tipo de documento sendo
indexado. Por exemplo, um índice do twitter poderia ter um tipo usuário e um tipo
tweet. Cada tipo podia ter seus próprios campos, ou seja, o tipo usuário poderia ter
um campo nome, um campo nomeusuario e um campo email, enquanto o tipo tweet
poderia ter um campo conteudo, datapostagem e o campo nome_usuario. Entretanto,
já está sendo tratado como descontinuado e por isso deve-se usar os endpoints sem
tipo ((/{index}/_doc/{id}, /{index}/_doc, ou /{index}/_create/{id})), como informado no
início do tópico. Na versão 7, ainda está sendo aceita a sintaxe antiga, mas é exibido
um aviso, como mostrado abaixo.

Bootcamp Analista de Banco de Dados – Página 130 de 147


Figura 95 – Aviso sobre a descontinuidade de tipos.

Fonte: Gustavo (2019).

Para consultar documentos pelo ID, é usado o verbo HTTP GET, seguido do
nome do índice, a API _doc e ID do documento que deseja, como mostrado a seguir.
Além do conteúdo do documento (campo _source) são retornados alguns campos
com metadados do documento, que o Elasticsearch insere automaticamente, como
por exemplo a versão (campo _version).

Figura 96 – Consultando documentos pelo ID.

Fonte: Gustavo (2019).

Para retornar mais documentos, pode-se usar a API _mget em conjunto com
o GET: GET equipamentos/_doc/_mget { "ids": [ "1","2" ] }.

Bootcamp Analista de Banco de Dados – Página 131 de 147


Outra operação possível, é verificar pela existência de um documento pelo
seu ID, usando o verbo HEAD, com a sinxate HEAD NOMEINDICE/_doc/ID.

Figura 97 – Verificando a existência de um documento.

Fonte: Gustavo (2019).

Para alterar os documentos, pode-se usar a estratégia de substituição do


documento (replace) ou de atualização (update). Para substituir um documento,
atualizando o valor de um ou mais campos, removendo ou acrescentando novos
campos, basta submeter o comando de criação de documento, passando o ID do
documento a ser substituído.

No exemplo abaixo, está se substituindo o documento existente de ID 1,


adicionando o campo datacompra:

Bootcamp Analista de Banco de Dados – Página 132 de 147


Figura 98 – Substituindo um documento.

Fonte: Gustavo (2019).

Já na estratégia de atualização, pode-se usar o endpoint _update com a


sintaxe: POST NOME_INDICE/_update/ID { “doc”: { ATUALIZACAO_AQUI }}. No
exemplo abaixo, está se atualizando o campo nome do documento de ID 2 do índice
equipamentos, além de inserir o novo campo fornecedor.

Bootcamp Analista de Banco de Dados – Página 133 de 147


Figura 99 – Atualizando um documento.

Fonte: Gustavo (2019).

Há também o recurso de atualizar um documento via script e não apenas com


um valor literal, permitindo fazer-se cálculos e operações mais complexas de
atualização. Esse recurso, chamado de scripted updates usa o campo de metadado
source, junto com as variáveis ctx e params, com os quais é possível acessar os
campos do documento, passar valores de parâmetros para o script e até mesmo
definir uma linguagem a ser utilizada no código do script. Abaixo temos um exemplo

Bootcamp Analista de Banco de Dados – Página 134 de 147


que utiliza um script para incrementar o campo contador no índice postagens, com
base no parâmetro contagem passado para o script.

POST postagens/_update/1

"script" : {

"source": "ctx._source.contador += params.contagem",

"lang": "painless",

"params" : {

"contagem" : 4

} } }

No site do fornecedor podem ser encontrados mais detalhes desse recurso


em www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting.html.

Além dessas opções, que atualizam um documento por vez, pelo ID do


mesmo, com a API update_by_query é possível alterar vários documentos que
atendam à um critério, quando usado em conjunto com scripted updates. No exemplo
abaixo, está-se incrementando todo o campo curtidas do índice postagens, somente
para as postagens do usuário Gustavo.

POST postagens/_update_by_query

"script": {

"source": "ctx._source.curtidas++",

"lang": "painless"

},

"query": {

"term": {

"usuario": "Gustavo"

Bootcamp Analista de Banco de Dados – Página 135 de 147


} }}

Por fim, temos também recursos para deletar documentos. Da mesma forma
que no update, é possível deletar apenas um documento com o verbo HTTP DELETE
ou excluir vários documentos usando a API _delete_by_query.

Para deletar apenas um documento a sintaxe é:

DELETE NOME_INDICE/_doc/ID

Figura 100 – Excluindo documento pelo ID.

Fonte: Gustavo (2019).

Para deletar um conjunto de documentos, deve-se passar a variável query


(que será o filtro, similar à condição where de um delete na linguagem SQL) para a
API delete_by_query, usando-se o verbo HTTP POST.

Bootcamp Analista de Banco de Dados – Página 136 de 147


POST NOME_INDICE/_delete_by_query { “query”: {

“match”: {“campo”:”valor” }

} }

Exemplificando, para excluir os documentos do índice equipamentos que são


do tipo “DESKTOP”:

POST equipamentos/_delete_by_query
{
"query": {
"match": {"tipo":"DESKTOP"}
}
}

7.7. Overview de agregações no Elastic Search

O recurso de agregação tem o objetivo de fornecer dados sumarizados


agrupados com base em uma pesquisa. Uma agregação pode ser vista como uma
unidade de trabalho que cria informações analíticas sobre um conjunto de
documentos.

Existem vários tipos de agregações, cada um com sua finalidade e saída de


dados. De forma macro, as agregações são divididas em quatro famílias principais:

▪ Bucketing: família de agregações que criam depósitos (buckets), onde cada


depósito é associado a uma chave e a um critério de documento. Quando a
agregação é executada, todos os critérios dos buckets são avaliados em
cada documento e, quando há uma correspondência do critério, considera-se
que o documento "está incluído" no intervalo relevante. No final do processo
de agregação, haverá uma lista de intervalos, cada um com seu conjunto de
documentos.

▪ Métrica: agregações que acompanham e calculam as métricas em um


conjunto de documentos.

Bootcamp Analista de Banco de Dados – Página 137 de 147


▪ Matriz: família de agregações que operam em vários campos e produzem um
resultado de matriz com base nos valores extraídos dos campos do
documento solicitado.

▪ Pipeline: agregações que consolidam a saída de outras agregações e suas


métricas associadas.

As agregações mais utilizadas são as da família de métricas, utilizadas em


larga escala no mundo relacional, para somar, contar, calcular média, valor mínimo,
máximo, etc. Para executar esse tipo de agregação, usa-se o verbo HTTP POST junto
da API aggs, aliada à função desejada (no exemplo abaixo, retornar o valor máximo
das vendas).

POST /vendas/_search?size=0
{
"aggs" : {
"valor_maximo" : { "max" : { "field" : "total_da_venda" } }
}
}

A lista completa das agregações disponíveis e a forma de uso para cada uma
delas, se encontra disponível no site do fornecedor, no link
www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html.

7.8. Overview de Mapping

Mapeamento é o processo para se definir como um documento e os campos


que ele contém serão armazenados e indexados. Pode-se, por exemplo, usar
mapeamento para definir:

▪ Quais campos do tipo string devem ser tratados como campos full text.

▪ Quais campos contêm números, datas ou geolocalização.

Bootcamp Analista de Banco de Dados – Página 138 de 147


▪ O formato de datas.

▪ Regras customizadas para controlar o mapeamento para campos


adicionados dinamicamente.

Nesse sentido, cada campo dos índices tem um tipo de dados que pode ser:

▪ Um tipo simples como texto, palavra-chave, data, long, double, boolean ou


IP.

▪ Um tipo que suporta a natureza hierárquica do JSON, como object ou nested.

▪ Ou um tipo especializado como geo_point ou geo_shape.

Campos e tipos de mapeamento não precisam ser definidos antes de serem


usados. Graças ao mapeamento dinâmico, novos campos serão adicionados
automaticamente, apenas pela indexação de um novo documento.

Para além disso, é possível também especificar de forma explícita os


mapeamentos. Para fazer isso, basta criar um índice e adicionar campos à ele com o
verbo PUT, definindo o tipo de dados para cada campo, como mostrado abaixo.
Figura 101 – Mapeamento explícito.

Fonte: Elastic (2019).

Bootcamp Analista de Banco de Dados – Página 139 de 147


Capítulo 8. Considerações finais

Com o surgimento do movimento DevOps e o surgimento dos bancos de


dados não relacionais, surgem muitas dúvidas quanto ao futuro das profissões
tradicionais relacionadas a administração de bancos de dados e sobre o
desenvolvimento e a arquitetura de sistemas nesse novo contexto.

Neste capítulo iremos abordar um pouco sobre o que se espera das


profissões de DBA e seu papel no desenvolvimento de aplicações em um mondo ágil
e não relacional.

8.1. O papel dos DBAs

Existem algumas diferenças entre os modelos de código e modelos


relacionais de bancos de dados. Muitas vezes as modelagens entidade relacional
desenham domínios que não são facilmente expressos na programação, e o contrário
às vezes também é percebido. Mesmo utilizando frameworks de mapeamento
entidade relacional (ORM), ainda assim encontramos muitas vezes uma série de
dificuldades em expressar nossos domínios.

Parte dessas diferenças são agravadas muitas vezes pela evolução das
práticas e dos padrões das linguagens de programação em descompasso às práticas
de bancos de dados.

Além disso, uma série de burocracias são geradas para proteger os


ambientes de produção, blindando os bancos de dados e consecutivamente criando
um gargalo que tira a agilidade da entrega de novas funcionalidades em produção.

Quando os bancos de dados NOSQL surgiram, muitos desenvolvedores e


arquitetos encontraram ali um atalho para agilizar o processo de entrega, pois com
modelos não normalizados não havia a necessidade de paradas, e o programador
ficava responsável pelas operações de bancos de dados.

Bootcamp Analista de Banco de Dados – Página 140 de 147


Algumas pessoas começaram a enxergar ali inclusive um movimento NoDBA
(em alusão a sigla do NOSQL), no qual o DBA não estaria envolvido neste processo
de evolução, removendo os gargalos criados pelas migrações e atualizações dos
dados.

Figura 102 – NoDBA.

Fonte: https://martinfowler.com/bliki/NoDBA.html.

O problema com esse tipo de abordagem é que práticas necessárias de


manutenção e otimização das plataformas são deixadas de lado, e fica nas mãos dos
desenvolvedores a escolha das tecnologias e abordagens para a modelagem de
dados, o que muitas vezes leva a escolha de tecnologias ruins ou de modelagens de
dados que posteriormente se mostram insustentáveis pelo time.

O papel do DBA sempre foi fundamental para garantir a segurança dos dados
e o desempenho dos sistemas de gerenciamento de bancos de dados, seja atuando
em incidentes, realizando manutenções preventivas ou projetando a organização dos
dados para refletir cenários de análise.

Desta forma, é necessário que o DBA não seja visto como um obstáculo para
a agilidade, e sim como um membro fundamental para o time de desenvolvimento, e
para isso é necessário que o DBA se especialize também em práticas de engenharia
de software e foque na arquitetura de dados da aplicação.

Bootcamp Analista de Banco de Dados – Página 141 de 147


Figura 103 – DBA.

Fonte: http://dell.com/.

Desde o surgimento do movimento DevOps, a integração entre os times para


garantir o funcionamento e evolução dos sistemas vem se tornando cada vez mais
forte, e com isso o DBA deve se aproximar do time de desenvolvimento e operações
atuando desde o momento do desenho da arquitetura do projeto, tratando a questão
de persistência como uma questão de desenvolvimento de software, e não como uma
atividade e disciplina isoladas do resto da aplicação.

O pensamento deve ser de que a aplicação não é apenas um meio amigável


para se tratar os dados que estão salvos em um banco de dados, e sim que o banco
de dados faz o papel de repositório para servir à aplicação e ao usuário final
garantindo desempenho e disponibilidade dos dados.

O DBA deve estar atento a uma série de mudanças que ocorreram, como o
CodeFirst, no qual primeiro é gerado e pensado a nível de código e depois o banco é
atualizado através de uma migration para refletir o modelo; o surgimento de nuvens
públicas e privadas, serviços de bancos de dados como serviços e a necessidade da
persistência poliglota.

Com isso, o DBA deve trabalhar como arquiteto de dados, sugerindo e


aplicando modelos de bancos de dados relacionais e não relacionais conforme o
melhor cenário de aplicação.

Bootcamp Analista de Banco de Dados – Página 142 de 147


8.2. O dia a dia de um DBA que atua com NOSQL

Vejamos rapidamente um exemplo de como é o dia a dia de um DBA que


trabalha em um time ágil com NOSQL e DevOps, quais são suas atribuições e
atuações diárias nos quesitos de administração, desenvolvimento e otimizações.

▪ Administração:

A administração do banco de dados começa no planejamento das


atualizações do sistema, o que muitas vezes requer que o DBA tenha acesso, planeje
e configure ferramentas de integração contínua e de publicações automatizadas.

Como podemos ter diferentes tipos de bancos de dados, é necessário que a


estrutura de atualização esteja preparada para realizar as alterações sem parada do
sistema, ou pelo menos de forma que ela seja imperceptível ao usuário.

Ele deve possuir um painel que lhe permita monitorar os diferentes sistemas
de bancos de dados, com atenção especial no desempenho das requisições e na
forma como os dados estão sendo usadas e requisitadas.

Além disso, ele garante as rotinas e práticas de manutenção, backup e testes


de restauração, além de fornecer ao time de desenvolvimento um ambiente de
trabalho que represente bem o cenário de produção.

▪ Desenvolvimento:

É necessário que DBA consiga criar códigos e scripts para gerar análises e
relatórios, tendo em mente que nem todos os bancos de dados serão consultados
através de instruções SQL.

Deve estar junto ao time de desenvolvimento para realizar a depuração e a


análise de problemas e inconsistência nos dados, implementar escalabilidade,
distribuição e garantir a disponibilidade dos dados e dos ambientes.

Ele deve sempre sugerir alterações dos modelos de dados, criação de índices
e até mesmo mudança nas estratégias de armazenamento e acesso aos dados.

Bootcamp Analista de Banco de Dados – Página 143 de 147


▪ Otimizações:

Ele deve continuamente medir a performance do banco de dados, ajustar as


funções de distribuição dos dados e reportar problemas de desempenho ao time de
desenvolvimento, sugerindo pontos de melhoria.

Resumo do capítulo

O papel do DBA vem se transformando dentro do ciclo de vida de


desenvolvimento, no qual ele ganha cada vez mais importância na definição, no
desenho e na arquitetura dos dados e da informação.

Ele deve se tornar o ponto focal de conhecimento dentro do time em relação


a tecnologias e modelos de dados a serem adotados, atuando continuamente na
melhoria e no tratamento dos dados, muitas vezes usando recursos de codificação.

Material complementar

▪ DATASTAX. WhitePaper – DBA’s Guide to NoSQL. Disponível em:


<https://www.datastax.com/dbas-guide-to-NOSQL>. Acesso em: 17 set. 2020.

▪ FOWLER, Martin. No DBA. 2013. Disponível em:


<https://martinfowler.com/bliki/NoDBA.html>. Acesso em: 17 set. 2020.

▪ HILBERT, Matt. Does NoSQL = NoDBA? In: Redgat Hub, 2014. Disponível em:
<https://www.simple-talk.com/opinion/opinion-pieces/does-NOSQL-nodba/>.
Acesso em: 17 set. 2020.

▪ MAPPIC, Sandy. Will NoSQL and Big Data Kill the DBA? In: AppDynamics,
2011. Disponível em: <https://blog.appdynamics.com/engineering/will-
NOSQL-kill-the-dba/>. Acesso em: 17 set. 2020.

Bootcamp Analista de Banco de Dados – Página 144 de 147


▪ MongoDB vs RDBMS DBA duties. In: Database Administrators – Questions.
Stack Exchange, 2016. Disponível em:
<https://dba.stackexchange.com/questions/138522/mongodb-vs-rdbms-dba-
duties>. Acesso em: 17 set. 2020.

▪ RANGEGOWDA, Dharshan. The Role of the DBA in NoSQL. In: DZone, 2014.
Disponível em: <https://dzone.com/articles/role-dba-NOSQL>. Acesso em: 17
set. 2020.

▪ _____________________. The Role of the DBA in NoSQL. In: ScaleGrid,


2014. Disponível em: <https://scalegrid.io/blog/the-role-of-the-dba-in-
NOSQL/>. Acesso em: 17 set. 2020.

Bootcamp Analista de Banco de Dados – Página 145 de 147


Referências

ANDERSEN, Bo. Understanding Replication. In: Elasticsearch. Disponível em


<https://codingexplained.com/coding/elasticsearch/understanding-replication-in-
elasticsearch>. Acesso em: 17 set. 2020.

ANDERSEN, Bo. Understanding Sharding. In: Elasticsearch. Disponível em


<https://codingexplained.com/coding/elasticsearch/understanding-sharding-in-
elasticsearch>. Acesso em: 17 set. 2020.

BROOKS, C. Enterprise NoSQL for Dummies. 1. Ed. EUA: John Wiley & Sons, Inc,
2014.

BROWNER, Julian. Brewer's CAP Theorem. Disponível em


<http://www.julianbrowne.com/article/brewers-cap-theorem>. Acesso em: 17 set.
2020.

ELASTIC. Disponível em: <http://www.elastic.co/>. Acesso em: 17 set. 2020.

FIREBASE. Firebase Realtime Database. Disponível em:


<https://firebase.google.com/docs/database/?hl=pt-br>. Acesso em: 17 set. 2020.

FOWLER, M., SADALAGE, P. The future is: Polyglot Persistence. DISPONÍVEL EM:

<https://martinfowler.com/articles/nosql-intro-original.pdf>. Acesso em: 17 set. 2020.

FOWLER, M.; SADALAGE, P. NoSQL Distilled: A Brief Guide to the Emerging World
of Polyglot Persistence. 1. Ed. EUA: Addison-Wesley Professional, 2012, p. 192.

GORMLEY, Clinton; TONG, Zachary. Elasticsearch: The Definitive Guide: A


Distributed Real-Time Search and Analytics Engine. USA: O’Reilly, 2015.

HILLS, Ted. NOSQL and SQL Data Modeling: Bringing Together Data, Semantics,
and Software. Technics Publications, 2016.

LAKSHMANAN, Valliappa. Data Science on the Google Cloud Platform: Implementing


End-to-End Real-time Data. USA: O’Reilly, 2015.

Bootcamp Analista de Banco de Dados – Página 146 de 147


MCCREARY, D.; KELLY A. Making Sense of NoSQL: A guide for managers and the
rest of us. 1. Ed. EUA: Manning Publications, 2013, 312 p.

MONGODB. Site Oficial do Fabricante. Disponível em <https://www.mongodb.com>.


Acesso em: 17 set. 2020.

NOSQL DATABASE ORG. Disponível em: <http://nosql-database.org/>. Acesso em:


17 set. 2020.

REDMOND, E.; WILSON J. Seven Databases in Seven Weeks: A Guide to Modern


Databases and the NoSQL Movement. 1. Ed. EUA: Pragmatic Bookshelf, 2012, p.
352.

SIMPLILEARN. Introduction to NOSQL Databases Tutorial. Disponível em


<https://www.simplilearn.com/introduction-to-nosql-databases-tutorial-video>.
Acesso em: 17 set. 2020.

SOLLIVAN, D. NoSQL for mere mortals. 1. Ed. EUA: Addison-Wesley Professional,


2015, p. 552.

Bootcamp Analista de Banco de Dados – Página 147 de 147

Potrebbero piacerti anche