Resumo
Com a proliferação de bancos de dados JSON nos últimos anos, uma nova linguagem de consulta SQL++ começou a surgir para padronizar a forma de acessar essas fontes de dados. Na verdade, a linguagem já existe há alguns anos, mas tem existido principalmente no âmbito acadêmico. O Couchbase N1QL, uma linguagem SQL para dados JSON, foi lançado em 2015. A empresa continuou a desenvolver sua linguagem N1QL/SQL++ e, em outubro de 2018, lançou anunciado o lançamento do Couchbase Analytics. Don Chamberlinco-inventor do SQL original, também é autor de um Livro tutorial de SQL++ com exemplos práticos que funcionam com o Couchbase Analytics.
Visão geral
O SQL++ é uma linguagem de consulta de banco de dados projetada para trabalhar com dados estruturados e semiestruturados. A linguagem é baseada no SQL original com extensões para trabalhar com banco de dados de documentos JSON. Em bancos de dados relacionais, os dados são representados em forma de tabela. Cada uma das linhas de uma tabela tem a mesma estrutura de registro simples, com nomes e tipos de campo idênticos (de acordo com o esquema da tabela). Os bancos de dados semiestruturados relaxam essas restrições, permitindo que os registros sejam aninhados, tenham nomes e tipos de campos diferentes e não exijam um esquema. Dessa forma, o SQL++ "estende" o SQL, o padrão de linguagem de consulta usado no mundo relacional, relaxando suas restrições no modelo de dados. Ao fazer isso, o SQL++ mantém os benefícios do SQL, incluindo sua natureza declarativa de alto nível, ao mesmo tempo em que permite lidar com as estruturas mais flexíveis comumente encontradas no mundo semiestruturado. Fornecedores de bancos de dados relacionais como IBM, Microsoft e Oracle, bem como sistemas de código aberto como PostgreSQL e MySQL, estenderam suas próprias versões do SQL para trabalhar com dados JSON. Eles adicionam extensões (geralmente específicas do sistema) para JSON como um tipo de coluna, bem como novas funções e, em alguns casos, nova sintaxe, para permitir a manipulação de documentos JSON[1][2][3][4][5] O próprio padrão ANSI/ISO SQL foi ampliado de forma semelhante em 2016[6].
Por outro lado, conforme explicado acima, o SQL++ foi desenvolvido relaxando o modelo de dados de destino do SQL para chegar a uma linguagem de consulta em que os dados JSON são tratados como dados de "primeira classe" e em que os dados relacionais são um caso especial cujos registros são regulares, de tipo idêntico e não aninhados.[7]
Histórico
O SQL++ foi originalmente desenvolvido por Yannis Papakonstantinou e outros na Universidade da Califórnia, em San Diego[8]. O SQL++ também foi usado no projeto FORWARD, financiado pela NSF[9] na UCSD.
Aplicativos
Um dos primeiros a adotar o SQL++ foi Apache AsterixDBum sistema de gerenciamento de Big Data de código aberto, originalmente co-desenvolvido por uma equipe de professores, funcionários e alunos da UC Irvine e UC Riverside em 2009. Outro dos primeiros a adotar o SQL++ é a Couchbase, Inc., um fornecedor de banco de dados JSON dimensionável cuja versão 6.0 adotou o SQL++ para o Couchbase Analytics [8] oferta.
Livros
Donald D Chamberlinum dos principais projetistas da especificação original da linguagem SQL, criou um tutorial para a linguagem SQL++[11] que inclui exemplos práticos para mostrar como a linguagem funciona com o Couchbase Analytics.
Exemplos
SELECIONAR E SELECIONAR VALOR
Uma das principais diferenças entre o SQL e o SQL++ está no formato do resultado. O SQL padrão, projetado para linha e tabela, retorna o conjunto de resultados em um formato de tabela. O SQL++, por outro lado, retorna o conjunto de resultados no formato JSON.
(Q1) Liste a identificação do cliente, o nome, o CEP e a classificação de crédito de todos os clientes, em ordem por identificação do cliente.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
SELECIONAR custid, nome, endereço.código postal, classificação DE clientes ORDEM BY custid LIMITE 2; Resultado: [ { "custid" : "C13", "Nome" : "T. Cruise", "CEP" : "63101", "Classificação" : 750 }, { "custid" : "C25", "Nome" : "M. Streep", "CEP" : "02340", "Classificação" : 690 } ] |
(Q2) Encontre os nomes dos clientes com uma classificação maior que 650.
|
1 2 3 4 5 6 7 8 |
SELECIONAR nome DE clientes ONDE classificação > 650; Resultado: [ { "name" (nome): "T. Cruise" }, { "name" (nome): "M. Streep" }, { "name" (nome): "T. Hanks" } ] |
(Q3) Mostra os efeitos de SELECT VALUE (compare com Q2).
|
1 2 3 4 |
SELECIONAR VALOR nome DE clientes Consultas ONDE classificação > 650; Resultado: [ "T. Cruise", "M. Streep", "T. Hanks" ] |
Uma consulta SELECT VALUE pode ser usada com um construtor de objetos para criar rótulos ou para dar alguma estrutura a um resultado de consulta, como no exemplo a seguir.
(Q4) Liste os clientes com classificação de crédito superior a 650, em ordem decrescente de classificação de crédito, e novamente em ordem crescente por CEP.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
SELECIONAR VALOR { "Clientes de alta classificação, ordenados por classificação": (SELECIONAR c.classificação, c.custid, c.nome DE clientes AS c ONDE c.classificação > 650 ORDEM BY c.classificação DESC), "clientes de alto nível, ordenados por código postal": (SELECIONAR c.endereço.código postal, c.custid, c.nome DE clientes AS c ONDE c.classificação > 650 ORDEM BY c.endereço.código postal) }; Resultado: [ { "Clientes de alta classificação, ordenados por classificação": [ { "classificação": 750, "custid": "C13", "name" (nome): "T. Cruise" }, { "classificação": 750, "custid": "C37", "name" (nome): "T. Hanks" }, { "classificação": 690, "custid": "C25", "name" (nome): "M. Streep" } ], "clientes de alto nível, ordenados por código postal": [ { "zipcode" (código postal): "02115", "custid": "C37", "name" (nome): "T. Hanks" }, { "zipcode" (código postal): "02340", "custid": "C25", "name" (nome): "M. Streep" }, { "zipcode" (código postal): "63101", "custid": "C13", "name" (nome): "T. Cruise" } ] } ] |
GROUPING, AGGREGATION e UNNEST
O SQL++ suporta o mesmo conceito SQL de agrupamento e agregação. O UNNEST pega o conteúdo de arrays aninhados, ou seja, pedidos, e os une ao seu objeto pai, ou seja, clientes.
(Q6) Liste o primeiro pedido por número de pedido e número de item, juntamente com a quantidade total de todos os pedidos feitos em 2017-05-01.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
SELECIONAR o.ordem, i.itemno AS número_do_item, soma(i.quantidade) AS quantidade DE pedidos AS o INÚTIL o.itens AS i ONDE o.data_do_pedido = "2017-05-01" GRUPO BY o.ordem, i.itemno ORDEM BY o.ordem, número_do_item LIMITE 1; Resultado: [ { "orderno": 1002, "item_number": 460, "quantidade": 95 } ] |
GRUPO COMO
Uma consulta pode gerar dados de saída em nível de resumo. A definição do nível é fornecida na cláusula GROUP BY. A consulta Q6 gera um resumo de pedidos no nível do número do pedido e do número do item do pedido. Muitas vezes, você desejará gerar uma saída que inclua dados de resumo e itens de linha nos resumos. Para essa finalidade, o SQL++ oferece suporte a várias extensões importantes dos recursos de agrupamento tradicionais do SQL. As cláusulas GROUP BY e HAVING, já conhecidas, ainda estão presentes e são unidas por uma nova cláusula chamada GROUP AS.
(Q7) Liste todos os pedidos por número de pedido e número de item, juntamente com a quantidade total de todos os pedidos feitos em 01/05/2017, incluindo também todos os pedidos e itens de pedido feitos para cada linha de resumo. (Compare com a Q6)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
SELECIONAR o.ordem, i.itemno AS número_do_item, soma(i.quantidade) AS quantidade, od DE pedidos AS o INÚTIL o.itens AS i ONDE o.data_do_pedido = "2017-05-01" GRUPO BY o.ordem, i.itemno GRUPO AS od LIMITE 1; Resultado: [ { "od": [ { "o": { "custid": "C13", "itens": [ { "itemno": 460, "price" (preço): 100.99, "qty": 95 }, { "itemno": 680, "price" (preço): 8.75, "qty": 150 } ], "order_date" (data do pedido): "2017-05-01", "orderno": 1002, "ship_date": "2017-05-03" }, "i": { "itemno": 460, "price" (preço): 100.99, "qty": 95 } } ], "orderno": 1002, "item_number": 460, "quantidade": 95 } ] |