Tratamento de fusos horários no data mart / warehouse

12

Estamos começando a projetar os blocos de construção de um data mart / armazém e precisamos oferecer suporte a todos os fusos horários (nossos clientes são de todo o mundo). Ao ler as discussões on-line (e nos livros), uma solução comum parece ter uma dimensão separada de data e hora, além de um registro de data e hora nas tabelas de fatos.

No entanto, a pergunta que estou tendo dificuldade em responder é qual é a utilidade das dimensões de data e hora para mim, considerando meus requisitos dinâmicos de fuso horário? Uma dimensão de tempo faz um pouco mais de sentido, mas estou tendo dificuldades com a dimensão de data. Uma abordagem geral de design para uma dimensão de data geralmente inclui propriedades como nome do dia, dia da semana, nome do mês etc. O problema que estou tendo com tudo isso é 23h na terça-feira, 31 de dezembro de 2013 no UTC, na quarta-feira. , 1º de janeiro de 2014 em todos os fusos horários após o UTC + 2.

Portanto, se tiver que fazer todas essas conversões de fuso horário em todas as consultas (e relatórios), qual é o sentido de armazenar e armazenar essas propriedades que provavelmente nunca irei usar (parece)? Algumas pessoas sugerem ter linhas de fatos para cada fuso horário, mas isso me parece ridículo. Precisamos ser capazes de armazenar milhões de registros por mês.

Outros sugerem ter uma tabela de ponte de fuso horário que, embora faça algum sentido, também pareça uma complexidade extra e junções extras para realizar algo que meus aplicativos e relatórios de clientes possam descobrir facilmente a partir de uma data (os relatórios serão principalmente baseados na Web onde existem inúmeras bibliotecas para auxiliar na conversão, exibição e formatação de datas).

A única coisa em que consigo pensar é na facilidade e, possivelmente, no desempenho do agrupamento por data e hora, mas quão ruim é uma prática de agrupar por parte da data (estamos usando o MS SQL, mas estaremos consultando milhões de linhas) ou devemos considerar apenas dimensões extremamente simples de data e hora com, no máximo, números de horas, dias, meses e anos, pois a maioria dos literais, como segunda-feira, não significaria muito quando os fusos horários entrariam em jogo?

Vesselin Obreshkov
fonte
1
Acho que o que você procura é o tipo de dados datetimeoffset e, em seguida, armazena todas as datas na representação UTC. Então, quando você precisar extrair os dados, consulte-os no seu valor UTC e deixe o cliente representá-los no horário local.
Allan S. Hansen,
6
Não consigo pensar em nenhum motivo para armazenar a data independentemente do tempo. Armazene tudo como data e hora UTC e deixe a camada de apresentação se preocupar com a localização.
billinkc
1
Eu concordo com @billinkc. Não tenho certeza do benefício que você obteria com o armazenamento de data e hora separadamente, quando você constantemente os reunia novamente para fazer a conversão do fuso horário.
Mmarie 29/10
2
@ billinkc: "Não consigo pensar em nenhum motivo para armazenar a data independentemente do tempo". - Eu posso. Sempre que você estiver construindo um cubo fora do armazém. Ter dimensões separadas de data e hora do dia é comum e é uma prática recomendada.
Mitch Wheat
@MitchWheat Você poderia me ajudar a entender isso (talvez esteja compondo uma resposta)? Sou uma empresa adulta com vendas globais e, às 23:00 GMT, tenho um forte aumento nas vendas. Eu arrasto meu slicer para o relatório e, certamente, nos fusos horários do Leste e Central dos EUA, talvez haja algumas vendas enquanto as pessoas pegam algumas bebidas embaladas no caminho de casa, mas é 0330 na Índia e ninguém pega o Kingfisher nessa hora e as 6 da manhã de Perth Vocês estão bem abaixo, mas quem está escovando os dentes com VB? Em vez disso, as pessoas compram bebida depois do trabalho de modo 1700ish mas eu então precisa se preocupar com limites de data
billinkc

Respostas:

7

Primeiramente...

Separar-se Datime/Timeem uma Datedimensão e uma Timedimensão é definitivamente o caminho a percorrer.

Para gerenciar vários fusos horários que você precisa para duplicar o DateKeyeo TimeKeypara que você tenha o seguinte:

  • LocalDateKey
  • LocalTimeKey
  • UtcDateKey
  • UtcTimeKey

Você diz...

O problema que estou tendo com tudo isso é que as 23h da terça-feira, 31 de dezembro de 2013 no UTC, são quarta-feira, 1º de janeiro de 2014 em todos os fusos horários após o UTC + 2.

