Os aplicativos de negócios têm requisitos: receber pedidos de clientes, entregar pedidos de clientes, rastrear remessas, gerar relatórios de inventário, relatórios comerciais de fim de dia/mês/trimestre, gerar painéis de negócios e muito mais. Esses requisitos evoluem lentamente. Eles permanecem mesmo quando você escolhe um Banco de dados NoSQL.
Nos bancos de dados NoSQL, os desafios são enfrentados por uma série de tecnologias e soluções alternativas. Aqui estão algumas delas:
- Copiar os dados com uma chave diferente para facilitar as digitalizações.
- Obter todos os dados necessários para o aplicativo e, em seguida, gerar relatórios
- Carregar os dados em bancos de dados relacionais para gerar o relatório.
- Os produtos oferecem soluções alternativas com visualizações de redução de mapas, APIsetc.
- Por fim, o próprio SQL foi injustificadamente eficaz para dados estruturados e semiestruturados. Os bancos de dados NoSQL, como Couchbase, Cassandra, CosmosDB estenderam o SQL para JSON e modelo de dados de coluna ampla.
O NoSQL evoluiu de "NO SQL" para Not Only SQL. Se você estiver interessado em alguns dos antecedentes evolutivos combinados com um histórico da evolução do SQL para dar suporte a dados semiestruturados, sugiro as seguintes entrevistas.
- Entrevista de Ravi Mayuram com Don Chamberlin [2017]: https://youtu.be/-U_UjqnhMBI?t=3492
- Um painel de discussão entre Ravi Mayuram, Don Chamberlin e o Prof. Mike Carey [2018]: https://www.youtube.com/watch?v=LAlDe1w7wxc
Muitos bancos de dados NoSQL alegam ter "suporte a SQL". O Padrão SQL é amplo e profundo, coberto de nove livros volumosos. Ninguém, nem Oráculo nem SQL ServerO NoSQL, apesar de décadas de trabalho, suporta tudo o que está no padrão. Portanto, os bancos de dados NoSQL têm um longo caminho a percorrer para se atualizarem. Portanto, vale a pena fazer uma avaliação detalhada do suporte a SQL.
Aqui estão os critérios que você deve usar para avaliar o suporte a SQL em bancos de dados NoSQL.
- Suporte à linguagem: Quais declarações, tipos de dados, operações (junções, agrupamento, agregação, janelas, paginação, etc.)
- Suporte à indexação: Os índices são essenciais para o desempenho, especialmente nas cargas de trabalho de aplicativos interativos.
- Otimizador: A reescrita de consultas, a escolha do caminho de acesso correto e a criação do caminho ideal de execução de consultas é o que torna o SQL uma 4GL bem-sucedida. Alguns têm um otimizador baseado em regras, outros têm um otimizador baseado em custos e outros têm ambos. É fundamental avaliar a qualidade do otimizador. Os benchmarks típicos (TPC-C, TPC-DS, YCSB, YCSB-JSON) não o ajudarão aqui.
- Como diz o ditado: "Há três coisas importantes nos bancos de dados: desempenho, desempenho e desempenho". É importante medir o desempenho de sua carga de trabalho. YCSB e a extensão YCSB-JSON facilitará essa avaliação.
- SDKs: SDKs avançados e suporte a idiomas aceleram seu desenvolvimento.
- Suporte de ferramentas de BI: Para a análise de grandes volumes de dados, é importante o suporte das ferramentas de BI, geralmente por meio de drivers de conectividade de banco de dados padrão.
Neste artigo, vou comparar e contrastar o suporte à linguagem SQL no Cassandra, CosmosDB, Couchbase e MongoDB por meio de suas respectivas implementações. Com certeza, o MongoDB não oferece suporte a SQL, mas tem alguns comandos comparativos.
Dividi a análise em várias seções. A formatação do WordPress torna essas tabelas muito grandes. Aqui está uma versão em PDF que é compacta e fácil de ler. [Clique na imagem para visualizar o PDF].
Abordagem de suporte ao SQL:
SQL | O SQL é uma linguagem declarativa, com as operações select-join-project servindo como base. |
Cassandra | CQL: Linguagem inspirada em SQL para o Cassandra. |
CosmosDB | Oferece suporte a SQL juntamente com a API do MongoDB, Gremlin (para o gráfico), etc. Suporte simples a select-from-where-order-by. |
Couchbase | N1QL: SQL para JSON.
O Couchbase tem duas implementações do N1QL: serviço de consulta e serviço de análise. |
MongoDB | Consulta baseada em comandos SQL simplificada e baseada em Javascript. |
ENTRADA e SAÍDA
SQL | INPUT: Conjunto de linhas (tuplas)
SAÍDA: Um conjunto de linhas (tuplas) |
Cassandra | ENTRADA: Conjuntos de linhas
SAÍDA: Conjunto de linhas |
CosmosDB | INPUT: Conjuntos de JSON
SAÍDA: Conjunto de JSON |
Couchbase | INPUT: Conjuntos de JSON
SAÍDA: Conjunto de JSON |
MongoDB | INPUT: Conjuntos de JSON
SAÍDA: Conjunto de JSON |
SELECT: FROM Clause
SQL | Especifica as tabelas de fontes de dados (relações) |
Cassandra | cláusula FROM com apenas uma tabela permitida. Agora são permitidas junções, subconsultas ou expressões. A interpretação da cláusula From é igual à do SQL. |
CosmosDB | A cláusula FROM oferece suporte a uma única coleção e a uniões próprias (o mesmo que UNNEST no Couchbase). |
Couchbase | Cláusula FROM com vários espaços-chave (subconjunto de bucket), subconsultas, expressões. Igual ao SQL |
MongoDB | db.t1.find() para uma única tabela SELECT.
db.t1.aggregate() é usado como a estrutura de consulta generalizada. aggregate() pode se unir a coleções adicionais usando o operador $lookup. Pode haver vários operadores $lookup na estrutura do pipeline de agregação, o que o torna o primo mais próximo da cláusula SQL FROM. |
SELECT: Cláusula WHERE
SQL | Critérios para selecionar uma linha |
Cassandra | Expressões booleanas padrão. Sem subconsultas. |
CosmosDB | Igual ao SQL |
Couchbase | Expressões e subconsultas booleanas padrão. |
MongoDB | db.t1.find({x:10});
aggregate() tem a cláusula $match. |
SELECT: Cláusula SELECT
SQL | Cláusula de projeção |
Cassandra | A cláusula SELECT é igual à do SQL. |
CosmosDB | A cláusula SELECT é igual à do SQL. |
Couchbase | A cláusula SELECT é igual à do SQL. |
MongoDB | db.t1.find({x:10}, {a:1, b:1})
Operador do projeto $ no pipeline de agregação |
SELECT: CTE - Expressão de tabela comum
SQL | Fonte de dados definida dinamicamente (tabela, conjunto de resultados) |
Cassandra | Sem suporte |
CosmosDB | Sem suporte |
Couchbase | WITH; igual ao SQL (na versão 6.5). Não há suporte para CTE recursivo |
MongoDB | Sem suporte |
SELECT: Subquery
SQL | Subquery: Subconsultas na cláusula FROM, na cláusula WHERE e em qualquer lugar em que uma expressão seja permitida. |
Cassandra | Sem suporte |
Cosmosdb | Sem suporte |
Couchbase | Oferece suporte a subconsultas correlacionadas e não correlacionadas. |
MongoDB | Sem suporte em find(). Pode adicionar $match no pipeline, mas não é exatamente um equivalente de uma subconsulta. |
SELECT: GROUP BY
SQL | Agrupa as linhas com base em uma ou mais expressões. Bastante útil em relatórios e agregação de grupos. |
Cassandra | Suportado; igual ao SQL. |
Cosmosdb | Sem suporte. Só é possível fazer a agregação em todo o conjunto de resultados. |
Couchbase | Suportado; semelhante ao SQL. |
MongoDB | Operador $group no pipeline aggregate() |
SELECT: cláusula HAVING
SQL | Filtragem após a agregação. |
Cassandra | Sem suporte |
CosmosDB | Sem suporte |
Couchbase | Cláusula HAVING; igual ao SQL |
MongoDB | $match após o agrupamento e a agregação. |
SELECT: Cláusula ORDER BY
SQL | A ordem final dos resultados produzidos pelo bloco de consulta |
Cassandra | Cláusula ORDER BY; igual ao SQL. |
Cosmosdb | Cláusula ORDER BY; igual ao SQL. |
Couchbase | Cláusula ORDER BY; igual ao SQL. |
MongoDB | db.t1.find().sort({a:1, b:-1});
aggregate() tem $sort para especificar a ordem do resultado. |
SELECT: Cláusula LIMIT, OFFSET
SQL | Usado para paginação do conjunto de resultados |
Cassandra | "LIMIT é compatível.
OFFSET não é compatível." |
CosmosDB | Cláusula LIMIT (TOP) e OFFSET; semelhante ao SQL |
Couchbase | Cláusula LIMIT e OFFSET; igual ao SQL |
MongoDB | métodos skip(), limit() com find(). $offset, $limit com aggregate(). |
SELECT: Cláusula JOIN
SQL | INNER JOIN, junções externas LEFT/RIGHT/FULL. |
Cassandra | Não há suporte para uniões. Os aplicativos terão que modelar os dados para evitar junções ou fazer as junções na camada do aplicativo. |
Cosmosdb | Somente self JOINs. Não há junções INNER/LEFT/RIGHT/etc. |
Couchbase | Oferece suporte a INNER, LEFT OUTER, NEST, UNNEST e RIGHT outer limitado. A mesma sintaxe do SQL. Não há suporte para junção FULL OUTER. |
MongoDB | LEFT OUTER JOIN limitado somente por meio do operador $lookup. Não há junção em elementos de matriz ou expressões. |
SELECT: Agregação
SQL | Agregação |
Cassandra | Há suporte para a agregação simples em todo o resultado. A agregação com GROUP BY não é compatível. |
CosmosDB | Há suporte para a agregação simples em todo o resultado. A agregação com GROUP BY não é compatível. |
Couchbase | SUM, AVG, COUNT, MAX, MIN, VARIANCE: igual ao SQL |
MongoDB | $sum, $count, $avg com suporte a agrupamento |
SELECT: funções agregadas
SQL | Há suporte para a agregação simples em todo o resultado. A agregação com GROUP BY não é compatível. |
Cassandra | Sem suporte |
Cosmosdb | Sem suporte |
Couchbase | Oferece suporte às funções analíticas da janela SQL Standard na versão 6.5. |
MongoDB | Sem suporte |
SELECT : Funções de janela (analíticas/agregação)
SQL | Funções de janela para executar totais usando a cláusula OVER() |
Cassandra | Sem suporte |
CosmosDB | Sem suporte |
Couchbase | Oferece suporte às funções analíticas da janela SQL Standard na versão 6.5.
Ver detalhes: https://www.couchbase.com/blog/json-to-insights-fast-and-easy/ https://www.couchbase.com/blog/get-a-bigger-picture-with-n1ql-window-functions-and-cte/ |
MongoDB | Sem suporte |
INSERT: inserção de uma única linha/documento.
SQL | Inserir uma única linha |
Cassandra | Declaração INSERT |
CosmosDB | Inserção de API |
Couchbase | Declaração INSERT |
MongoDB | db.t1.save() |
INSERT: inserção de várias linhas/documentos.
SQL | Declaração INSERT |
Cassandra | Sem suporte |
Cosmosdb | Sem suporte |
Couchbase | INSERT com vários documentos |
MongoDB | db.t1.insert() |
Declaração DELETE
SQL | Excluir um ou mais documentos |
Cassandra | Declaração DELETE; igual ao SQL |
Cosmosdb | Exclusão da API |
Couchbase | Declaração DELETE; igual ao SQL |
MongoDB | db.t1.delete() |
Declaração UPSERT
SQL | INSERIR. UPDATE se existir. |
Cassandra | Sem suporte |
Cosmosdb | Sem suporte |
Couchbase | Declaração UPSERT. |
MongoDB | Sem suporte |
Declaração de atualização
SQL | |
Cassandra | UPDATE; o mesmo que SQL |
CosmosDB | Atualização da API |
Couchbase | UPDATE; o mesmo que SQL |
MongoDB | db.t1.update() |
MERGE: mescla uma relação (conjunto de linhas) com outra.
SQL | Mesclar um conjunto de linhas (documentos) em outro. |
Cassandra | Sem suporte |
CosmosDB | Sem suporte |
Couchbase | Declaração MERGE, igual ao SQL. |
MongoDB | Sem suporte |
Declaração PREPARE
SQL | Analisar, analisar e criar um plano de execução. |
Cassandra | Com suporte. Vejo exemplos de preparedStatement() no Java SDK.dd |
CosmosDB | Sem suporte |
Couchbase | Apoiado; PREPARAR |
MongoDB | Sem suporte |
EXECUTAR
SQL | Executar uma declaração ad-hoc ou preparada. |
Cassandra | Suportado em Java. |
Cosmosdb | Sem suporte |
Couchbase | Suportado, semelhante ao SQL. |
MongoDB | Sem suporte |
CONCESSÃO/REVOGAÇÃO
SQL | Conceder/REVOGAR permissões para operações específicas no conjunto de dados |
Cassandra | CONCESSÃO, REVOGAÇÃO |
CosmosDB | Suporte à API |
Couchbase | CONCEDER FUNÇÃO, REVOGAR FUNÇÃO |
MongoDB | TBD?? |
Declaração DESCRIBE
SQL | Descreve o esquema de uma tabela |
Cassandra | DESCREVER |
Cosmosdb | Sem suporte |
Couchbase | O INFER descreve o esquema dos documentos |
MongoDB | Ferramenta de bússola - somente gráfica. |
Declaração TRUNCATE
SQL | Trunca os dados da tabela sem alterar a segurança ou o esquema físico. |
Cassandra | TRUNCAR |
CosmosDB | Sem suporte |
Couchbase | Operação FLUSH |
MongoDB | Sem suporte. Solução alternativa: remover a coleção e recriá-la com as mesmas configurações de segurança. |
Lógica de valores (valores booleanos)
SQL | True, False, NULL (Desconhecido) |
Cassandra | True, False, NULL (Desconhecido) |
Cosmosdb | True, False, NULL (Desconhecido) |
Couchbase | True (Verdadeiro), False (Falso), NULL (Desconhecido), Missing (Ausente)
https://docs.couchbase.com/server/4.0/n1ql/n1ql-language-reference/booleanlogic.html |
MongoDB | True, False, NULL (Desconhecido) |
Otimizador de consultas: Tipo de otimizador
SQL | Otimizador baseado em regras e em custos. Faz reescrita de consultas, seleção de índices, ordenação de junções, seleção de tipos de junções e posição dos tabuladores (interno/externo, construção/probe de tabelas de hash) |
Cassandra | Otimizador baseado em regras. A seleção de índices para a tabela única é feita, pois não há junções. |
CosmosDB | O otimizador baseado em regras faz principalmente a seleção de índices. |
Couchbase | Otimizador baseado em regras, seleção de índice(s). Bloqueia a junção de loop aninhado por padrão, mas oferece suporte à junção de hash por meio de dica do usuário na consulta. |
MongoDB | Otimizador "baseado em forma" de acordo com a documentação. Cada nova consulta é combinada com uma consulta baseada na "forma". Na primeira vez que uma consulta é executada, o otimizador faz a seleção do índice, mas quando há vários candidatos, ele executa várias consultas simultaneamente para ver quem retorna os resultados primeiro. |
Otimizador de consultas: Seleção de índice
SQL | Sim |
Cassandra | Sim |
CosmosDB | Sim |
Couchbase | Sim |
MongoDB | Sim |
Otimizador de consultas: Reescrita de consultas
SQL | Reescrever partes da consulta em um equivalente lógico para melhorar o desempenho. Por exemplo, reescrita de subconsulta, dobramento de visualização, conversão de tipo de junção, avaliação de expressão constante etc. |
Cassandra | Nenhum |
Cosmosdb | Nenhuma reescrita conhecida |
Couchbase | Reescrita de consulta básica. LEFT OUTER para INNER quando aplicável, avaliação de expressões constantes. |
MongoDB | Nenhum |
Otimização de consultas: Tipo JOIN
SQL | Escolha o índice mais eficiente, dentre os tipos de união disponíveis. |
Cassandra | Não aplicável, pois não há suporte para uniões. |
CosmosDB | Não está claramente documentado. |
Couchbase | Loop aninhado por padrão. Junção de hash por dica de usuário. |
MongoDB | Apenas o loop aninhado é suportado. |
Suporte à TRANSAÇÃO.
SQL | Suporte ACID com suporte a várias linhas e várias declarações. |
Cassandra | Não |
Cosmosdb | Sim |
Couchbase | Não |
MongoDB | Sim, na versão 4.0 |
Índices
SQL | Estruturas de dados mantidas para acelerar o desempenho da consulta. Os índices são |
Cassandra | Oferece suporte a índices primários, secundários e de matriz. É necessário instalar e indexar os dados no SOLR para um índice de pesquisa. |
CosmosDB | Indexa tudo por padrão: escalares, matrizes. Não há suporte para o índice de pesquisa. |
Couchbase | Oferece suporte a índices primários, secundários, compostos, funcionais, adaptativos, de pesquisa, espaciais, particionados e de réplica. Os índices são eventualmente consistentes. |
MongoDB | Oferece suporte a índices primário, secundário, composto, de pesquisa, espacial, particionado e de réplica. O índice de pesquisa é criado de forma simplista em uma árvore B. |
SQL: Suporte a tipos de dados.
SQL | Amplo suporte a tipos de dados numéricos, de caracteres e de data e hora. |
Cassandra | Numérico, decimal, duplo. Int, float, varint, Timestamp, coleção (set, list) |
CosmosDB | Tipos de dados JSON: numérico, string, booleano, objeto, matrizes |
Couchbase | Tipos de dados JSON: numérico, string, booleano, objeto, matrizes |
MongoDB | Tipos de dados JSON: numérico, cadeia de caracteres, booleano, objeto, matrizes e extensões personalizadas para o tipo de dados de carimbo de data/hora. |
Conclusão:
Os bancos de dados NoSQL populares tentaram estender e dar suporte ao SQL declarativo para os respectivos modelos e arquiteturas de dados. Portanto, é importante entender os recursos, as limitações dos recursos e a arquitetura durante a avaliação.
Referências:
[...] transações e sua semântica. O SQL como linguagem de consulta tem sido excessivamente eficaz mesmo em sistemas de banco de dados NoSQL. No entanto, poucos sistemas de banco de dados NoSQL suportam transações. Os que suportam vêm com uma longa [...]