La matriz es LA diferencia entre el modelo relacional y el modelo JSON. - Gerald Sangudi

Resumen

JSON array te da flexibilidad en el tipo de elementos, número de elementos, tamaño de los elementos, y la profundidad de los elementos. Esto se suma a la flexibilidad de las bases de datos operacionales JSON como Couchbase y MongoDB. El rendimiento de las consultas con un predicado de matriz en bases de datos operativas depende de los índices de matriz. Sin embargo, los índices de matrices en estas bases de datos vienen con importantes limitaciones. Por ejemplo, sólo se permite una clave de matriz por índice. Los índices de arrays, incluso cuando se crean, sólo pueden procesar predicados AND eficientemente. La próxima versión de Couchbase 6.6 elimina estas limitaciones de JSON usando un índice invertido integrado para indexar y consultar arrays en N1QL. Este artículo explica los antecedentes y el funcionamiento de esta novedosa implementación.

Introducción

Un array es un tipo básico integrado en JSON definido como En matriz es una colección ordenada de valores. Un array empieza por [soporte izquierdo y termina con ]soporte derecho. Los valores están separados por ,comaUna matriz le ofrece flexibilidad porque puede contener un número arbitrario de valores escalares, vectoriales y de objeto. Un perfil de usuario puede tener un array de aficiones, un perfil de cliente un array de coches, un perfil de miembro un array de amigos. Couchbase N1QL proporciona un rico conjunto de operadores para manipular matrices; MongoDB tiene una lista de operadores para manejar matrices también.

Antes de empezar a consultar, necesitas modelar tus datos en arrays. Todas las bases de datos de documentos JSON como Couchbase, MongoDB te recomiendan desnormalizar tu modelo de datos para mejorar tu rendimiento y appdev. Lo que eso significa es, transformar tu relación 1:N en un único documento incrustando el N en 1. En JSON, harías eso usando un array. En el ejemplo de abajo, el documento(1) contiene 8 (N) gustos. En lugar de almacenar una referencia de clave externa a otra tabla, en JSON, almacenamos los datos en línea. 

Los valores aquí son matrices de cadenas. En JSON, cada elemento puede ser de cualquier tipo JSON válido: escalares (numéricos, cadenas, etc.) u objetos o vectores (matrices). Cada documento de hotel contiene una matriz de reseñas. Este es el proceso de desnormalización. Conversión de múltiples relaciones 1:N en un único objeto hotel que contiene N public_likes y M reviews. Con esto, el objeto hotel contiene dos matrices: public_likes y reviews. Puede haber cualquier número de valores de cualquier tipo bajo estas matrices. Este es el factor clave que contribuye a la flexibilidad del esquema JSON. Cuando necesites añadir nuevos gustos o comentarios, simplemente añade un nuevo valor o un objeto a esto. 

Al igual que el objeto del hotel anterior, si desnormalizas tu modelo de datos en JSON, puede haber muchas matrices para cada objeto. Los perfiles tienen matrices para aficiones, coches, tarjetas de crédito, preferencias, etc. Cada una de ellas puede ser escalar (simples valores numéricos/cadenas/booleanos) o vectores (matrices de otros escalares, matrices de objetos, etc.). 

 

Una vez modelados y almacenados los datos, hay que procesarlos: seleccionar, unir, proyectar. Couchbase N1QL (SQL para JSON) proporciona un lenguaje expresivo para hacer esto y mucho más. Estos son los casos de uso más comunes.

Indexación de matrices:

La indexación de matrices es un reto para los índices basados en árboles B. Sin embargo, la base de datos JSON tiene que hacerlo para cumplir los requisitos de rendimiento: MongoDB lo hace; Couchbase lo hace. Sin embargo, ambos tienen sus limitaciones. Sólo se puede tener una clave de matriz dentro de un índice. Esto es verdadero de MongoDBesto es verdadero de Couchbase N1QL. La razón principal de esta limitación es que, cuando se indexan elementos de una matriz, se necesitan entradas de índice separadas.  

El tamaño del índice crece exponencialmente como el número de claves del array en el índice y el número de elementos del array en el índice. De ahí la limitación. Las implicaciones de esta limitación son: 

  • Introduce sólo un predicado de matriz en el escaneo del índice y maneja otros predicados después del escaneo del índice.
    • Esto significa que las consultas con múltiples predicados de matriz pueden ser lentas.
  • Evite los índices compuestos con claves de matriz para evitar índices enormes.
    • Esto significa que las consultas con predicados complejos sobre claves de matrices serán lentas.

Buenas noticias de la CAMPO IZQUIERDO.

El índice de búsqueda de texto completo se diseñó para gestionar la búsqueda de patrones de texto basada en la relevancia. Lo hace tokenizando cada campo. En este ejemplo, cada documento se analiza para obtener tokens:

Para cada token, guarda la lista de documentos en los que está presente. Esta es la estructura de árbol invertida. A diferencia de un índice basado en un árbol B, evita repetir el mismo valor de token N veces, una por cada documento en el que está presente. Cuando se tienen millones o miles de millones de documentos, el ahorro es enorme. 

