none
TABELA DIMENSÃO TEMPO RRS feed

  • Pergunta

  • Prezados, Bom dia

    Tenho duas dúvidas, primeira é sobre a tabela tempo, vi alguns vídeos e posts onde pessoal simula o diagrama estrela dizendo que a boa prática de um BI é ter tabela tempo. Problema e que não vi um exemplo de como popular a mesma e quando achei o desenvolvedor inseriu dados nessa tabela o qual não entendi, pois o mesmo fez um for e colocou datas de um período x a y por um getdate()

    Mas supondo que tenho uma tabela vendas, onde consta, produto, cliente, valor e data da venda. Minha dúvida é:

    Essa tabela fato tempo não deveria ser populada com as datas da tabela venda ? Pois se eu criar a fato que é toda feita de fk de outras tabelas e terá id_tempo ligado a tabela tempo, para termos filtros corretos então deveríamos popular ela com dados das datas das vendas e não fazer um for de um período sem vinculo ao tempo de venda como vi o pessoal fazer.

    Estou certo ? Tabela tempo deve ser populada com dados das tabelas dimensões que tem campo data ?

    Segunda dúvida é: por que em uma dimensão fato eu não posso ter as datas já de filtro. Supondo que há um sql consolidado que me traz mês ano etc, e na fato ao popular com id_venda, eu coloque já direto nela o campo, ano, mês, dia ?

    Busca seria muito mais rápido do que pegar de uma tabela secundaria do que fazer o filtro indexado na própria fato. Tirem-me essa dúvida cruel....

    Att

    Luis



    • Editado LCAlvesP quarta-feira, 13 de maio de 2015 11:58
    quarta-feira, 13 de maio de 2015 11:54

Respostas

  • Lcesar, faz total sentido a sua intenção quando estamos falamos em pequenos volumes. Desta forma vc poderia criar dimensões degeneradas a partir da tabela fato. Agora imagina esta técnica aplicada para 100 milhões/1 bilhão de linhas contidas numa tabela fato? Ao criar uma dimensão degenerada, a chave da dimensão passa ser a chave primária da fato. Isto vai onerar e muito a perfomance de suas consultas. 

    O campo data é um campo obrigatório na tabela fato e a melhor prática é criar esta data no formato inteiro (ex. 20150514), conforme sugestão do Renato. Desta forma, vc estará transformando o campo data em uma chave e ganhará mais perfomance pelo fato de trabalhar com um campo do tipo numérico.

    Na dimensão tempo vc populará a linha 20150514 como chave primária, como tipo inteiro e as colunas subsequentes para obter dados mais amigáveis, como Mês, ano, bimestre, semestre, Dia da semana e etc. Neste modelo a sua dimensão terá aproximadamente  1.825 linhas ( 365 dias multiplicado por 5 anos, que geralmente é o padrão de retenção histórica em um datawarehouse). 1.825 linhas é bem diferente de vc ter uma dimensão degenerada de alguns milhões/bilhões de linhas e a perfomance do seu cubo será astronomicamente mais rápido. Quando vc for utilizar a dimensão degenerada, vc não vai visualizar todas as linhas populadas, pois o analysis Services agrupa os dados no momento do processamento, mas o apontamento interno que o Analysis Services realiza é através ID chave primária da fato e não simplesmente pela chave primária da dimensão.

    Quanto as chaves primárias e estrangeiras o seu raciocínio está correto.

    No caso do seu exemplo da fato: id_produto, id_cliente,vr_valor

    Vc precisa adicionar o campo: id_tempo do tipo inteiro, conforme minha sugestão acima.

    Criar uma tabela DimTempo, como chave primária id_tempo e associar os dois campos no momento da modelagem do cubo. 

    A criação e inserção dos dados da DimTempo é feita através de um script com um for looping, começando da data em que a sua fato começou até mais ou menos Y+1. Lembrando que conforme o tempo for passando vc deve continuadamente avançar os registros de datas na tabela fato, ou se quiser já popule 5 anos pra frente. Isto não vai afetar a perfomance nas análises realizadas.

    Espero ter esclarecido suas dúvidas.

    Abs.


    Eduardo Gomes - http://www.h1solucoes.com.br - Twitter: @edugp_sp

    • Marcado como Resposta LCAlvesP sexta-feira, 22 de maio de 2015 01:00
    quinta-feira, 14 de maio de 2015 16:01

