Las dimensiones de evolución lenta (SCD) son un marco para gestionar y rastrear los cambios en los datos de dimensiones de un almacén de datos a lo largo del tiempo. Este marco se refiere a las dimensiones como de "evolución lenta" porque asume que las SCD de datos cubren cambios con baja frecuencia, pero sin un patrón temporal aparente. Utilice las SCD cuando los requisitos del almacén de datos incluyan la funcionalidad para rastrear y reproducir resultados basados en el estado histórico de los datos.
Un caso de uso común para los SCD es el reporte. Por ejemplo, en los sistemas de reporte financiero, necesitas explicar las diferencias entre los valores agregados en un reporte generados el mes pasado y los de la versión actual del reporte desde el almacén de datos.
Las diferentes implementaciones de SCD en SQL se denominan "tipos". Los tipos 0 y 1, los más básicos, solo registran el estado original o actual de los datos, respectivamente. El tipo 2, la implementación más común, crea tres nuevos campos: validFrom, validTo y una bandera opcional en el último conjunto de datos, a menudo llamado isValid o isEffective.
Tipos de SCD
Tipo SCD | Descripción |
|---|---|
Tipo 0 | Solo conserva el estado original y los datos no se pueden modificar. |
Tipo 1 | Solo se mantiene actualizado el estado y no se puede almacenar el historial. |
Tipo 2 | Mantener el historial en un nuevo documento. |
Tipo 3 | Mantener el historial en nuevos campos en el mismo documento. |
Tipo 4 | Mantenga el historial en una colección separada. |
Tipo 6 | Combinación de tipo 2 y tipo 3. |
SCD en MongoDB
Puede aplicar el marco SCD a MongoDB de la misma manera que a una base de datos relacional. El concepto de dimensiones de cambio lento se aplica por documento en el modelo de datos seleccionado y optimizado para el caso de uso específico.
Ejemplo
Considere una colección llamada prices que almacena los precios de un conjunto de artículos. Necesita realizar un seguimiento de los cambios de precio de un artículo a lo largo del tiempo para poder procesar devoluciones, ya que el dinero reembolsado debe coincidir con el precio del artículo en el momento de la compra. Cada documento de la colección tiene un campo item y un campo price:
db.prices.insertMany( [ { 'item': 'shorts', 'price': 10 }, { 'item': 't-shirt', 'price': 2 }, { 'item': 'pants', 'price': 5 }, ] )
Supongamos que el precio de los pantalones cambia de 5 a 7. Para rastrear este cambio de precio, asuma los valores predeterminados de los campos de datos necesarios para el tipo SCD 2. El valor predeterminado para validFrom es 01.01.1900, para validTo es 01.01.9999 y para isValid es true. Para cambiar el campo price del objeto por 'item': 'pants', inserte un nuevo documento que represente el estado actual de los pantalones y actualice el documento previamente válido para que ya no lo sea:
let now = new Date(); db.prices.updateOne( { 'item': 'pants', "$or": [ { "isValid": false }, { "isValid": null } ] }, { "$set": { "validFrom": new Date("1900-01-01"), "validTo": now, "isValid": false } } ); db.prices.insertOne( { 'item': 'pants', 'price': 7, "validFrom": now, "validTo": new Date("9999-01-01"), "isValid": true } );
Para evitar romper la cadena de validez, asegúrese de que ambas operaciones de base de datos anteriores se realicen en la misma fecha y hora. Según los requisitos de la aplicación, puede integrar los dos comandos anteriores en una transacción para garantizar que MongoDB siempre aplique ambos cambios juntos. Para más información, consulte Actas.
La siguiente operación demuestra cómo consultar el último price del documento que contiene el elemento pants:
db.prices.find( { 'item': 'pants', 'isValid': true } );
Para consultar el price del documento que contiene el elemento pants en un momento específico, utilice la siguiente operación:
let time = new Date("2022-11-16T13:00:00"); db.prices.find( { 'item': 'pants', 'validFrom': { '$lte': time }, 'validTo': { '$gt': time } } );
Seguimiento de cambios en pocos campos
Si solo necesita realizar un seguimiento de los cambios a lo largo del tiempo en unos pocos campos de un documento, puede usar el tipo SCD 3 incorporando el historial de un campo como una matriz en el primer documento.
Por ejemplo, el siguiente pipeline de agregación actualiza el price en el documento que representa a pants a 7 y almacena el valor anterior de price con una marca de tiempo de cuándo el price anterior se volvió inválido en un arreglo llamado priceHistory:
db.prices.aggregate( [ { $match: { 'item': 'pants' } }, { $addFields: { price: 7, priceHistory: { $concatArrays: [ { $ifNull: [ '$priceHistory', [] ] }, [ { price: "$price", time: now } ] ] } } }, { $merge: { into: "prices", on: "_id", whenMatched: "merge", whenNotMatched: "fail" } } ] )
Esta solución puede volverse lenta o ineficiente si el tamaño de la matriz es demasiado grande. Para evitar matrices grandes, puede usar patrones de valores atípicos o de cubos para diseñar su esquema.
Federación de datos de Outlook
Los ejemplos anteriores se centran en una representación estricta y precisa de los cambios en los campos del documento. En ocasiones, es posible que tenga requisitos menos estrictos para mostrar datos históricos. Por ejemplo, podría tener una aplicación que solo requiere acceso al estado actual de los datos la mayor parte del tiempo, pero debe ejecutar consultas analíticas sobre el historial completo de datos.
En este caso, puede almacenar la versión actual de los datos en una colección y los cambios históricos en otra. Luego, puede eliminar la colección histórica del clúster de MongoDB activo mediante Funcionalidades de base de datos federada MongoDB Atlas, y en la versión totalmente administrada utilizando el Archivo en línea.
Otros casos de uso
Si bien el cambio gradual de dimensiones es útil para el almacenamiento de datos, también puede usar el marco SCD en aplicaciones basadas en eventos. Si tiene eventos poco frecuentes en diferentes tipos de categorías, resulta costoso encontrar el evento más reciente por categoría, ya que el proceso podría requerir agrupar u ordenar los datos para encontrar el estado actual.
En el caso de eventos poco frecuentes, puede modificar el modelo de datos añadiendo un campo que almacene la hora del próximo evento, además de la hora del evento por documento. El nuevo campo de fecha garantiza que, si realiza una búsqueda en un momento específico, pueda recuperar el evento buscado de forma fácil y eficiente.