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 como "tipos". Los tipos 0 y 1, los tipos más básicos, sólo rastrean el estado original de los datos o el estado actual de los datos, respectivamente. El tipo 2, que es la implementación más comúnmente aplicada, crea tres nuevos campos: validFromvalidTo, y una marca opcional en el conjunto más reciente de datos, a menudo llamada 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 | Mantén 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úrate de que ambas operaciones de base de datos mencionadas anteriormente ocurran al mismo tiempo. Dependiendo de los requisitos de la aplicación, puedes agrupar los dos comandos anteriores en una transacción para asegurarse de que MongoDB siempre aplique ambos cambios juntos. Para más información, consulta 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, puedes modificar el modelo de datos agregando un campo para almacenar la hora del siguiente evento, además del tiempo de evento por documento. El nuevo campo de fecha garantiza que, si realizas una búsqueda para un momento específico en el tiempo, puedas recuperar fácil y eficientemente el evento respectivo que estás buscando.