Como escolher um banco de dados
Tags: braziliandevs, beginners, todayilearned
Published: 2022-05-14 02:56:46

### Today I Learned 13/05/2022

## SQL E NoSQL

Antes de começarmos a explorar os diferentes tipos de banco de dados é importante diferenciar bancos SQL e NoSQL. O SQL é uma linguagem utilizada há muito tempo e era utilizado independente do tipo de dado. Fazendo assim que os dados sempre fossem moldados como relacionais.

Mas com aplicações que precisam de dados que vem de fontes diversas alem de necessitarem tambem de latencia de disponibilidade especificas fez com que começassem a surgir bancos de dados `Not Only SQL` ou `NoSQL`

O NoSQL é um categoria que engloba múltiplos banco de dados, semi-relacionais ou não relacionais. Esses bancos não são necessariamente melhores em relação aos bancos relacionais, eles servem a um proposito especifico e nesse artigo vou tentar descrever como escolher qual o banco de dados utilizar

## Tipos de Bancos de dados

### Relacional
O tipo ideal para dados tabulares e uniformes. São estabelecidas relações entre os dados de acordo com as informações contidas em linhas e seus atributos distribuídos em colunas

Os bancos relacionais são maduros e possuem a linguagem SQL como padrão que acaba sendo uma das suas grandes vantagens. Se formos considerar outros benefícios temos a alta consistência dos dados que devem se manter em replicas dos bancos, sendo assim o banco relacional é o ideal para transações criticas de negócios.

### Chave-valor
Ao contrario do banco relacional os bancos chave-valor é focado em escalabilidade e baixa latência, porem isso vem em detrimento da consistência. 

Os bancos chave-valor são formados por uma string que serve como uma chave que é o índice e o valor que são os dados guardados para essa string. Ele é recomendado para operações que não precisam de consistência e que precisam de baixa latencia, por isso muita gente inclusive eu, gostam de utilizar esse tipo de bancos para fazer cache, onde em bancos como o DynamoDB da Amazon podemos inclusive setar facilmente um tempo para o cache expirar e ele apagar aquele dado

### Orientado a documentos
Acredito que nesse tipo o mais famoso é o MongoDB. Nesse tipo de banco os dados tem formato de documentos. e diferente de bancos relacionais os documentos não precisam todos ter os mesmos campos, o que acaba contribuindo para que eles sejam mais facil de escalar horizontalmente.

Para endereçar os documentos são usadas chaves únicas que os representam (geralmente o ID) como os de chave-valor mas os de documento são mais complexos pois um documento pode englobar pares de chave-valor.

Bancos orientados a documentos são uma ótima opção se não precisa que os dados tenham os mesmos campos


### Banco de dados em memória
É a própria memoria do celular em caso de aplicações mobile, ou em caso de aplicações web pode ser o local storage por exemplo

## Como escolher
Beleza, agora que já sabemos alguns dos tipos de bancos de dados como que escolhemos o banco de dados que queremos?

### Teorema CAP
![Imagem do teorema](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/83mt2rrdbdt7p5d6gud6.png)
 
É um teorema que fala que os bancos de dados distribuídos só podem entregar bem 2 de 3 características, sendo elas:

- Consistência (Consistency)
Significa que todos os clientes veem os mesmos dados ao mesmo tempo, não importando em qual nó eles se conectem. Para garantir isso sempre que um dado for gravado em um nó ele deve ser instantaneamente replicado para os outros nós

- Disponibilidade (Availability)
Significa que qualquer cliente que fizer uma solicitação de dados vai ser respondido mesmo que um ou mais nós estejam caídos. Ou seja todos os nós em funcionamento retornam uma resposta valida para qualquer solicitação, sem exceção.

- Tolerância de partição (Partition Tolerance)\
Partição é uma quebra de comunicações dentro de um sistema distribuído, uma conexão perdida ou temporariamente lenta entre dois nós. tolerância de partição significa que o cluster deve funcionar mesmo que ocorram uma ou mais falhas de comunicação entre os nós do sistema

### Tipos desses bancos
> Banco de dados CP: um banco de dados CP entrega consistência e tolerância de partição em detrimento da disponibilidade. Quando uma partição ocorre entre dois nós quaisquer, o sistema deverá desativar o nó não consistente (ou seja, torná-lo indisponível) até que a partição seja resolvida.

> Banco de dados AP: um banco de dados AP entrega disponibilidade e tolerância de partição em detrimento da consistência. Quando ocorre uma partição, todos os nós permanecem disponíveis, exceto aqueles na extremidade errada de uma partição podem retornar uma versão mais antiga de dados do que outros. Quando a partição é resolvida, os bancos de dados AP geralmente ressincronizam os nós para corrigir todas as inconsistências no sistema.

> Banco de dados CA: um banco de dados CA entrega consistência e disponibilidade em todos os nós. Porém, isso não é possível se houver uma partição entre dois nós quaisquer no sistema, no entanto, e, portanto, não poderá entregar tolerância a falhas.

#### Banco de dados CP
MongoDB é um exemplo de banco de dados CP, ele funciona como um sistema de mestre único onde ele tem apenas um nó primário que recebe todas as operações de escrita. Todos os outros nós nesse conjunto são os nós secundários que replicam o log de operações do nó primário e aplicam ao seu próprio conjunto de dados. 

Por padrão os clientes leem a partir do nó primário mas pode ser definida uma preferencia de leitura que faz com que eles leiam dos nós secundários, caso esse nó primário tenha algum problema algum nó secundário é eleito para assumir o seu lugar, durante esse período os clientes não podem fazer solicitações para manter a consistência por toda a rede.

#### Banco de dados AP
Cassandra é um exemplo de banco de dados AP ele é um banco de dados que permite armazenar os dados em uma rede distribuída. No entanto ao contrario do mongo ele tem uma arquitetura sem mestre e portanto ela acaba tendo diversos pontos de falha ao invés de um único. 

O Cassandra consegue entregar disponibilidade porem não consegue entregar consistência o tempo todo. Como ele não tem um nó principal todos os nós precisam estar disponíveis o tempo todo. No entanto o Cassandra fornece consistência eventual permitindo que os clientes escrevam em qualquer nó a qualquer momento e resolvem inconsistência o mais rápido possível

Como a inconsistência somente acontece caso tenha uma partição o Cassandra fornece a funcionalidade de reparação para ajudar os nós a recuperar sua consistência em relação aos outros



#### Banco de dados CA
A maioria dos bancos relacionais serve de exemplo para esse, inclusive esse é o motivo de ser extremamente dificil de distribuir bancos relacionais, pois é impossivel garantir que não vai ocorrer uma falha em sistemas distribuidos, e se ocorrer como esses bancos não são tolerantes a falhas ele vai dar um erro e ficar fora do ar

## ACID
É um acronimo para caracteristicas de bancos de dados relacionais

- Atomicidade
O commit finaliza uma operação por completo ou o banco de dados dá um rollback para seu estado anterior

- Consistência
Qualquer mudança precisa manter a integridade dos dados ou é cancelada

- Isolado
Nenhum read/write deve impactar no read/write de outras transações

- Durabilidade
Commits realizados com sucesso devem ser permanentes

> Referencias
[Que tipo de Banco de Dados utilizar](https://solvimm.com/blog/que-tipo-de-banco-de-dados-utilizar/)
[How to choose the right database for your service
](https://medium.com/wix-engineering/how-to-choose-the-right-database-for-your-service-97b1670c5632)
[Teorema CAP](https://www.ibm.com/br-pt/cloud/learn/cap-theorem#toc-o-que--o-t-6RfYDMyx)