En mis posts sobre modelado de datos clave-valor con Couchbase, las principales preocupaciones eran:
En un mundo N1QL, todavía estamos pensando en cosas similares y en este post voy a ver dos de ellos:
- * cómo representar los tipos de documentos
- * Modelización de las relaciones entre documentos.
Fundamentalmente, se trata de hacer las concesiones correctas para crear un producto de calidad. modelo físico de datos que represente más eficientemente su modelo lógico. Lo único que ha cambiado son algunos detalles de implementación.
No hacer nada
En primer lugar, vale la pena decir que puedes consultar datos JSON existentes sin tener que hacer ningún cambio. N1QL no te va a exigir que remodeles toda tu base de datos existente.
Sin embargo, puedes hacer cambios a tu modelo que harán que N1QL sea más eficiente y tus consultas más fáciles de escribir. Y si estás empezando desde cero, también podrías considerar la consultabilidad de N1QL desde el principio.
Tipos de documentos
Una de las partes más importantes del modelado de datos clave-valor es el diseño de las claves. En un mundo de clave-valor, la clave tiene una enorme responsabilidad: debe indicarte qué estás almacenando y debe ser fácil de volver a encontrar.
Por ejemplo, las claves de los registros de clientes podrían tener el siguiente formato:
* cust::name
el registro principal del cliente* cust::name::payment
los datos de pago del cliente
Con la consulta enriquecida, el papel del nombre de la clave cambia. En lugar de pedir directamente la clave, se piden los datos que se desean. Estas dos responsabilidades (describir lo que se almacena y facilitar la búsqueda de los datos) se trasladan al propio documento como tipo de documento.
Aquí es donde nos encontramos con una de las grandes diferencias prácticas entre N1QL y SQL: FROM hace menos trabajo en N1QL hoy en día. El alcance de un cubo Couchbase es muy diferente del alcance de una tabla relacional típica.
SQL FROM reduce el alcance de nuestra consulta a los datos que nos interesan. N1QL FROM indica al motor de consulta qué bucket debe consultar. Como un bucket típico contiene todos los datos de una aplicación, necesitamos otra forma de distinguir los tipos de documentos.
Un cliente
Veamos con más detalle un cliente. He aquí un registro sencillo:
{
"name": "Alan Partridge",
"email": "alan@example.com",
"localización": "Norwich",
"teléfono": "+44-1603-619-331",
"docInfo":
{
"tipo": "cliente",
"creado": "2015-10-22T10:17:24.731Z",
"schemaVersion": "1.2.3"
}
}
En tipo para limitar el alcance de nuestra consulta N1QL:
SELECT * FROM
por defecto
WHERE tipo = cliente;
Utilización de la tipo
podemos construir índices que contengan sólo los documentos de un tipo determinado. Por ejemplo:
CREAR ÍNDICE clientes EN
por defecto
WHERE type=cliente;
Lo más probable es que los esquemas de tus documentos ya especifiquen un tipo, particularmente si has estado usando las vistas de Couchbase. En cualquier caso, cuando creas un documento debes especificar su tipo dentro del cuerpo del documento.
En futuras iteraciones de Couchbase y N1QL, podríamos ver namespacing por debajo del nivel de bucket, pero los tipos siempre nos darán una forma de bajo coste de diferenciar documentos.
Relaciones entre documentos
La cuestión de cuándo integrar y cuándo derivar sigue siendo importante cuando se modela para N1QL. La diferencia es que N1QL maneja estas relaciones para usted a través de JOINs.
Las uniones N1QL pueden tener lugar entre:
- * documentos en diferentes cubos
- * documentos en el mismo cubo
En ambos casos, el JOIN hace coincidir un valor del documento de la izquierda con el nombre clave de un documento de la derecha. Por lo tanto, si un documento contiene el nombre clave de otro documento, puede UNIR esos dos documentos.
Añadamos al perfil la compra más reciente de nuestro cliente ficticio:
{ últimaCompra: "prod::drivinggloves" }
El valor aquí es también el nombre clave de un documento de producto en otra parte de nuestro bucket.
Así, para devolver el nombre del cliente y el precio de su última compra para cada cliente que viva en Norwuch, utilizaríamos el siguiente N1QL:
SELECT r.name, a.price FROM
default
r JOIN por defecto
a ON KEYS r.lastPurchase WHERE r.location = "Norwich";
El resultado sería algo así:
{
"requestID": "a2284985-541f-491d-b921-4c248f154293",
"firma":
{
"name": "json",
"price": "json" },
"resultados":
[
{ "name": "Alan Partridge",
"precio": "9.99"
}
],
"estado": "éxito",
"métricas":
{
"elapsedTime": "5.223111ms",
"executionTime": "5.124029ms",
"resultCount": 1,
"resultSize": 77
}
}
Con N1QL, podemos producir relaciones uno a uno, uno a muchos y muchos a muchos entre documentos. Así que mientras que los documentos incrustados eran anteriormente una gran parte de cómo modelábamos nuestros datos para Couchbase, con N1QL se convierten en algo sin esfuerzo para nosotros como desarrolladores.
En resumen
Los dos puntos principales que hay que extraer de este post son:
- los documentos deben tener un tipo que las consultas puedan utilizar para limitar su alcance
- Los JOIN dependen de que la clave principal del documento del lado derecho aparezca en el cuerpo del documento del lado izquierdo.
En última instancia, no hay mucho que cambiar acerca de sus datos JSON para que pueda utilizar N1QL. A medida que te sumerjas más en N1QL, sin duda encontrarás formas de documentos que funcionen mejor que otras. Si es así, compártelas con nosotros en el Foros de Couchbase!