Ratnopam Chakrabarti es un desarrollador de software que trabaja actualmente para Ericsson Inc. Lleva bastante tiempo centrado en IoT, tecnologías máquina a máquina, coches conectados y dominios de ciudades inteligentes. Le encanta aprender nuevas tecnologías y ponerlas en práctica. Cuando no está trabajando, le gusta pasar tiempo con su hijo de 3 años.
Inserción de documentos con teclas secuenciales (autonumeración)
Durante el proceso de desarrollo de software, a menudo nos encontramos con una situación en la que necesitamos generar una clave única (de una entidad) de forma secuencial ordenada (ya sea en orden creciente o decreciente). Algunos ejemplos comunes son:
-
Almacenamiento de entradas de un archivo de registro con un número de secuencia autogenerado asignado a cada fila de datos.
-
Almacenar entidades empresariales en una base de datos y tener una clave primaria generada a partir de un número de secuencia incremental.
En el mundo de las bases de datos relacionales, esto se consigue haciendo uso de algo conocido como "secuencia de base de datos". La secuencia es una característica proporcionada por la mayoría de los productos de bases de datos que simplemente crea valores numéricos únicos de forma ordenada. Simplemente incrementa un valor y lo devuelve. Sin una secuencia de base de datos no es muy fácil generar números únicos en un orden determinado. Por eso es una opción popular cuando se trata de rellenar una clave primaria (o cualquier clave única) con valores únicos autoincrementables.
Otras formas de generar claves aleatoriamente únicas incluyen el uso de funciones como GUID o UUID. Sin embargo, no existe ninguna garantía en cuanto a la naturaleza de autoincremento que se obtiene al utilizar un generador de secuencias de base de datos.
Sin secuencia en las bases de datos NoSQL
A diferencia del mundo de las bases de datos relacionales, la mayoría de las bases de datos NoSQL del mercado no disponen de una función integrada de generación de secuencias. Se podría argumentar que no es habitual que un sistema distribuido con datos de forma libre tenga un número único autoincremental que sirva como clave única en un documento debido a los números conflictivos que se generan en el caso de la replicación cruzada de datos entre diferentes nodos y fragmentos. En su lugar, la implementación de un UUID parece una opción mucho más viable para garantizar la unicidad. Sin embargo, si necesitas un ID único generado aleatoriamente en una secuencia, entonces de alguna manera necesitas tener una columna de secuencia de incremento automático en una base de datos NoSQL, porque la solución UUID no preservaría la naturaleza secuencial de los números generados. La pregunta principal: ¿Cómo manejar esto usando Couchbase? Bueno, Couchbase lo tiene cubierto y eso es lo que este post describirá.
Configurar un bucket Couchbase para guardar los datos
Digamos que estamos almacenando artículos de un catálogo de productos en Couchbase, y mientras almacenamos los productos en un bucket de Couchbase necesitamos establecer una secuencia generada en cada uno de los datos JSON del producto para que pueda ser utilizado como una "clave" identificable de forma única de un documento.
Para ello, siga estos pasos para crear un cubo llamado "prodcat".
- En primer lugar, inicie sesión en la consola administrativa de Couchbase.
- Tipo http://localhost:8091/ui/index.html en tu navegador.
- Inicie sesión con el nombre de usuario y la contraseña admin.
- Vaya a la pestaña Cubos de datos y haga clic en Crear nuevo cubo de datos.
- Introduzca "prodcat" en el campo Bucket Name y 512 en el campo Per Node RAM Quota.
- Deje todos los demás campos por defecto y haga clic en "Crear".
- Una vez que el cubo se haya creado correctamente, aparecerá con 0 elementos.
Utilización de contradocumentos
Couchbase maneja la generación de secuencias mediante lo que se conoce como un documento "contador". Contador es un documento que puede ser incrementado o decrementado secuencialmente. Algo importante a tener en cuenta aquí es que la operación de incremento o decremento del contador es atómica. Cuando insertamos una entidad de negocio (como Producto en nuestro caso) como un documento JSON, podemos utilizar el documento contador con un patrón clave para generar una secuencia.
El siguiente fragmento de código inicializa un documento contador con un valor inicial de 20.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// crear una conexión a couchbase cluster y bucket Grupo grupo = CouchbaseCluster.crear("127.0.0.1"); Cubo cubo = grupo.openBucket(NOMBRE_CUBO); // Aquí, el BUCKET_NAME = "prodcat" (El que fue creado usando la consola de administración de Couchbase) Cadena clave = "idGeneradorParaProductos"; pruebe { cubo.eliminar(clave); } captura (DocumentDoesNotExistException e) { } pruebe { cubo.contador(clave, 0, 20); } captura (DocumentDoesNotExistException e) { registro.información("el contador aún no existe y no se ha proporcionado un valor inicial"); } |
En este punto, nuestro documento contador se inicializa con un valor de 20.
Ejecutamos el siguiente código en un bucle para insertar los datos de los productos de forma secuencial:
1 2 3 4 5 6 7 8 9 10 11 12 |
largo nextIdNumber = cubo.contador(clave, 1).contenido(); registro.información("nextIdNumber = "+ nextIdNumber); Cadena id = "Prod::" + nextIdNumber; //ya está listo para guardar su documento: Producto producto = ProductUtil.getProducto(nextIdNumber); JsonObject contenido = JsonObject.crear() .poner("tipo", Producto.TIPO) .poner("id", producto.getId()) .poner("descripción", producto.getDescription()) .poner("precio", producto.getPrice()); cubo.insertar(JsonDocument.crear(id, contenido)); |
A continuación se explica el código anterior:
El nextId se calcula incrementando el contador en 1.
Utilizamos nextId para rellenar el campo "id" del documento del producto.
Donde "idGeneratorForProducts" es el documento contador que contiene el valor actual del contador. Cada documento de producto tiene el "id" poblado con la secuencia:
1 2 3 4 5 6 |
{ "id": "Producto 21", "precio": "20", "tipo": "Producto, "descripción": "Este es un producto de utilidad" } |
Vale la pena mencionar que también podemos implementar la secuencia en orden decreciente. En ese caso, lo único que tenemos que hacer es:
- Inicializa el contador al valor máximo.
- Disminuye el contador en 1 para generar el siguienteId en secuencia.
- Utilice el nextId para insertar un documento en un bucket.
Conclusión
El código utilizado para este artículo está escrito en Java y hace uso de la función Spring Boot y Spring Data Dependencias de Couchbase. Los mismos conceptos se pueden aplicar a cualquier SDK de cliente Couchbase.
El código fuente de la aplicación se encuentra en https://github.com/ratchakr/prodcat.
¿Está esta funcionalidad disponible en Admin API (o sólo está disponible con SDK)?