Resumen
Con la proliferación de las bases de datos JSON en los últimos años, un nuevo lenguaje de consulta SQL que podría normalizar la forma de acceder a estas fuentes de datos. De hecho, el lenguaje existe desde hace varios años, pero ha existido sobre todo en el ámbito académico. Couchbase N1QL, un lenguaje SQL para datos JSON, se lanzó en 2015. La compañía ha seguido desarrollando su lenguaje N1QL/SQL++ y en octubre de 2018 anunciado el lanzamiento de Couchbase Analytics. Don Chamberlinco-inventor del SQL original, también es autor de un Libro tutorial de SQL con ejemplos prácticos que funcionan con Couchbase Analytics.
Visión general
SQL++ es un lenguaje de consulta de bases de datos diseñado para trabajar con datos estructurados y semiestructurados. El lenguaje se basa en el SQL original con extensiones para que funcione con bases de datos de documentos JSON. En las bases de datos relacionales, los datos se representan en forma de tabla. Cada una de las filas de una tabla tiene la misma estructura plana de registro, con idénticos nombres y tipos de campo (según el esquema de la tabla). Las bases de datos semiestructuradas relajan estas restricciones y permiten anidar registros, con nombres y tipos de campo diferentes, sin necesidad de esquema. En consecuencia, SQL++ "amplía" SQL, el lenguaje de consulta estándar utilizado en el mundo relacional, relajando sus restricciones sobre el modelo de datos. De este modo, SQL++ conserva las ventajas de SQL, incluida su naturaleza declarativa de alto nivel, al tiempo que le permite manejar las estructuras más flexibles que suelen encontrarse en el mundo semiestructurado. Los proveedores de bases de datos relacionales como IBM, Microsoft y Oracle, así como sistemas de código abierto como PostgreSQL y MySQL, han ampliado sus propias versiones de SQL para trabajar con datos JSON. Añaden extensiones (a menudo específicas del sistema) para JSON como tipo de columna, así como nuevas funciones y, en algunos casos, una nueva sintaxis, para permitir la manipulación de documentos JSON.[1][2][3][4][5] La propia norma ANSI/ISO SQL se amplió de forma similar en 2016[6].
En cambio, como ya se ha explicado, SQL++ se desarrolló relajando el modelo de datos objetivo de SQL para llegar a un lenguaje de consulta en el que los datos JSON se tratan como datos de "primera clase" y en el que los datos relacionales son un caso especial cuyos registros son regulares, de idéntico tipo y no anidados.[7]
Historia
SQL++ fue desarrollado originalmente por Yannis Papakonstantinou y otros en la Universidad de California en San Diego.[8]. SQL++ también se utilizó en el proyecto FORWARD, financiado por la NSF[9] en la UCSD.
Aplicaciones
Uno de los primeros en adoptar SQL++ fue Apache AsterixDBun sistema de gestión de Big Data de código abierto, desarrollado originalmente por un equipo de profesores, empleados y estudiantes de la UC Irvine y la UC Riverside en 2009. Otro de los primeros en adoptar SQL++ es Couchbase, Inc, un proveedor de bases de datos JSON escalables cuya versión 6.0 ha adoptado SQL++ para su Couchbase Analytics. [8] ofreciendo.
Libros
Donald D Chamberlinuno de los principales diseñadores de la especificación original del lenguaje SQL, es autor de un tutorial sobre el lenguaje SQL[11] que incluye ejemplos prácticos para mostrar cómo funciona el lenguaje con Couchbase Analytics.
Ejemplos
SELECCIONAR & SELECCIONAR VALOR
Una de las principales diferencias entre SQL y SQL++ radica en el formato del resultado. SQL estándar, diseñado para filas y tablas, devuelve el conjunto de resultados en formato de tabla. SQL++, en cambio, devuelve el conjunto de resultados en formato JSON.
(P1) Enumere el identificador de cliente, el nombre, el código postal y la calificación crediticia de todos los clientes, ordenados por identificador de cliente.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
SELECCIONE custid, nombre, dirección.código postal, valoración DESDE clientes PEDIR POR custid LÍMITE 2; Resultado: [ { "custid" : "C13", "Nombre" : "T. Cruise", "Código postal : "63101", "Clasificación" : 750 }, { "custid" : "C25", "Nombre" : "M. Streep", "Código postal : "02340", "Clasificación" : 690 } ] |
(P2) Encuentra los nombres de los clientes con una valoración superior a 650.
1 2 3 4 5 6 7 8 |
SELECCIONE nombre DESDE clientes DONDE valoración > 650; Resultado: [ { "nombre": "T. Cruise" }, { "nombre": "M. Streep" }, { "nombre": "T. Hanks" } ] |
(Q3) Muestra los efectos de SELECCIONAR VALOR (comparar con Q2).
1 2 3 4 |
SELECCIONE VALOR nombre DESDE clientes Consultas DONDE valoración > 650; Resultado: [ "T. Cruise", "M. Streep", "T. Hanks" ] |
Una consulta SELECT VALUE puede utilizarse con un constructor de objetos para crear etiquetas o para dar alguna estructura al resultado de una consulta, como en el siguiente ejemplo.
(P4) Enumerar los clientes con calificación crediticia superior a 650, en orden descendente por calificación crediticia, y de nuevo en orden ascendente por código postal.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
SELECCIONE VALOR { "clientes más votados, ordenados por puntuación": (SELECCIONE c.valoración, c.custid, c.nombre DESDE clientes AS c DONDE c.valoración > 650 PEDIR POR c.valoración DESC), "clientes más votados, ordenados por código postal": (SELECCIONE c.dirección.código postal, c.custid, c.nombre DESDE clientes AS c DONDE c.valoración > 650 PEDIR POR c.dirección.código postal) }; Resultado: [ { "clientes más votados, ordenados por puntuación": [ { "rating": 750, "custid": "C13", "nombre": "T. Cruise" }, { "rating": 750, "custid": "C37", "nombre": "T. Hanks" }, { "rating": 690, "custid": "C25", "nombre": "M. Streep" } ], "clientes más votados, ordenados por código postal": [ { "código postal": "02115", "custid": "C37", "nombre": "T. Hanks" }, { "código postal": "02340", "custid": "C25", "nombre": "M. Streep" }, { "código postal": "63101", "custid": "C13", "nombre": "T. Cruise" } ] } ] |
AGRUPACIÓN, AGREGACIÓN y UNNEST
SQL++ soporta el mismo concepto SQL de agrupación y agregación. El UNNEST toma el contenido de matrices anidadas, es decir, pedidos y los une con su objeto padre, es decir, clientes.
(P6) Enumere el primer pedido por número de pedido y número de artículo, junto con la cantidad total de todos los pedidos realizados el día 2017-05-01.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
SELECCIONE o.número de pedido, i.itemno AS número_artículo, suma(i.Cantidad) AS cantidad DESDE pedidos AS o UNNEST o.artículos AS i DONDE o.fecha_pedido = "2017-05-01" GRUPO POR o.número de pedido, i.itemno PEDIR POR o.número de pedido, número_artículo LÍMITE 1; Resultado: [ { "orderno": 1002, "número_artículo": 460, "cantidad": 95 } ] |
GRUPO AS
Una consulta puede generar datos de salida a nivel de resumen. La definición del nivel se proporciona en la cláusula GROUP BY. La consulta Q6 genera un resumen de pedidos a nivel de número de pedido y número de posición de pedido. A menudo querrá generar una salida que incluya tanto datos de resumen como partidas dentro de los resúmenes. Para ello, SQL++ admite varias extensiones importantes de las funciones de agrupación tradicionales de SQL. Las conocidas cláusulas GROUP BY y HAVING siguen existiendo, y a ellas se une una nueva cláusula denominada GROUP AS.
(P7) Enumere todos los pedidos por número de pedido y número de artículo, junto con la cantidad total para todos los pedidos realizados en 2017-05-01, incluya también todos los pedidos y artículos de pedido que realizó para cada línea de resumen. (Comparar con P6)
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 |
SELECCIONE o.número de pedido, i.itemno AS número_artículo, suma(i.Cantidad) AS cantidad, od DESDE pedidos AS o UNNEST o.artículos AS i DONDE o.fecha_pedido = "2017-05-01" GRUPO POR o.número de pedido, i.itemno GRUPO AS od LÍMITE 1; Resultado: [ { "od": [ { "o": { "custid": "C13", "artículos": [ { "itemno": 460, "precio": 100.99, "cantidad": 95 }, { "itemno": 680, "precio": 8.75, "cantidad": 150 } ], "fecha_pedido": "2017-05-01", "orderno": 1002, "fecha_envío": "2017-05-03" }, "i": { "itemno": 460, "precio": 100.99, "cantidad": 95 } } ], "orderno": 1002, "número_artículo": 460, "cantidad": 95 } ] |