.NET

Pasar de SQL Server a Couchbase Parte 1: Modelado de datos

En esta serie de entradas de blog, voy a exponer las consideraciones a tener en cuenta al pasar a una base de datos de documentos cuando se tiene una experiencia relacional. En concreto, Microsoft SQL Server en comparación con Servidor Couchbase.

En tres partes, voy a cubrir:

El objetivo es establecer algunas directrices generales que pueda aplicar a la planificación y el diseño de su aplicación.

Si quieres seguirme, he creado una aplicación que demuestra Couchbase y SQL Server lado a lado. Obtenga el código fuente en GitHuby asegúrese de descargar una versión preliminar para desarrolladores de Couchbase Server.

¿Por qué iba a hacerlo?

Antes de empezar, quiero dedicar un poco de tiempo a la motivación. Hay 3 razones principales por las que uno podría considerar el uso de un almacén de datos de documentos en lugar de (o además de) una base de datos relacional. Tu motivación puede ser una o las tres:

  • Velocidad: Couchbase Server utiliza un arquitectura memory-first que puede proporcionar un gran aumento de velocidad en comparación con las bases de datos relacionales.
  • Escalabilidad: Couchbase Server es un base de datos distribuidaque le permite ampliar (y reducir) la capacidad simplemente acumulando hardware básico. Las funciones integradas de Couchbase, como la autodistribución, la replicación y el equilibrio de carga, hacen que el escalado sea mucho más fácil y fluido que el de las bases de datos relacionales.
  • Flexibilidad: Algunos datos encajan perfectamente en un modelo relacional, pero otros pueden beneficiarse de la flexibilidad del uso de JSON. A diferencia de SQL Server, el mantenimiento del esquema ya no es un problema. Con JSON: el esquema se dobla según tus necesidades.

Por estas y otras razones, Gannett cambia SQL Server por Couchbase Server. Si lo está considerando, definitivamente consulte la presentación completa de Gannett.

