Modelado de datos

Modelado de datos JSON para usuarios de RDBMS

El modelado de datos JSON es una parte vital del uso de una base de datos de documentos como Couchbase. Más allá de la comprensión de los conceptos básicos de JSON, hay dos enfoques clave para modelar las relaciones entre los datos que serán cubiertos en esta entrada del blog.

Los ejemplos de este post se basarán en el ejemplo de facturas que mostré en Herramientas CSV para migrar a Couchbase desde una base relacional.

Actualización de datos importados

En el ejemplo anterior, partí de dos tablas de una base de datos relacional: Facturas e InvoicesItems. Cada partida de factura pertenece a una factura, lo que se hace con una clave ajena en una base de datos relacional.

Hice una importación muy directa (ingenua) de estos datos a Couchbase. Cada fila se convirtió en un documento en un bucket "staging".

Data imported from CSV

A continuación, debemos decidir si ese diseño de modelado de datos JSON es apropiado o no (no creo que lo sea, como si el hecho de que el cubo se llame "staging" no lo delatara ya).

Dos enfoques para el modelado de datos JSON de relaciones

Con una base de datos relacional, sólo hay una solución: normalizar los datos. Esto significa tablas separadas con claves externas que unan los datos.

Con una base de datos de documentos, hay dos enfoques. Puede mantener los datos normalizados o puede desnormalizar los datos anidándolos en su documento padre.

Normalizado (documentos separados)

Un ejemplo del estado final del normalizado representa una única factura repartida en varios documentos:

Esto coincide con la importación directa de CSV. En InvoiceId de cada documento de factura es similar a la idea de una clave foránea, pero ten en cuenta que Couchbase (y las bases de datos de documentos distribuidas en general) no imponen esta relación de la misma manera que las bases de datos relacionales. Este es un compromiso hecho para satisfacer las necesidades de flexibilidad, escalabilidad y rendimiento de un sistema distribuido.

Tenga en cuenta que, en este ejemplo, los documentos "hijos" apuntan al padre a través de InvoiceId. Pero también podría ser al revés: el documento "padre" podría contener una matriz con las claves de cada documento "hijo".

Desnormalizado (anidado)

El estado final del anidado se utilizaría un único documento para representar una factura.

Tenga en cuenta que "InvoiceId" ya no está presente en los objetos de la carpeta Artículos array. Estos datos ya no son extranjeros, ahora son nacionales, por lo que ese campo ya no es necesario.

Reglas básicas del modelado de datos JSON

Puede que ya esté pensando que el segundo es una opción natural en este caso. Una factura en este sistema es una raíz agregada. Sin embargo, no siempre es sencillo y obvio cuándo y cómo elegir entre estos dos enfoques en su aplicación.

He aquí algunas reglas generales sobre cuándo elegir cada modelo:

Tabla 1. Ficha de datos de modelización
Si... Entonces considera...

La relación es de 1 a 1 o de 1 a muchos

Objetos anidados

La relación es muchos-a-1 o muchos-a-muchos

Documentos separados

Los datos leídos son en su mayoría campos padre

Documento aparte

Los datos leídos son en su mayoría campos padre + hijo

Objetos anidados

Las lecturas de datos son en su mayoría parentales o niño (no ambos)

Documentos separados

Las escrituras de datos son en su mayoría de los padres y niño (ambos)

Objetos anidados

Ejemplo de modelización

Para profundizar en este tema, hagamos algunas suposiciones sobre el sistema de facturación que estamos construyendo.

  • Un usuario suele ver la factura completa (incluidas las partidas de la factura)
  • Cuando un usuario crea una factura (o realiza cambios), está actualizando tanto los campos "raíz" como los "artículos" juntos
  • Existen algunos consultas (pero no muchas) en el sistema que sólo se interesan por los datos raíz de la factura e ignoran los campos "artículos".

Entonces, basándonos en ese conocimiento, sabemos que:

  1. La relación es de 1 a muchos (una sola factura tiene muchos artículos)
  2. Las lecturas de datos son sobre todo campos padre + hijo juntos

Por tanto, los "objetos anidados" parecen el diseño adecuado.

Recuerde que no se trata de reglas rígidas que se apliquen siempre. Son simplemente directrices que le ayudarán a empezar. La única "mejor práctica" es utilizar tus propios conocimientos y experiencia.

Transformación de datos de puesta en escena con N1QL

Ahora que hemos hecho algunos ejercicios de modelado de datos JSON, es el momento de transformar los datos en el cubo de preparación de documentos separados que vinieron directamente de la base de datos relacional al diseño de objetos anidados.

Hay muchos enfoques para esto, pero voy a mantenerlo muy simple y utilizar el potente Couchbase Lenguaje N1QL para ejecutar consultas SQL en datos JSON.

Preparación de los datos

