Olá amigos. Antes de partir para a segunda parte dos feriados de maio, compartilhamos com você o material que traduzimos às vésperas do lançamento de um novo fluxo à taxa de
"Relational DBMS" .

Os desenvolvedores de aplicativos gastam muito tempo comparando vários bancos de dados operacionais para escolher o que funciona melhor para a carga de trabalho pretendida. As necessidades podem incluir modelagem de dados simplificada, garantias transacionais, desempenho de leitura / gravação, dimensionamento horizontal e tolerância a falhas. Por tradição, a escolha começa com uma categoria de banco de dados, SQL ou NoSQL, pois cada categoria fornece um conjunto claro de compensações. Alto desempenho em termos de baixa latência e alto rendimento é geralmente visto como um requisito de troca e, portanto, é necessário para qualquer banco de dados da amostra.
O objetivo deste artigo é ajudar os desenvolvedores de aplicativos a fazer a escolha certa entre SQL e NoSQL no contexto da modelagem de dados de aplicativos. Examinaremos um banco de dados SQL, o PostgreSQL e dois NoSQL - Cassandra e MongoDB, para falar sobre o básico do design de banco de dados, como criar tabelas, preenchê-las, ler dados da tabela e excluí-los. No próximo artigo, veremos definitivamente índices, transações, JOINs, diretivas TTL e design de banco de dados baseado em JSON.
Qual é a diferença entre SQL e NoSQL?Os bancos de dados SQL aumentam a flexibilidade do aplicativo com garantias transacionais do ACID, bem como sua capacidade de consultar dados usando JOINs de maneiras inesperadas sobre os modelos de banco de dados relacional normalizados existentes.
Dada sua arquitetura monolítica / de nó único e o uso de um modelo de replicação mestre-escravo para redundância, os bancos de dados SQL tradicionais não possuem dois recursos importantes: escalabilidade linear do registro (ou seja, divisão automática em vários nós) e perda de dados automática / zero. Isso significa que a quantidade de dados recebidos não pode exceder a taxa de transferência máxima de gravação de um nó. Além disso, alguma perda temporária de dados deve ser levada em consideração durante a tolerância a falhas (em uma arquitetura sem compartilhamento de recursos). Aqui você deve ter em mente que confirmações recentes ainda não foram refletidas na cópia do escravo. Atualizações sem tempo de inatividade também são difíceis de obter nos bancos de dados SQL.
Os bancos de dados NoSQL são normalmente distribuídos por natureza, ou seja, neles, os dados são divididos em seções e distribuídos por vários nós. Eles exigem desnormalização. Isso significa que os dados inseridos também devem ser copiados várias vezes para responder a solicitações específicas que você envia. O objetivo geral é obter alto desempenho, reduzindo o número de fragmentos disponíveis durante a leitura. Segue a declaração de que o NoSQL exige que você modele suas consultas, enquanto o SQL exige que você modele seus dados.
O NoSQL se concentra em obter alto desempenho em um cluster distribuído, e essa é a principal justificativa para muitas trocas de design de banco de dados que incluem ACIDs de perda de transação, JOINs e índices secundários globais consistentes.
Acredita-se que, embora os bancos de dados NoSQL forneçam escalabilidade de gravação linear e alta tolerância a falhas, a perda de garantias transacionais os torna inadequados para dados essenciais.
A tabela a seguir mostra como a modelagem de dados no NoSQL difere do SQL.
SQL e NoSQL: Por que ambos são necessários?Aplicativos do mundo real com um grande número de usuários, como Amazon.com, Netflix, Uber e Airbnb, realizam tarefas complexas e com várias classificações. Por exemplo, um aplicativo de comércio eletrônico como o Amazon.com precisa armazenar dados leves e altamente críticos, como informações sobre usuários, produtos, pedidos, faturas, além de dados pesados, mas menos sensíveis, como análises de produtos, mensagens de suporte , atividade do usuário, revisões e recomendações do usuário. Naturalmente, esses aplicativos contam com pelo menos um banco de dados SQL junto com pelo menos um banco de dados NoSQL. Nos sistemas inter-regionais e globais, o banco de dados NoSQL funciona como um cache distribuído geograficamente para dados armazenados em um banco de dados SQL de origem confiável, trabalhando em qualquer região.
Como o YugaByte DB combina SQL e NoSQL?Construído em um mecanismo de armazenamento misto orientado a log, sharding automático, replicação de consenso de sharding distribuído e transações distribuídas ACID (inspiradas no Google Spanner), o YugaByte DB é o primeiro banco de dados de código aberto do mundo a ser simultaneamente compatível com o NoSQL (Cassandra & Redis ) e SQL (PostgreSQL). Conforme mostrado na tabela abaixo, o YSQL, a API YugaByte DB compatível com Cassandra, adiciona os conceitos de transações ACID únicas e com várias chaves e índices secundários globais às APIs NoSQL, abrindo assim a era dos bancos de dados transacionais NoSQL. Além disso, o YSQL, uma API YugaByte DB compatível com PostgreSQL, adiciona a noção de escala linear de registros e tolerância automática a falhas à API SQL, introduzindo bancos de dados SQL distribuídos no mundo. Como o banco de dados YugaByte DB é essencialmente transacional, a API NoSQL agora pode ser usada no contexto de dados críticos.