[youtube https://www.youtube.com/watch?v=mor2p0UqZ14&w=560&h=315]

Cabe señalar que las bases de datos documentales y las bases de datos relacionales pueden ser complementarias. Tu aplicación puede ser mejor servida por una, la otra, o una combinación de ambas. En muchos casos, simplemente no es posible eliminar completamente las bases de datos relacionales de tu diseño, pero una base de datos de documentos como Couchbase Server todavía puede aportar los beneficios anteriores a tu software. El resto de esta serie de blogs asumirá que tienes experiencia con SQL Server y que estás reemplazando, complementando o empezando un nuevo proyecto usando Couchbase.

La facilidad o dificultad de la transición de una aplicación existente varía mucho en función de una serie de factores. En algunos casos puede ser extremadamente fácil; en otros llevará mucho tiempo y será difícil; en algunos casos (cada vez menos) puede que ni siquiera sea una buena idea.

Comprender las diferencias

El primer paso consiste en comprender cómo se modelan los datos en una base de datos documental. En una base de datos relacional, los datos suelen almacenarse en una tabla y se estructuran con claves primarias y externas. Como ejemplo sencillo, consideremos una base de datos relacional para un sitio web que tiene un carrito de la compra, así como características de medios sociales. (En este ejemplo, esas funciones no están relacionadas para simplificar las cosas).

Relational database example diagram

En una base de datos de documentos, los datos se almacenan como claves y valores. Un bucket de Couchbase contiene documentos; cada documento tiene una clave única y un valor JSON. No hay claves externas (o, más exactamente, no hay restricciones de clave externa).

He aquí una comparación de alto nivel de las características/nomenclatura de SQL Server en comparación con Couchbase:

Tabla 1. SQL Server comparado con Couchbase
Servidor SQL Servidor Couchbase

Servidor

Grupo

Base de datos

Cubo

Fila(s) de tabla(s)

Documento

Columna

Clave/valor JSON

Clave principal

Clave del documento

Estas comparaciones son un punto de partida metafórico. Mirando esa tabla, puede ser tentador adoptar un enfoque simplista. "Tengo 5 tablas, por lo tanto me limitaré a crear 5 tipos diferentes de documentos, con un documento por fila". Esto equivale a traducir literalmente una lengua escrita. Este enfoque puede funcionar a veces, pero no tiene en cuenta toda la potencia de una base de datos de documentos que utiliza JSON. Al igual que una traducción literal de una lengua escrita no tiene en cuenta el contexto cultural, los modismos y el contexto histórico.

Debido a la flexibilidad de JSON, los datos de una base de datos de documentos se pueden estructurar más como un objeto de dominio en su aplicación. Por lo tanto, no tienes un desajuste de impedancia que a menudo se aborda con herramientas OR/M como Entity Framework y NHibernate.

Hay dos enfoques principales que puedes utilizar al modelar datos en Couchbase que examinaremos más adelante:

  • Desnormalización - En lugar de dividir los datos entre tablas utilizando claves externas, agrupe los conceptos en un único documento.
  • Referencial - Los conceptos tienen sus propios documentos, pero hacen referencia a otros documentos utilizando la clave de documento.

Ejemplo de desnormalización

Consideremos la entidad "carrito de la compra".

Para representar esto en una base de datos relacional probablemente se necesitarían dos tablas: una tabla ShoppingCart y una tabla ShoppingCartItem con una clave externa a una fila en ShoppingCart.

Al crear el modelo para una base de datos de documentos, hay que decidir si se sigue modelando como dos entidades separadas (por ejemplo, un documento ShoppingCart y los correspondientes documentos ShoppingCartItem) o si se "desnormaliza" y se combinan una fila de ShoppingCart y fila(s) de ShoppingCartItem en un único documento para representar un carrito de la compra.

En Couchbase, utilizando una estrategia de desnormalización, un carrito de la compra y los artículos que contiene estarían representados por un único documento.

Observe que la relación entre los artículos y el carro de la compra está ahora implícita al estar contenidos en el mismo documento. Ya no es necesario un ID en los artículos para representar una relación.

En C#, es probable que defina Carrito de la compra y Artículo para modelar estos datos:

Estas clases seguirían teniendo sentido con Couchbase, así que puedes reutilizarlas o diseñarlas de esta forma. Pero con una base de datos relacional, este diseño no coincide de forma directa.

De ahí la necesidad de OR/Ms como NHibernate o Entity Framework. La forma en que el modelo anterior se puede asignar a una base de datos relacional se representa en Entity Framework* de la siguiente manera:

*Otros OR/M tendrán asignaciones similares

Basándome en estos mapeos y en un análisis de los casos de uso, pude decidir que se modelaría como un único documento en Couchbase. ShoppingCartItemMap sólo existe para que el OR/M sepa cómo rellenar el Artículos propiedad en Carrito de la compra. Además, es poco probable que la aplicación haga lecturas del carrito de la compra sin también necesidad de leer los artículos.

En un post posterior se hablará más de las OR/M, pero por ahora puedo decir que las ShoppingCartMap y ShoppingCartItemMap no son necesarias cuando se utiliza Couchbase, y las clases Id campo de Artículo no es necesario. De hecho, el SDK .NET de Couchbase puede rellenar directamente un Carrito de la compra sin OR/M en una sola línea de código:

Esto no quiere decir que usar Couchbase siempre resulte en un código más corto y fácil de leer. Pero para ciertos casos de uso, definitivamente puede tener un impacto.

Ejemplo referencial

No siempre es posible u óptimo desnormalizar relaciones como la Carrito de la compra ejemplo. En muchos casos, un documento necesitará hacer referencia a otro documento. Dependiendo de cómo su aplicación espera hacer lecturas y escrituras, es posible que desee mantener su modelo en documentos separados mediante el uso de referencias.

Veamos un ejemplo en el que referenciar podría ser el mejor enfoque. Supongamos que tu aplicación tiene algunos elementos de redes sociales. Los usuarios pueden tener amigos, y los usuarios pueden publicar actualizaciones de texto.

Una forma de modelar esto:

  • Usuarios como documentos individuales
  • Actualizaciones como documentos individuales que hacen referencia a un usuario
  • Friends como matriz de claves dentro de un documento de usuario

Con dos usuarios, dos actualizaciones, tendríamos 4 documentos en Couchbase con este aspecto:

Decidí modelar los "amigos" como una relación unidireccional (como Twitter) para este ejemplo, por lo que Matt Groves tiene a Nic Raboy como amigo, pero no viceversa. (No le des demasiada importancia, Nic :).

La forma de modelar esto en C# podría ser:

En Actualización a FriendbookUsuario puede modelarse como una Guía o como otro FriendbookUsuario objeto. Se trata de un detalle de implementación. Usted puede preferir uno, el otro, o ambos, dependiendo de sus necesidades de aplicación y / o cómo su OR / M funciona. En cualquier caso, el modelo subyacente es el mismo.

Aquí está el mapeo que utilicé para estas clases en Entity Framework. Su kilometraje puede variar, dependiendo de cómo utilice EF u otras herramientas OR/M. Concéntrate en el modelo subyacente y no en los detalles de la herramienta de mapeo OR/M.

Si, en lugar de almacenar estas entidades como documentos separados, aplicáramos la misma desnormalización que en el ejemplo de la cesta de la compra e intentáramos almacenar un usuario y las actualizaciones en un solo documento, acabaríamos teniendo algunos problemas.

  • Duplicación de amigosCada usuario almacenaría los datos de sus amigos. Esto no es sostenible, porque ahora la información de un usuario estaría almacenada en múltiples lugares en lugar de tener una única fuente de verdad (a diferencia del carrito de la compra, donde tener el mismo artículo en más de un carrito probablemente no tiene ningún sentido de dominio). Esto podría estar bien cuando se utiliza Couchbase como una caché, pero no como un almacén de datos primario.
  • Tamaño de las actualizaciones: Durante un periodo de uso regular, un usuario individual podría publicar cientos o miles de actualizaciones. Esto podría dar lugar a un documento muy grande que podría ralentizar las operaciones de E/S. Esto se puede mitigar con la herramienta de Couchbase subdocumento APIpero ten en cuenta que Couchbase tiene un límite de 20 MB por documento.

Nota: Aquí también hay un problema de N+1 (amigos de amigos, etc.), pero no voy a dedicar tiempo a resolverlo. Es un problema que no es exclusivo de ninguna de las dos bases de datos.

Además, puede que cuando la aplicación lea o escriba un usuario no necesite leer o escribir amigos y actualizaciones. Y, al escribir una actualización, no es probable que la aplicación necesite actualizar un usuario. Dado que estas entidades a menudo pueden ser leídas/escritas por sí solas, eso indica que necesitan ser modeladas como documentos separados.

Observe la matriz en el Amigos del documento de usuario y el valor del campo Usuario del documento de actualización. Estos valores se pueden utilizar para recuperar los documentos asociados. Más adelante en este post, voy a discutir cómo hacerlo con operaciones clave/valor y cómo hacerlo con N1QL.

En resumen, hay dos formas de modelar datos en una base de datos de documentos. En el ejemplo de la cesta de la compra se utilizó objetos anidadosmientras que el ejemplo de las redes sociales documentos separados. En esos ejemplos, la elección era relativamente sencilla. Cuando tomes tus propias decisiones de modelado, aquí tienes una práctica hoja de trucos:

Tabla 2. 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

Operaciones clave/valor

Para obtener documento(s) en Couchbase, la forma más sencilla y rápida es pedirlos por clave. Una vez que tenga uno de los FriendbookUsuario documentos anteriores, puede ejecutar otra operación para obtener los documentos asociados. Por ejemplo, podría pedirle a Couchbase que me diera los documentos de las claves 2, 3 y 1031 (como una operación por lotes). Esto me daría los documentos de cada amigo. Luego puedo repetir eso para Actualizacionesetc.

El beneficio de esto es la velocidad: las operaciones clave/valor son muy rápidas en Couchbase, y probablemente estarás obteniendo valores directamente de la RAM.

El inconveniente es que implica al menos dos operaciones (obtener el documento FriendbookUser y, a continuación, obtener las actualizaciones). Así que esto puede implicar un poco de codificación adicional. También puede requerir que pienses más detenidamente en cómo construyes las claves de los documentos (más sobre esto más adelante).

N1QL

En Couchbase, tienes la posibilidad de escribir consultas usando N1QL, que es SQL para JSON. Esto incluye el ÚNASE A palabra clave. Esto me permite, por ejemplo, escribir una consulta para obtener las 10 últimas actualizaciones y los usuarios que les corresponden.

El resultado de esta consulta sería:

N1QL le permite tener una gran flexibilidad en la recuperación de datos. No tengo que estar restringido al uso de claves. También es fácil de aprender, ya que es un superconjunto de SQL con el que los usuarios de SQL Server se sentirán cómodos rápidamente. Sin embargo, la contrapartida es que la indexación es importante. Incluso más que la indexación de SQL Server. Si escribiera una consulta en la base de datos Nombre por ejemplo, debería tener un índice como

De lo contrario, la consulta no se ejecutará (si no tiene indexación) o no tendrá rendimiento (si sólo tiene un índice primario creado).

Hay pros y contras en la decisión de utilizar o no la referenciación. Los valores en amigos y usuario son similares a las claves foráneas, en el sentido de que hacen referencia a otro documento. Pero no hay imposición de valores por parte de Couchbase. La gestión de estas claves debe ser manejada adecuadamente por la aplicación. Además, mientras Couchbase provee transacciones ACID para operaciones de un solo documento, no hay transacciones ACID multi-documento disponibles.

Hay formas de abordar estas advertencias en la capa de aplicación que se tratarán con más detalle en posteriores entradas de esta serie, así que permanezca atento.

Diseño clave y diferenciación de documentos

En las bases de datos relacionales, las filas de datos (normalmente, no siempre) corresponden a una clave primaria, que suele ser un número entero o un Guid, y a veces una clave compuesta. Estas claves no tienen necesariamente ningún significado: sólo sirven para identificar una fila dentro de una tabla. Por ejemplo, dos filas de datos en dos tablas diferentes pueden tener la misma clave (un valor entero de 123, por ejemplo), pero eso no significa necesariamente que los datos estén relacionados. Esto se debe a que el esquema aplicado por las bases de datos relacionales a menudo transmite un significado por sí mismo (por ejemplo, el nombre de una tabla).

En bases de datos de documentos como Couchbase, no hay nada equivalente a una tabla, per se. Cada documento en un bucket debe tener una clave única. Pero un bucket puede tener una variedad de documentos en él. Por lo tanto, a menudo es conveniente encontrar una manera de diferenciar los documentos dentro de un cubo.

Claves significativas

Por ejemplo, es perfectamente posible tener un FriendbookUsuario con una clave de 123y un Actualización con una clave de 456. Sin embargo, sería conveniente añadir más información semántica a la clave. En lugar de 123utilice una clave de AmigoUsuario::123. Entre las ventajas de incluir información semántica en su clave figuran las siguientes:

  • Legibilidad: De un vistazo se puede saber para qué sirve un documento.
  • Referenciabilidad: Si tiene un AmigoUsuario::123 documento, entonces podría tener otro documento con una clave FriendbookUser::123::Actualizaciones que tiene una asociación implícita.

Si piensas utilizar N1QL, puede que no necesites que las claves tengan tanto significado semántico. En términos de rendimiento, cuanto más corta es la clave, más de ellas pueden almacenarse en RAM. Así que sólo utilice este patrón si planea hacer un uso intensivo de operaciones clave/valor en lugar de consultas N1QL.

Campos discriminadores

Cuando se utiliza N1QL, otra táctica que se puede utilizar además o en lugar de claves significativas es añadir campo(s) a un documento que se utilizan para diferenciar el documento. Esto suele implementarse como tipo dentro de un documento.

No hay nada mágico en el tipo campo. No es una palabra reservada dentro de un documento y no es tratada especialmente por Couchbase Server. Podría llamarse tipo de documento, elTipoetc. Pero puede ser útil dentro de su aplicación cuando se utiliza N1QL para consultar documentos de un determinado tipo.

Incluso puedes ir un paso más allá y añadir un objeto incrustado a tus documentos para que actúe como una especie de "metadatos" de imitación:

Esto puede ser excesivo para algunas aplicaciones. Es similar a un patrón que he visto en bases de datos relacionales: una tabla "raíz" para simular la herencia dentro de una base de datos relacional, o quizás los mismos campos añadidos a cada tabla.

Conclusión de la 1ª parte

En esta entrada del blog se trató el modelado de datos mediante desnormalización, el modelado de datos mediante referenciación, el diseño de claves y la discriminación de campos. El modelado de datos en una base de datos de documentos es un proceso de pensamiento, algo así como una forma de arte, y no un proceso mecánico. No existe una receta sobre cómo modelar los datos en una base de datos de documentos: depende en gran medida de cómo interactúe la aplicación con los datos.

Puede obtener el código fuente de toda la serie de blogs en GitHub ahorapartes del cual se presentaron en esta entrada del blog. Si tienes preguntas sobre diversas partes de ese código, no dudes en dejar un comentario a continuación o abrir una incidencia en GitHub.

Permanezca atento al próximo blog de la serie, en el que se hablará de datos y migración de datos.

Si tiene alguna pregunta, deje un comentario a continuación, póngase en contacto conmigo en Twittero utilice el botón Foros de Couchbase.

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.

4 Comentarios

  1. [...] volviendo a la primera entrada del blog sobre modelado de datos, la necesidad de transacciones multidocumento suele reducirse o eliminarse, en comparación con un modelo relacional [...]

  2. [...] de SQL Server a Couchbase - Parte 1 (modelado de datos), Parte 2 (migración de datos), Parte 3 [...]

  3. [...] al modelado de datos JSON es algo que toqué en la primera parte de mi serie "Pasar de SQL Server a Couchbase". Desde esa entrada de blog, me han llamado la atención algunas herramientas nuevas de Hackolade, que [...]

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.