Todas as Respostas

  • LCesar,

    Gerar uma dimensão/tabela de tempo com datas pré-fixadas costuma ser uma prática comum em BI. Nas aplicações que desenvolvemos aqui na empresa costumamos fazer isso, até como uma forma de se evitar a necessidade de checar data a data e alimentar a dimensão de tempo (algo que levaria mais tempo durante um processamento moroso).

    Além disso, vc pode criar hieraquias numa dimensão de tempo, como classificações de ano, semestre, trimestre, mês, quinzena e dia. Isto é particularmente útil na elaboração de dashboards e relatórios de BI mais elaborados.

    Se tiver interesse, segue o link de um script usado para popular uma dimensão de tempo no SQL Server:

    http://www.codeproject.com/Articles/647950/Create-and-Populate-Date-Dimension-for-Data-Wareho

    quarta-feira, 13 de maio de 2015 12:16
  • LCesar,

    Como citado pelo Renato é uma boa prática popular uma tabela tempo já com datas pré-definidas, através de um for. A sua linha de racionio faz sentido no ponto de vista de ter uma tabela tempo mais otimizada, contendo apenas as datas que tiveram algum "fato", mas no ponto de vista de perfomance de processamento vc incluirá mais um passo em seu processo de ETL, que consiste em procurar as datas faltantes em sua tabela fato e populá-los na dimensão tempo.

    Quanto a sua segunda pergunta eu não entendi direito. Vc proproe criar uma dimensão de data a partir da tabela fato? É isso?

    Abs.


    Eduardo Gomes - http://www.h1solucoes.com.br - Twitter: @edugp_sp

    quarta-feira, 13 de maio de 2015 15:11
  • Prezados, Boa noite

    Já adianto meu agradecimento a esclarecerem as minha dúvidas, muito obrigado mesmo.

    [Eduardo]

    A minha ideia seria no processo ETL de popular a tabela fato, eu já atribuir campos de data, ano, mês, dia, pois viria a data tratada diretamente da tabela tbd_dim_venda, assim isentando de ter outra tabela para tratamento dessas dimensões;

    Na hora de popular a fato, eu posso tratar no próprio SQL month(dt_venda),year(dt_venda),day(dt_venda) e no insert já atribuir esses campos, assim posso agrupar e fazer qualquer dinâmica somente com dados pertinentes a minhas vendas.

    [Eduardo/Renato]

    Como venho de banco de dados relacional normalizado, estou com sérios problemas para entender a lógica de popular uma tabela tempo por um for.

    Supondo que eu tenha uma:

    a) tbd_dim_produto(id_produto,ds_descricao);

    b) tbd_dim_cliente(id_cliente,ds_cliente);

    c) tbd_dim_filial(id_filial,ds_filial)

    d) tbd_fat_vendas(id_produto,id_cliente,id_filial,total_vendas); --Minha sugestão era colocar ao popular minha tabela de vendas, já com data tratada ficando assim tbd_fat_vendas(id_produto,id_cliente,id_filial,dia,mes,ano,total_vendas);

    Agora o que não entendo e a relação da tabela tbd_dim_tempo(id_tempo,dia,mes,ano), com a minhas dimensão vendas. Aqui que não acho a lógica das chaves, pois se você popula essa tabela com datas aleatórias de um determinado intervalo, qual a ligação com a fato ?

    Se eu tiver 3 vendas = tbd_fat_vendas(id_produto,id_cliente,id_filial,total_vendas);

    a) 1 - 1 - 1 - 100.00 >> Essa venda aconteceu em 01/01/2015

    b) 2 - 1 - 1 - 200.00 >> Essa venda aconteceu em 02/01/2015

    c) 3 - 1 - 1 - 300.00 >> Essa venda aconteceu em 03/01/2015

    Minha dúvida é se eu colocar chave "id_tempo" na fato venda, deixando ela assim: tbd_fat_vendas(id_tempo, id_produto,id_cliente,id_filial,total_vendas);

    Na hora de popular ela, id_tempo é preenchido com qual dado ? Pois preciso de uma chave para procurar na tabela tbd_dim_tempo.

    Imaginei que no meu processo etl, a data de venda eu transformaria em inteiro ex: 01012015 e quando eu ligar pk da tbd_dim_tempo a fk tbd_fat_venda, ai sim teria uma logica de busca.

    Esse id que me atormenta, pois não vi ninguém mostrar um exemplo que popula uma tabela fato com id_tempo me mostrando qual a relação com dimensão tempo.

    Me desculpe de não ter sido objetivo, mas foi a forma que encontrei de explicar meu problema, relacionamento.

    Att

    Luis

    quinta-feira, 14 de maio de 2015 02:07
  • No meu caso, ao menos 2 projetos nos quais estou atuando, usamos um número representando a data como ID. Se considerarmos a data de hoje (14/05/2015), o Id na dimensão Tempo seria 20150514 (considerando um formato como aaaammdd).

    A meu ver então, seu raciocínio está correto.

    quinta-feira, 14 de maio de 2015 11:07
  • Lcesar, faz total sentido a sua intenção quando estamos falamos em pequenos volumes. Desta forma vc poderia criar dimensões degeneradas a partir da tabela fato. Agora imagina esta técnica aplicada para 100 milhões/1 bilhão de linhas contidas numa tabela fato? Ao criar uma dimensão degenerada, a chave da dimensão passa ser a chave primária da fato. Isto vai onerar e muito a perfomance de suas consultas. 

    O campo data é um campo obrigatório na tabela fato e a melhor prática é criar esta data no formato inteiro (ex. 20150514), conforme sugestão do Renato. Desta forma, vc estará transformando o campo data em uma chave e ganhará mais perfomance pelo fato de trabalhar com um campo do tipo numérico.

    Na dimensão tempo vc populará a linha 20150514 como chave primária, como tipo inteiro e as colunas subsequentes para obter dados mais amigáveis, como Mês, ano, bimestre, semestre, Dia da semana e etc. Neste modelo a sua dimensão terá aproximadamente  1.825 linhas ( 365 dias multiplicado por 5 anos, que geralmente é o padrão de retenção histórica em um datawarehouse). 1.825 linhas é bem diferente de vc ter uma dimensão degenerada de alguns milhões/bilhões de linhas e a perfomance do seu cubo será astronomicamente mais rápido. Quando vc for utilizar a dimensão degenerada, vc não vai visualizar todas as linhas populadas, pois o analysis Services agrupa os dados no momento do processamento, mas o apontamento interno que o Analysis Services realiza é através ID chave primária da fato e não simplesmente pela chave primária da dimensão.

    Quanto as chaves primárias e estrangeiras o seu raciocínio está correto.

    No caso do seu exemplo da fato: id_produto, id_cliente,vr_valor

    Vc precisa adicionar o campo: id_tempo do tipo inteiro, conforme minha sugestão acima.

    Criar uma tabela DimTempo, como chave primária id_tempo e associar os dois campos no momento da modelagem do cubo. 

    A criação e inserção dos dados da DimTempo é feita através de um script com um for looping, começando da data em que a sua fato começou até mais ou menos Y+1. Lembrando que conforme o tempo for passando vc deve continuadamente avançar os registros de datas na tabela fato, ou se quiser já popule 5 anos pra frente. Isto não vai afetar a perfomance nas análises realizadas.

    Espero ter esclarecido suas dúvidas.

    Abs.


    Eduardo Gomes - http://www.h1solucoes.com.br - Twitter: @edugp_sp

    • Marcado como Resposta LCAlvesP sexta-feira, 22 de maio de 2015 01:00
    quinta-feira, 14 de maio de 2015 16:01
  • Sei que a pergunta é antiga, mas atualmente tive o problema parecido e logo saí em busca de soluções na net e pode ser que tenha alguma outra pessoa com o mesmo problema que o meu, logo resolvi compartilhar. A solução que utilizei para qual dado seria selecionado para minha id_tempo foi criar uma subquery que selecionava o id_tempo da tabela DIM_TEMPO que fosse correspondente a data anteriormente carregada na dimensão e que fosse igual a data de carga na minha tabela Fato.

    Ficou assim: SET @ID_TEMPO = (SELECT ID_TEMPO FROM DIM_TEMPO T WHERE T.DATA = @DATA_CARGA)

    Pronto, agora para acessar os dados da tabela dim tempo, basta utilizar o id_tempo que foi selecionado de acordo com a data de carga. 

    • Sugerido como Resposta MAGDA AMARAL segunda-feira, 3 de setembro de 2018 18:39
    segunda-feira, 3 de setembro de 2018 18:39