Ao ter as 4 colunas listadas acima, você poderá associar a tabela de fatos à dimensão Data e / ou Hora Usando Aliases de Tabela (na terminologia Kimball, essas tabelas de dimensões com alias são conhecidas como "Dimensões de RPG"), portanto você teria algo como o seguinte:

/*
    Assumes the following:
        - [DateLongName] has the format of this example "Tuesday, December 31, 2013"
        - [TimeShortName] has the format of this example "11:00 PM"
        - Both [DateLongName] & [TimeShortName] are strings
*/
select
    -- Returns a string matching this example  "11:00 PM Tuesday, December 31, 2013"
    localTime.TimeShortName + ' ' + localDate.DateLongName
    ,utcTime.TimeShortName + ' ' + utcDate.DateLongName
    ,f.*
from
    FactTableName  AS f

    -- Local Date and Local Time joins          
    inner join dbo.Date  AS localDate
        on localDate.DateKey = f.LocalDateKey

    inner join dbo.Time  AS localTime
        on localTime.TimeKey = f.LocalTimeKey 

    -- Utc Date and Utc Time joins    
    inner join dbo.Date  AS utcDate
        on utcDate.DateKey = f.UtcDateKey

    inner join dbo.Time  AS utcTime
        on utcTime.TimeKey = f.UtcTimeKey 

No fechamento ...

Como você está construindo um data mart, e não um banco de dados OLTP, a geração dos horários Local e Utc deve ser realizada em seu ETL , NÃO em nenhum aplicativo do lado do cliente pelos seguintes motivos (além da localização do horário UTC no perspectiva do leitor de relatório):

  • O fato de o cálculo residir em qualquer consulta gera uma carga extra de desempenho, multiplicada pelo número de vezes que você precisa executar a consulta para qualquer relatório que tenha (isso é importante ao ler milhões de linhas)
  • Carga extra de garantir que o cálculo seja mantido corretamente em cada consulta (especialmente quando você considera o horário de verão)
  • Impedir a varredura de intervalo de todos os índices dos quais a coluna faz parte, pois você realizará um cálculo na coluna que força as consultas a realizar varreduras de índice em vez de buscas (que geralmente são mais caras à medida que cada página de dados precisa ser lida); isso é conhecido como não- sargável .
    • Editar devido a comentários: isso se aplica se você enviar a conversão para a consulta real .
  • Usando o conceito de disponibilidade de datas e horários UTC adicionais, não há nada que o impeça de adotá-lo e estendê-lo chamando-o StandardisedDateKey, ou CorporateHQDateKey, onde, em vez de uma tabela de datas UTC, você padroniza com base em algum outro padrão comercial acordado
  • Tendo os dois tipos de coluna separados (Local e UTC), permite a comparação lado a lado através da distância geográfica. Pense -> alguém na Austrália digita um registro com registro de data e hora local e UTC, alguém em Nova York lê o relatório com a data e hora Local (Austrália) e a representação de Nova York da data e hora UTC, vendo assim algo sua contraparte australiana aconteceu durante o meio do dia (horário da Austrália) no meio da noite (horário de Nova York). Essa comparação de tempo é indispensável em empresas multinacionais.
Adrian Torrie
fonte
Por que usar dimensões Datee separadas em Timevez de uma única DateTime? Uma tabela de fatos pode ter várias datas e o armazenamento de duas INTs em vez de uma para cada uma pode somar.
Jon of All Trades
1
@ Jon of All Trades: Dimesions separados de Data e Hora é uma prática recomendada comum. Reduz a cardinalidade geral da dimensão e, na prática, geralmente dividimos por data e hora, ou filtramos por data e depois por tempo.
Mitch Wheat
0

Peço desculpas antecipadamente pela brevidade desta resposta e planejo elaborar quando não estou no trabalho.

Certamente, há vantagens em ter tabelas de data e hora, pois permitem uma fácil agregação de seus dados. Em muitos casos, é a maneira mais simples de classificar por mês ou dia útil itens dessa natureza. No entanto, isso não substitui necessariamente a utilidade de um carimbo de data / hora. No seu caso específico, um carimbo de data / hora UTC. Depois de ter esse carimbo de data / hora, basta alterá-lo para o horário local na camada de relatório ou apresentação. Para evitar varreduras de intervalo, verifique também se está convertendo seu intervalo de solicitações para a hora UTC.

Se houver outras perguntas ou comentários, não hesite em perguntar.

Zane
fonte
1
Isso não responde à pergunta.
Mitch Wheat