La segunda cosa a tener en cuenta aquí es, el índice invertido utilizado para ¡un ARRECIBO DE TOKENS!    De hecho, la estructura de árbol invertido de la búsqueda de texto completo es ideal para indexar y buscar valores de matrices, especialmente cuando estos valores tienen duplicados. 

Indexar matrices utilizando el índice invertido será el mismo proceso, excepto que no hay tokenización. Volvamos a indexar nuestro documento "bob", con documentos adicionales, "Sam" y "Neill"

En Couchbase FTS tiene un analizador llamado analizador de palabras clave. Esto indexa los valores tal cual en lugar de tratar de encontrar su raíz por stemming. Básicamente, el valor es el token. Para la indexación de valores de matrices, podemos utilizar este índice y explotar las eficiencias de un índice invertido. Construyamos un índice FTS en los documentos bob, sam, neil.  En el caso del árbol invertido, cada campo tiene su propio árbol invertido: uno para id, uno para a y uno para b. Al tratarse de árboles individuales, no crecen exponencialmente como el índice compuesto del árbol B. El número de entradas del índice es proporcional al número de elementos únicos de cada campo. En este caso, tenemos 14 entradas para los 3 documentos con tres campos de un total de 24 valores. La creación de un índice de árbol B en (id, a, b) para el mismo documento creará ¡36 entradas!

Observe que para tres documentos con dos entradas de índice la diferencia es de 157%. A medida que aumenta el número de documentos y el número de matrices, también aumenta el ahorro al utilizar un índice invertido.

Inverted index on three fields.

Índice invertido en tres campos.

Sin embargo, tenemos un problema.  ¿Cómo se procesan los predicados?

El índice B-Tree almacena todos los valores de (id, a y b) juntos, el índice invertido en FTS tiene árboles distintos para cada campo. Por lo tanto, aplicar predicados múltiples no es tan fácil. Esto se aplica tanto al procesamiento de matrices como al de texto. En el tratamiento de textos es habitual hacer preguntas del tipo: buscar todos California residentes con Esquí como su hobby.

Para procesar esto, FTS aplica el predicado en cada campo individualmente para obtener la lista de claves de documento para cada predicado. A continuación, aplica el predicado booleano Y encima. Esta capa utiliza el famoso paquete bitmap rugiente para crear y procesar el mapa de bits de ids de documentos para finalizar el resultado. Sí, hay un procesamiento adicional aquí en comparación con un índice basado en B-TREE más simple, pero esto hace que sea posible indexar muchas matrices y procesar la consulta en un tiempo razonable.

Árbol invertido: Un árbol que sigue dando.

El índice compuesto B-Tree combina la exploración y la aplicación del predicado AND. El enfoque de árbol invertido separa ambos. Indexar y escanear cada campo es diferente de procesar el predicado compuesto. Debido a esta separación, la capa de mapa de bits puede procesar los predicados OR, NOT junto con los predicados AND. Cambiar el AND del ejemplo anterior por OR es simplemente una instrucción al procesamiento del mapa de bits en la calificación y deduplicación del documento

Liberación de COUCHBASE:

Couchbase 6.6 soportará el uso de índices FTS para procesar predicados de arrays complejos. Esto mejora el coste total de propiedad de la gestión de arrays y permite a los desarrolladores y diseñadores utilizar, indexar y consultar arrays según sus necesidades sin limitaciones. Esté atento a los próximos anuncios, documentación, blogs de características, etc.

Referencias

  1. Trabajando con Arrays JSON en N1QL
  2. Utilización de matrices: Modelización, consulta e indexación
  3. Operadores de recogida N1QL de Couchbase
  4. MongoDB: Consulta de un arrray
  5. Couchbase FTS
  6. GRATUITO Formación interactiva sobre Couchbase
  7. FTS BLogs:  https://www.couchbase.com/blog/tag/fts/
  8. Operadores de recogida
  9. Indexación ARRAY
  10. Saca el máximo partido a tus arrays... con N1QL Array Indexing
  11. Aproveche al máximo sus matrices... con índices de matrices de cobertura y mucho más.
  12. Indexación de Couchbase
  13. NEST y UNNEST: normalización y desnormalización de JSON sobre la marcha

Autor

Publicado por Keshav Murthy

Keshav Murthy es Vicepresidente de Couchbase R&D. Anteriormente, estuvo en MapR, IBM, Informix, Sybase, con más de 20 años de experiencia en diseño y desarrollo de bases de datos. Dirigió el equipo de I+D de SQL y NoSQL en IBM Informix. Ha recibido dos premios President's Club en Couchbase y dos premios Outstanding Technical Achievement en IBM. Keshav es licenciado en Informática e Ingeniería por la Universidad de Mysore (India), es titular de diez patentes estadounidenses y tiene tres pendientes.

Dejar una respuesta