Diseño de Datawarehouse: dimensión combinada de fecha y hora versus dimensiones separadas de día y hora y zonas horarias


10

Recién estamos comenzando a diseñar un nuevo almacén de datos y estamos tratando de diseñar cómo funcionarán nuestras dimensiones de fecha y hora. Necesitamos ser capaces de soportar múltiples zonas horarias (probablemente al menos GMT, IST, PST y EST). Inicialmente pensamos que tendríamos una dimensión de fecha y hora combinada amplia de hasta una granularidad de 15 minutos, de esa manera tenemos una clave en nuestras tablas de hechos y todos los datos de fecha y hora diferentes para todas las zonas horarias admitidas están en una tabla de dimensión. (es decir, clave de fecha, fecha GMT, hora GMT, fecha IST, hora IST, etc.)

Kimball sugiere tener una dimensión de día separada de la dimensión de hora del día para evitar que la tabla crezca demasiado (The data warehouse toolkit p. 240), lo que suena bien, sin embargo, eso significaría que tenemos dos claves en nuestras tablas de hechos para cada zona horaria necesitamos soporte (uno para la fecha y otro para la hora del día).

Como soy muy inexperto en esta área, espero que alguien conozca las compensaciones entre los dos enfoques, es decir, el rendimiento frente a la gestión de todas las diferentes claves de zona horaria. Tal vez también hay otros enfoques, he visto a algunas personas hablar de tener una fila separada en la tabla de hechos por zona horaria, pero eso parece un problema si las tablas de hechos son millones de filas, entonces debe cuadruplicarlo para agregar zonas horarias .

Si hacemos el grano de 15 minutos, tendremos 131,400 (24 * 15 * 365) filas por año en nuestra tabla de dimensiones de fecha y hora que no suena demasiado horrible para el rendimiento, pero no lo sabremos con seguridad hasta que probemos algunos consultas prototipo. La otra preocupación por tener claves de zona horaria separadas en la tabla de hechos es que la consulta debe unir la tabla de dimensiones a una columna diferente en función de la zona horaria deseada, quizás esto es algo que SSAS se encarga de usted, no estoy seguro .

gracias por cualquier pensamiento, -Matt


1
Esta pregunta también existe en Stack Overflow: stackoverflow.com/questions/2507289/… .
Jon of All Trades

Respuestas:


5

Tener la fecha y la hora separadas le permitirá hacer agregados por tiempo con mucha facilidad. por ejemplo: si desea ejecutar una consulta para encontrar qué período del día está más ocupado. Esto se realiza con mucha facilidad utilizando una dimensión de tiempo separada.

Además, solo debe tener una tecla de tiempo. Decida el horario GMT / EST, luego use esto en la tabla de hechos. Si necesita ejecutar informes basados ​​en la otra zona horaria, simplemente conviértalo en su aplicación o consulta.


Ok, eso tiene sentido, los usuarios no pueden agrupar los datos en función de su zona horaria, pero eso es probablemente algo sin lo que podríamos vivir para simplificar el diseño.
Matt Palmerlee

@MattPalmerlee: los usuarios pueden agrupar por zona horaria si se lo das. Normalmente lo incluiría en la Geographytabla, pero si no se aplica, puede agregarlo como un atributo de su tabla de hechos.
Jon of All Trades

5

Solo un seguimiento de cómo decidimos implementar nuestro DataWarehouse para admitir múltiples zonas horarias y ser lo más eficientes posible: elegimos crear una tabla de zonas horarias (id, nombre, etc.), así como una "zona horaria" puente "que se ve así:

time_zone_bridge
---------------
date_key_utc
time_key_utc
timezone_id
date_key_local
time_key_local

De esta manera, podemos mantener pequeñas nuestras tablas normales de dimensiones de fecha y hora, todos nuestros hechos se vinculan con las teclas de fecha / hora UTC, luego, si necesitamos informar / agrupar por una zona horaria diferente, solo tenemos que unirnos a través de la tabla puente de zona horaria y vincule las teclas locales de fecha / hora a las tablas de dimensiones de fecha y hora. Rellenamos nuestra tabla de puentes de zona horaria utilizando el código C # invocado desde SSIS, ya que esto era mucho menos complicado que hacer cosas TZ desde SqlServer directamente.


También creo que su solución probablemente tenga más sentido sin meterse en nada demasiado complicado. Estoy probando mi DW usando una tabla timeZone y TimeZoneBridge similar a la suya. También tiene tablas TimeDimension y DateDimension. Creé un índice agrupado en date_key_local, time_key_local y timezone_id, de modo que traducir la hora local a la hora UTC usando TimeZoneBridge sería rápido.
dsum

1
Nuestra clave principal agrupada para la tabla del puente está en las columnas de fecha / hora utc + la identificación de la zona horaria (si no recuerdo mal), ya que todas las claves de tiempo de las tablas de hechos estarán en utc, te unirás al puente a través del utc keys + tz id, podría funcionar mejor tener el índice agrupado en esos. Sin embargo, haga lo que tenga sentido para sus necesidades. Me alegra que mi respuesta haya ayudado a alguien, creo que es un buen enfoque y de todas nuestras pruebas, todavía es razonablemente rápido, solo tenga cuidado cuando se trata de la cláusula WHERE: filtre los rangos de fechas que desea tan pronto como sea posible. posible en sus consultas.
Matt Palmerlee

