Las dimensiones de cambio lento (SCD, por sus siglas en inglés) es un marco para gestionar y rastrear los cambios en los datos de dimensión en un almacén de datos con el paso del tiempo. Este marco se refiere a las dimensiones como "lentamente cambiantes" porque asume que los SCD de datos cubren cambios con poca frecuencia, pero sin un patrón aparente en el tiempo. Usa SCD cuando los requisitos del Data Warehouse cubran la funcionalidad para rastrear y reproducir salidas en función de los estados históricos 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
SCD Type | Descripción |
|---|---|
Tipo 0 | Solo mantener el estado original y no se pueden cambiar los datos. |
Tipo 1 | Solo mantener el estado actualizado y no se puede almacenar el historial. |
Tipo 2 | Conserved la historia 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. |
SCDs en MongoDB
Puede aplicar el marco SCD a MongoDB de la misma manera que se aplica a una base de datos relacional. El concepto de dimensiones que cambian lentamente se aplica a nivel de documento en el modelo de datos elegido y optimizado para el caso de uso específico.
Ejemplo
Considera una colección denominada prices que almacena los precios de un conjunto de artículos. Necesitas mantener un registro de los cambios del precio de un artículo a lo largo del tiempo para poder procesar devoluciones de un artículo, 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 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 por defecto para los campos de datos necesarios para SCD tipo 2. El valor por defecto para validFrom es 01.01.1900, para validTo es 01.01.9999 y para isValid es true. Para cambiar el campo price en el objeto con 'item': 'pants', inserte un nuevo documento para representar el estado actual de los pantalones y actualice el documento previamente válido para que ya no sea válido:
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 transacción.
La siguiente operación demuestra cómo consultar el price más reciente 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, utiliza 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 necesitas hacer un seguimiento de los cambios a lo largo del tiempo en algunos campos de un documento, puedes utilizar SCD tipo 3 incrustando el historial de un campo como un arreglo 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 tu arreglo se vuelve demasiado grande. Para evitar grandes arreglos, puedes usar los patrones de atípico o bucket para diseñar tu esquema.
Outlook Data Federation
Los ejemplos anteriores se centran en una representación estricta y precisa de los cambios en los campos del documento. A veces, puedes tener requisitos menos estrictos para mostrar datos históricos. Por ejemplo, podrías tener una aplicación que solo requiera acceso al estado actual de los datos la mayor parte del tiempo, pero debes ejecutar algunas consultas analíticas sobre todo el historial 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 colección. Luego se puede remover la colección histórica del clúster activo de MongoDB utilizando la Base de datos federada MongoDB Atlas funcionalidades, y en la versión totalmente gestionada utilizando el Archivo en línea.
Otros casos de uso
Aunque el cambio lento de dimensiones es útil para el almacenamiento de datos, también se puede utilizar el marco SCD en aplicaciones basadas en eventos. Si tienes 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 tus 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.