Como afirmado anteriormente no artigo
“Introdução ao YSQL: uma API SQL distribuída compatível com PostgreSQL para o YugaByte DB” , a escolha entre SQL ou NoSQL no YugaByte DB depende inteiramente das características da carga de trabalho principal:
- Se a carga de trabalho principal for operações com várias chaves com JOINs, ao escolher YSQL, entenda que suas chaves podem ser distribuídas por vários nós, o que levará a um atraso maior e / ou taxa de transferência menor do que no NoSQL.
- Caso contrário, selecione uma das duas APIs NoSQL, tendo em mente que você obterá melhor desempenho como resultado de consultas serem atendidas a partir de um nó por vez. O YugaByte DB pode servir como um único banco de dados operacional para aplicativos complexos reais, nos quais você precisa gerenciar várias cargas de trabalho ao mesmo tempo.
O laboratório de modelagem de dados da próxima seção é baseado nos bancos de dados YugaByte DB compatíveis com a PostgreSQL e a API Cassandra, diferentemente dos bancos de dados de origem. Essa abordagem enfatiza a facilidade de interação com duas APIs diferentes (em duas portas diferentes) do mesmo cluster de banco de dados, em vez de usar clusters completamente independentes de dois bancos de dados diferentes.
Nas seções a seguir, conheceremos o laboratório de modelagem de dados para ilustrar as diferenças e alguns recursos comuns dos bancos de dados em questão.
Laboratório de Modelagem de DadosInstalação de banco de dadosDada a ênfase no design de um modelo de dados (em vez de arquiteturas de implantação complexas), instalaremos os bancos de dados nos contêineres do Docker no computador local e, em seguida, interagiremos com eles usando os respectivos shells da linha de comando.
Compatível com PostgreSQL e Cassandra, banco de dados YugaByte DBmkdir ~/yugabyte && cd ~/yugabyte wget https://downloads.yugabyte.com/yb-docker-ctl && chmod +x yb-docker-ctl docker pull yugabytedb/yugabyte ./yb-docker-ctl create
Mongodb docker run
Acesso à linha de comandoVamos nos conectar aos bancos de dados usando o shell da linha de comando para as APIs correspondentes.
PostgreSQLO psql é um shell de linha de comando para interagir com o PostgreSQL. Para facilitar o uso, o YugaByte DB vem com o psql diretamente na pasta bin.
docker exec -it yb-postgres-n1 /home/yugabyte/postgres/bin/psql -p 5433 -U postgres
Cassandracqlsh é um shell de linha de comando para interagir com o Cassandra e seus bancos de dados compatíveis via CQL (linguagem de consulta do Cassandra). Para facilitar o uso, o YugaByte DB vem com o
cqlsh
no
bin
.
Observe que o CQL foi inspirado no SQL e possui conceitos semelhantes às tabelas, linhas, colunas e índices. No entanto, como uma linguagem NoSQL, ela adiciona um certo conjunto de restrições, a maioria das quais também abordaremos em outros artigos.
docker exec -it yb-tserver-n1 /home/yugabyte/bin/cqlsh
MongodbO mongo é um shell de linha de comando para interagir com o MongoDB. Ele pode ser encontrado no diretório bin da instalação do MongoDB.
docker exec -it my-mongo bash cd bin mongo
Criação de tabelaAgora podemos interagir com o banco de dados para executar várias operações usando a linha de comando. Vamos começar criando uma tabela que armazena informações sobre músicas escritas por diferentes artistas. Essas músicas podem fazer parte de um álbum. Também atributos opcionais para a música - ano de lançamento, preço, gênero e classificação. Precisamos considerar atributos adicionais que possam ser necessários no futuro através do campo "tags". Ele pode armazenar dados semiestruturados como pares de valores-chave.
PostgreSQL CREATE TABLE Music ( Artist VARCHAR(20) NOT NULL, SongTitle VARCHAR(30) NOT NULL, AlbumTitle VARCHAR(25), Year INT, Price FLOAT, Genre VARCHAR(10), CriticRating FLOAT, Tags TEXT, PRIMARY KEY(Artist, SongTitle) );
CassandraCriar uma tabela no Cassandra é muito semelhante ao PostgreSQL.
Uma das principais diferenças é a falta de restrições de integridade (por exemplo, NOT NULL), mas essa é a responsabilidade do aplicativo, não do banco de dados NoSQL . A chave primária consiste em uma chave de seção (coluna Artista no exemplo abaixo) e um conjunto de colunas de cluster (coluna SongTitle no exemplo abaixo). A chave da partição determina em qual partição / shard colocar a linha e as colunas de cluster indicam como os dados devem ser organizados dentro do shard atual.
CREATE KEYSPACE myapp; USE myapp; CREATE TABLE Music ( Artist TEXT, SongTitle TEXT, AlbumTitle TEXT, Year INT, Price FLOAT, Genre TEXT, CriticRating FLOAT, Tags TEXT, PRIMARY KEY(Artist, SongTitle) );
MongodbO MongoDB organiza os dados em bancos de dados (Banco de Dados) (semelhante ao Keyspace no Cassandra), onde existem coleções (Coleções) (semelhantes às tabelas), que contêm documentos (Documentos) (semelhantes às linhas de uma tabela). O MongoDB basicamente não requer a definição do esquema original. O comando
"usar banco de dados" mostrado abaixo cria uma instância do banco de dados na primeira chamada e altera o contexto do banco de dados recém-criado. Mesmo as coleções não precisam ser criadas explicitamente, elas são criadas automaticamente, simplesmente quando você adiciona o primeiro documento a uma nova coleção. Observe que o MongoDB usa o banco de dados de teste por padrão; portanto, qualquer operação em nível de coleção sem especificar um banco de dados específico será executada nele por padrão.
use myNewDatabase;
Recuperando informações da tabela do PostgreSQL \d Music Table "public.music" Column | Type | Collation | Nullable | Default
Cassandra DESCRIBE TABLE MUSIC; CREATE TABLE myapp.music ( artist text, songtitle text, albumtitle text, year int, price float, genre text, tags text, PRIMARY KEY (artist, songtitle) ) WITH CLUSTERING ORDER BY (songtitle ASC) AND default_time_to_live = 0 AND transactions = {'enabled': 'false'};
Mongodb use myNewDatabase; show collections;
Publicando dados em uma tabela do PostgreSQL INSERT INTO Music (Artist, SongTitle, AlbumTitle, Year, Price, Genre, CriticRating, Tags) VALUES( 'No One You Know', 'Call Me Today', 'Somewhat Famous', 2015, 2.14, 'Country', 7.8, '{"Composers": ["Smith", "Jones", "Davis"],"LengthInSeconds": 214}' ); INSERT INTO Music (Artist, SongTitle, AlbumTitle, Price, Genre, CriticRating) VALUES( 'No One You Know', 'My Dog Spot', 'Hey Now', 1.98, 'Country', 8.4 ); INSERT INTO Music (Artist, SongTitle, AlbumTitle, Price, Genre) VALUES( 'The Acme Band', 'Look Out, World', 'The Buck Starts Here', 0.99, 'Rock' ); INSERT INTO Music (Artist, SongTitle, AlbumTitle, Price, Genre, Tags) VALUES( 'The Acme Band', 'Still In Love', 'The Buck Starts Here', 2.47, 'Rock', '{"radioStationsPlaying": ["KHCR", "KBQX", "WTNR", "WJJH"], "tourDates": { "Seattle": "20150625", "Cleveland": "20150630"}, "rotation": Heavy}' );
CassandraEm geral, a expressão
INSERT
no Cassandra é muito semelhante à do PostgreSQL. No entanto, há uma grande diferença na semântica. No Cassandra,
INSERT
na verdade uma operação
UPSERT
em que os últimos valores são adicionados à string, caso ela já exista.
A entrada de dados é semelhante ao PostgreSQL INSERT
acima
MongodbEmbora o MongoDB seja um banco de dados NoSQL, como o Cassandra, sua operação de inserção não tem nada a ver com o comportamento semântico no Cassandra. No MongoDB, o
insert () não possui recursos
UPSERT
, o que faz com que pareça com o PostgreSQL. Adicionar dados padrão sem
_idspecified
adicionará um novo documento à coleção.
db.music.insert( {
artist: "No One You Know",
songTitle: "Call Me Today",
albumTitle: "Somewhat Famous",
year: 2015,
price: 2.14,
genre: "Country",
tags: {
Composers: ["Smith", "Jones", "Davis"],
LengthInSeconds: 214
}
}
);
db.music.insert( {
artist: "No One You Know",
songTitle: "My Dog Spot",
albumTitle: "Hey Now",
price: 1.98,
genre: "Country",
criticRating: 8.4
}
);
db.music.insert( {
artist: "The Acme Band",
songTitle: "Look Out, World",
albumTitle:"The Buck Starts Here",
price: 0.99,
genre: "Rock"
}
);
db.music.insert( {
artist: "The Acme Band",
songTitle: "Still In Love",
albumTitle:"The Buck Starts Here",
price: 2.47,
genre: "Rock",
tags: {
radioStationsPlaying:["KHCR", "KBQX", "WTNR", "WJJH"],
tourDates: {
Seattle: "20150625",
Cleveland: "20150630"
},
rotation: "Heavy"
}
}
);
Consulta de tabelaTalvez a diferença mais significativa entre SQL e NoSQL em termos de design de consulta seja o uso das instruções
FROM
e
WHERE
. O SQL permite selecionar várias tabelas após uma
FROM
, e uma
WHERE
pode ser de qualquer complexidade (incluindo operações
JOIN
entre tabelas). No entanto, o NoSQL tende a impor uma restrição estrita a
FROM
e trabalha com apenas uma tabela especificada e, em
WHERE
, a chave primária sempre deve ser especificada. Isso se deve ao desejo de melhorar o desempenho do NoSQL, sobre o qual falamos anteriormente. Esse desejo leva a toda redução possível em qualquer interação entre tabelas e chaves. Isso pode levar a um grande atraso na comunicação intermodal ao responder a uma solicitação e, portanto, é melhor evitar isso em princípio. Por exemplo, o Cassandra exige que as consultas sejam limitadas a determinados operadores (somente
=, IN, <, >, =>, <=
são permitidas) nas chaves de partição, exceto quando solicitar um índice secundário (somente o operador = é permitido aqui).
PostgreSQLTrês exemplos de consultas que podem ser facilmente executadas por um banco de dados SQL serão apresentados abaixo.
- Imprima todas as músicas do artista;
- Imprima todas as músicas do artista que correspondem à primeira parte do nome;
- Liste todas as músicas do artista que possuem uma palavra específica no título e têm um preço menor que 1,00.
SELECT * FROM Music WHERE Artist='No One You Know'; SELECT * FROM Music WHERE Artist='No One You Know' AND SongTitle LIKE 'Call%'; SELECT * FROM Music WHERE Artist='No One You Know' AND SongTitle LIKE '%Today%' AND Price > 1.00;
CassandraDas consultas do PostgreSQL acima, apenas a primeira funcionará no Cassandra inalterada, pois a instrução
LIKE
não pode ser aplicada a agrupamentos de colunas como o
SongTitle
. Nesse caso, apenas operadores
=
e
IN
são permitidos.
SELECT * FROM Music WHERE Artist='No One You Know'; SELECT * FROM Music WHERE Artist='No One You Know' AND SongTitle IN ('Call Me Today', 'My Dog Spot') AND Price > 1.00;
MongodbComo mostrado nos exemplos anteriores, o método principal para criar consultas no MongoDB é
db.collection.find () . Este método contém explicitamente o nome da coleção (
music
no exemplo abaixo), portanto, a solicitação de várias coleções é proibida.
db.music.find( { artist: "No One You Know" } ); db.music.find( { artist: "No One You Know", songTitle: /Call/ } );
Leia todas as linhas da tabelaA leitura de todas as linhas é apenas um caso especial do modelo de consulta que examinamos anteriormente.
PostgreSQL SELECT * FROM Music;
CassandraSemelhante ao exemplo no PostgreSQL acima.
Mongodb
db.music.find( {} );
Editando dados em uma tabelaPostgreSQLO PostgreSQL fornece uma
UPDATE
para modificar os dados. Ele não possui recursos
UPSERT
; portanto, a execução desta instrução falhará se a linha não estiver mais no banco de dados.
UPDATE Music SET Genre = 'Disco' WHERE Artist = 'The Acme Band' AND SongTitle = 'Still In Love';
CassandraCassandra tem uma
UPDATE
semelhante ao PostgreSQL.
UPDATE
possui a mesma semântica
UPSERT
INSERT
.
Semelhante ao exemplo no PostgreSQL acima.
MongodbA operação
update () no MongoDB pode atualizar completamente um documento existente ou atualizar apenas determinados campos. Por padrão, ele atualiza apenas um documento com a semântica do
UPSERT
. A atualização de vários documentos e o comportamento semelhante ao
UPSERT
pode ser aplicada definindo sinalizadores adicionais para a operação. Por exemplo, no exemplo abaixo, o gênero de um determinado artista é atualizado por sua música.
db.music.update( {"artist": "The Acme Band"}, { $set: { "genre": "Disco" } }, {"multi": true, "upsert": true} );
Removendo dados de uma tabelaPostgreSQL DELETE FROM Music WHERE Artist = 'The Acme Band' AND SongTitle = 'Look Out, World';
CassandraSemelhante ao exemplo no PostgreSQL acima.
MongodbO MongoDB possui dois tipos de operações para excluir documentos -
deleteOne () / deleteMany () e
remove () . Ambos os tipos excluem documentos, mas retornam resultados diferentes.
db.music.deleteMany( { artist: "The Acme Band" } );
Excluir tabelaPostgreSQL DROP TABLE Music;
CassandraSemelhante ao exemplo no PostgreSQL acima.
Mongodb db.music.drop();
ConclusãoO debate sobre a escolha entre SQL e NoSQL está em andamento há mais de 10 anos. Existem dois aspectos principais desse debate: a arquitetura do mecanismo de banco de dados (SQL monolítico e transacional versus NoSQL não transacional e distribuído) e a abordagem do design do banco de dados (modelagem de dados no SQL versus modelagem de suas consultas no NoSQL).
Com um banco de dados transacional distribuído como o YugaByte DB, o debate sobre a arquitetura do banco de dados pode ser facilmente dissipado. À medida que os volumes de dados se tornam maiores do que o que pode ser gravado em um único nó, torna-se necessária uma arquitetura totalmente distribuída que suporta escalabilidade linear de gravações com fragmentação / reequilíbrio automático.
Além de ser dito em um artigo do
Google Cloud , as arquiteturas transacionais e estritamente consistentes agora são mais amplamente usadas para fornecer melhor flexibilidade de desenvolvimento do que as arquiteturas não transacionais e, em última análise, consistentes.
Voltando à discussão sobre design de banco de dados, é justo dizer que as duas abordagens de design (SQL e NoSQL) são necessárias para qualquer aplicativo real complexo. A abordagem SQL "modelagem de dados" permite que os desenvolvedores atendam mais facilmente os requisitos de negócios em mudança, enquanto a abordagem NoSQL "modelagem de dados" permite que os mesmos desenvolvedores tratem grandes quantidades de dados com baixa latência e alta taxa de transferência. É por esse motivo que o YugaByte DB fornece APIs SQL e NoSQL em um kernel comum, em vez de promover uma das abordagens. Além disso, ao garantir a compatibilidade com linguagens populares de banco de dados, incluindo PostgreSQL e Cassandra, o YugaByte DB garante que os desenvolvedores não precisem aprender outro idioma para trabalhar com um mecanismo de banco de dados estritamente consistente e distribuído.
Neste artigo, descobrimos como os fundamentos do design de banco de dados diferem no PostgreSQL, Cassandra e MongoDB. Nos artigos a seguir, abordaremos conceitos avançados de design, como índices, transações, JOINs, diretivas TTL e documentos JSON.
Desejamos a você uma estadia maravilhosa no restante do fim de semana e convidamos você para um
webinar gratuito , que será realizado no dia 14 de maio.