¿Esto solo contiene fechas enteras? O si tiene 86000 valores de "clave de fecha / hora" en su tabla de hechos, la tabla puente tendrá 86000 filas * n zonas horarias admitidas, ¿y eso es solo para ese día?
Aaron Bertrand

1
quizás pueda agregar la definición de tabla exacta que tiene, para que los lectores puedan ver las restricciones primarias y únicas.
ypercubeᵀᴹ

@AaronBert y depende del grano (o la granularidad que elija) para rastrear sus datos, en nuestro caso solo necesitábamos una granularidad de 15 minutos en nuestras tablas de hechos, por lo que solo admitimos 4 * 24 = 96 registros por día por zona horaria, Lo cual es completamente razonable.
Matt Palmerlee

2

He visto DateTimerechazada la idea de un almacén utilizando una dimensión combinada , pero no he visto una razón muy clara por qué. Simplificando ligeramente, aquí está la tabla de hechos que estoy construyendo en este momento:

Transactions
(
...
CreatedDateTimeSK         INT NOT NULL,  -- Four bytes per date...
AuthorizedDateTimeSK      INT NOT NULL,
BatchSubmittedDateTimeSK  INT NOT NULL,
BatchApprovedDateTimeSK   INT NOT NULL,
SettlementDateTimeSK      INT NOT NULL,
LocalTimeZoneSK           TINYINT NOT NULL  -- ...plus one byte for the time zone
)

Los DateTimecampos se unen a una tabla DateTime:

DateTimes
(
DateTimeSK   INT NOT NULL PRIMARY KEY,
SQLDate      DATE NOT NULL,
SQLDateTime  DATETIME2(0) NOT NULL,
Year         SMALLINT NOT NULL,
Month        TINYINT NOT NULL,
Day          TINYINT NOT NULL,
Hour         TINYINT NOT NULL,
Minute       TINYINT NOT NULL CHECK (Minute IN (0, 30)),
...
)

Esto tiene una resolución de media hora, por lo que hay 48 registros por día, 350,400 en 20 años, bastante manejables.

La fecha / hora del evento se traduce a UTC cuando se almacena, pero con el LocalTimeZoneSKcampo y una tabla puente podemos unirnos fácilmente para obtener la hora local:

TimeZoneBridge
(
DateTimeSK       INT NOT NULL,
TimeZoneSK       TINYINT NOT NULL,
PRIMARY KEY (DateTimeSK, TimeZoneSK),
LocalDateTimeSK  INT NOT NULL
)

Para obtener transacciones creadas hoy, hora UTC:

SELECT COUNT(*)
FROM Transactions AS T
  INNER JOIN DateTimes AS CD ON T.CreatedDateTimeSK = CD.DateTimeSK
WHERE CD.SQLDate = '2014-08-22'

Para obtener transacciones creadas hoy, en hora local para la transacción:

SELECT COUNT(*)
FROM Transactions AS T
  INNER JOIN TimeZoneBridge AS TZB ON T.CreatedDateTimeSK = TZB.DateTimeSK AND T.TimeZoneSK = TZB.TimeZoneSK
  INNER JOIN DateTimes AS CD ON TZB.LocalDateTimeSK = CD.DateTimeSK
WHERE CD.SQLDate = '2014-08-22'

Puede tener la tentación de simplificar las cosas reemplazando el TimeZoneSKcon un REALdesplazamiento (por ejemplo, -5.0 para el horario de verano central de EE. UU.), Pero esto se desglosará si algunas fechas / horas para un registro de hechos están en el horario de verano y otras no.

Si los eventos para un registro de hechos pueden ocurrir en diferentes zonas horarias, como un envío o un vuelo, entonces necesita un campo de zona horaria para cada fecha, y tiene hasta cinco bytes por fecha.


Es un enfoque creativo. Sin embargo, como dice que solo tendrá 350,400 filas en su tabla combinada de fecha y hora combinada, si comienza a cambiar el grano a una resolución más fina, entrará rápidamente en los millones de registros. Si elige tener una dimensión de fecha separada de la dimensión de tiempo, solo tiene 48 filas en su tabla de dimensión de tiempo y solo 365 filas por año en su tabla de dimensión de fecha (o 7300 filas en 20 años). Su tabla de hechos simplemente tiene una columna para date_key y time_key. Esto también lo hace más flexible si tiene algunas tablas de hechos que solo requieren granularidad de fecha.
Matt Palmerlee

1
Un millón de filas en una dimensión no me concierne: los datos solo se cambian una vez por década, y un índice de cobertura en la PK y dos o tres campos más utilizados ocuparán una cantidad trivial de RAM del servidor. Sin embargo, agregar media docena de SMALLINTsegundos a una tabla de hechos de mil millones de filas es 12 GB más gastos generales, y ahora está hablando de dinero real. Para las fechas que solo necesitan almacenar la fecha, por supuesto, puede señalarlas al registro "12:00 AM" para la fecha apropiada.
Jon of All Trades
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.