En primer lugar, cree un bucket de "operación". Voy a transformar los datos y moverlos desde el cubo "staging" (que contiene los datos directos de la base de datos) al cubo "operación". Importación CSV) al cubo "operación".

A continuación, voy a marcar los documentos "raíz" con un campo "tipo". Esta es una forma de marcar los documentos como de un tipo determinado, y será útil más adelante.

Sé que los documentos raíz tienen un campo llamado "InvoiceNum" y que los artículos no tienen este campo. Así que esta es una forma segura de diferenciar.

A continuación, tengo que modificar los elementos. Anteriormente tenían una clave externa que era sólo un número. Ahora esos valores deben actualizarse para que apunten a la nueva clave de documento.

Se trata simplemente de añadir "invoice::" al valor. Tenga en cuenta que los documentos raíz no tienen un campo InvoiceId, por lo que no se verán afectados por esta consulta.

Después de esto, necesito crear un índice en ese campo.

Preparar un índice

Este índice será necesario para la próxima unión transformacional.

Ahora, antes de hacer operativos estos datos, vamos a ejecutar un SELECCIONE para obtener una vista previa y asegurarnos de que los datos se van a unir como esperamos. Utilice N1QL NEST operación:

El resultado de esta consulta debería ser un total de tres documentos de factura raíz.

Results of transformation with N1QL

Los elementos de la factura deberían estar ahora anidados en una matriz "Elementos" dentro de su factura principal (los he contraído en la captura de pantalla anterior en aras de la brevedad).

Mover los datos fuera de la puesta en escena

Una vez que haya verificado que todo parece correcto, puede mover los datos al cubo de "operaciones" mediante un comando INSERTAR que no será más que una ligera variación del comando anterior SELECCIONE mando.

Si eres nuevo en N1QL, hay un par de cosas que señalar aquí:

  • INSERTAR utilizará siempre CLAVE y VALOR. En esta cláusula no se enumeran todos los campos, como se haría en una base de datos relacional.
  • META(i).id es una forma de acceder a la clave de un documento
  • La sintaxis literal JSON que se SELECCIONA COMO v es una forma de especificar los campos sobre los que se desea pasar. Aquí se podrían utilizar comodines.
  • NEST es un tipo de unión que anidará los datos en una matriz en lugar de en el nivel raíz.
  • PARA i especifica el lado izquierdo del EN LA LLAVE join. Esta sintaxis es probablemente la parte menos estándar de N1QL, pero la próxima versión de Couchbase Server incluirá la funcionalidad "ANSI JOIN" que será mucho más natural de leer y escribir.

Después de ejecutar esta consulta, debería tener un total de 3 documentos en su bucket "operación" que representan 3 facturas.

Result from JSON data modeling transformation

Puede eliminar o vaciar el cubo de almacenamiento, ya que ahora contiene datos obsoletos. O puedes conservarlo para seguir experimentando.

Resumen

Migrar datos directamente a Couchbase Server puede ser tan fácil como importar vía CSV y transformar con unas pocas líneas de N1QL. Hacer el modelado real y tomar decisiones requiere más tiempo y reflexión. Una vez que decidas cómo modelar, N1QL te da la flexibilidad para transformar datos relacionales planos y dispersos en un modelo de documentos orientado a la agregación.

Más recursos:

No dude en ponerse en contacto conmigo si tiene alguna pregunta o necesita ayuda. Soy
@mgroves en Twitter. También puede hacer preguntas en Foros de Couchbase. Hay expertos en N1QL allí que son muy receptivos y pueden ayudarte a escribir el N1QL para acomodar tu modelado de datos JSON.

Comparte este artículo
Recibe actualizaciones del blog de Couchbase en tu bandeja de entrada
Este campo es obligatorio.

Autor

Publicado por Matthew Groves

A Matthew D. Groves le encanta programar. No importa si se trata de C#, jQuery o PHP: enviará pull requests para cualquier cosa. Lleva codificando profesionalmente desde que escribió una aplicación de punto de venta en QuickBASIC para la pizzería de sus padres, allá por los años noventa. Actualmente trabaja como Director de Marketing de Producto para Couchbase. Su tiempo libre lo pasa con su familia, viendo a los Reds y participando en la comunidad de desarrolladores. Es autor de AOP in .NET, Pro Microservices in .NET, autor de Pluralsight y MVP de Microsoft.

Deja un comentario

¿Listo para empezar con Couchbase Capella?

Empezar a construir

Consulte nuestro portal para desarrolladores para explorar NoSQL, buscar recursos y empezar con tutoriales.

Utilizar Capella gratis

Ponte manos a la obra con Couchbase en unos pocos clics. Capella DBaaS es la forma más fácil y rápida de empezar.

Póngase en contacto

¿Quieres saber más sobre las ofertas de Couchbase? Permítanos ayudarle.