top of page

A Importância da Dimensão Tempo no Modelo Star Schema

  • Foto do escritor: Michel  Souza Santana
    Michel Souza Santana
  • 17 de dez. de 2024
  • 6 min de leitura

Construindo a Dim_Tempo com Python


Introdução

No contexto de modelagem de dados, especialmente em sistemas OLAP (Online Analytical Processing), o modelo Star Schema é amplamente utilizado. Esse modelo organiza os dados em tabelas fato (que armazenam métricas ou eventos) e tabelas dimensão (que oferecem contexto descritivo).

Dentre as dimensões mais importantes, destaca-se a Dimensão Tempo, que organiza as informações relacionadas a datas e períodos, facilitando a análise histórica e a criação de métricas temporais, como vendas mensais, trimestrais ou anuais.

A Dimensão Tempo é fundamental para o sucesso de análises baseadas em séries temporais e dashboards, permitindo a criação de gráficos e relatórios precisos.


O que é uma Dimensão Tempo?

A Dimensão Tempo (ou Dim_Time) é um componente essencial em modelos de Data Warehousing, especialmente quando utilizamos o modelo Star Schema (Esquema Estrela). Ela contém informações relacionadas ao tempo (datas, meses, trimestres, anos, etc.) que facilitam a análise temporal de dados.

Em um Star Schema, as tabelas são organizadas em:

  • Tabela Fato: Armazena os dados mensuráveis (como vendas, valores, métricas, etc.) e as chaves que referenciam tabelas de dimensões.

  • Tabelas de Dimensão: Armazenam informações contextuais que descrevem os dados na tabela fato (ex.: Dim_Tempo, Dim_Produto, Dim_Cliente).

A Dimensão Tempo permite que analistas e cientistas de dados realizem análises avançadas baseadas em períodos específicos, tais como:

  • Comparar vendas entre anos ou trimestres;

  • Analisar sazonalidades (dias úteis x finais de semana);

  • Identificar padrões em feriados ou dias específicos do ano;

  • Criar relatórios acumulados de período (YTD - Year To Date, MTD - Month To Date, etc.).



Por que a Dimensão Tempo é Importante?

A Dimensão Tempo oferece uma série de benefícios, incluindo:

  1. Análise Histórica: Permite analisar tendências ao longo do tempo, como crescimento de vendas ou comportamento de usuários.

  2. Facilidade de Agregação: Facilita a criação de KPIs temporais (diários, semanais, mensais).

  3. Cálculos de Feriados e Fins de Semana: Auxilia na análise de desempenho em dias úteis versus feriados.

  4. Flexibilidade de Consulta: Torna as queries SQL mais eficientes, simplificando a segmentação temporal dos dados.



Script de Exemplo para Criação da Dimensão Tempo

Abaixo, apresentamos um exemplo prático de um script em Python que gera uma tabela Dim_Tempo no formato CSV.

Este script inclui informações como dia da semana, feriados, semana do ano, trimestre, e outras colunas úteis para análise de dados temporais.


Código em Python:


import csv
import calendar
from datetime import datetime, timedelta

# Função para verificar se uma data é feriado nacional
def verificar_feriado(data):
    # Feriados fixos
    feriados_fixos = [
        (1, 1),    # Ano Novo - 1º de janeiro
        (4, 21),   # Tiradentes - 21 de abril
        (5, 1),    # Dia do Trabalhador - 1º de maio
        (9, 7),    # Independência - 7 de setembro
        (10, 12),  # Nossa Senhora Aparecida - 12 de outubro
        (11, 15),  # Proclamação da República - 15 de novembro
        (12, 25)   # Natal - 25 de dezembro
    ]
    
    # Verificar se a data é um feriado fixo
    if (data.month, data.day) in feriados_fixos:
        return 1
    
    # Feriados móveis
    # Carnaval (2ª-feira antes da Quarta-feira de Cinzas) e Páscoa (Domingo de Páscoa)
    
    # Calcular o Carnaval (2ª feira antes da Quarta-feira de Cinzas)
    carnaval = calcular_carnaval(data.year)
    if data.date() == carnaval:
        return 1

    # Calcular o Domingo de Páscoa
    pascoa = calcular_pascoa(data.year)
    if data.date() == pascoa:
        return 1

    # Se não for nenhum feriado conhecido, retornar 0
    return 0

# Função para calcular a data da Páscoa
def calcular_pascoa(ano):
    a = ano % 19
    b = ano // 100
    c = ano % 100
    d = b // 4
    e = b % 4
    f = (b + 8) // 25
    g = (b - f + 1) // 3
    h = (19 * a + b - d - g + 15) % 30
    i = h // 28
    k = (a + 11 * h + 22 * i) // 451
    l = (h + k - 7 * i + 114) % 31
    pascoa = datetime(ano, 3, 1) + timedelta(days=l + 1)
    return pascoa.date()

# Função para calcular o Carnaval (segunda-feira antes da Quarta-feira de Cinzas)
def calcular_carnaval(ano):
    pascoa = calcular_pascoa(ano)
    carnaval = pascoa - timedelta(days=47)  # Carnaval é 47 dias antes da Páscoa
    return carnaval  # Retorna diretamente um objeto `date`

# Função para gerar a tabela Dim_Tempo
def gerar_dim_tempo(start_date, end_date, output_file):
    # Lista para armazenar as linhas de dados da dimensão
    dim_tempo = []

    # Percorrer todas as datas entre start_date e end_date
    current_date = start_date
    while current_date <= end_date:
        # Obter as informações da data
        year = current_date.year
        quarter = (current_date.month - 1) // 3 + 1
        month = current_date.month
        month_name = calendar.month_name[month]
        day = current_date.day
        day_of_week = current_date.weekday() + 1  # 1 = Segunda-feira, ..., 7 = Domingo
        day_name = calendar.day_name[current_date.weekday()]
        is_weekend = 1 if day_of_week in [6, 7] else 0  # 1 se for fim de semana
        week_of_year = current_date.isocalendar()[1]
        day_of_year = current_date.timetuple().tm_yday
        is_holiday = verificar_feriado(current_date)  # Verificar se é feriado

        # Adicionar a linha à tabela Dim_Tempo
        dim_tempo.append([
            current_date,        # Data completa
            year,                # Ano
            quarter,             # Trimestre
            month,               # Mês
            month_name,          # Nome do mês
            day,                 # Dia do mês
            day_of_week,         # Dia da semana (1-7)
            day_name,            # Nome do dia da semana
            is_weekend,          # Fim de semana (1/0)
            week_of_year,        # Semana do ano
            day_of_year,         # Dia do ano
            is_holiday           # Feriado (1/0)
        ])

        # Avançar para o próximo dia
        current_date += timedelta(days=1)

    # Escrever os dados no arquivo CSV
    with open(output_file, mode='w', newline='') as file:
        writer = csv.writer(file)
        writer.writerow([
            "data_completa", "ano", "trimestre", "mes", "nome_mes", "dia", "dia_semana", 
            "nome_dia_semana", "fim_de_semana", "semana_ano", "dia_ano", "feriado"
        ])
        writer.writerows(dim_tempo)

    print(f"Tabela Dim_Tempo gerada com sucesso em: {output_file}")

# Defina a data de início e fim da tabela
start_date = datetime(1999, 1, 1)  # Data de início
end_date = datetime(2024, 12, 31)  # Data de fim

# Defina o caminho do arquivo CSV de saída
output_file = '/home/michel/Documentos/NOCX/dim_tempo/dim_tempo.csv'

# Chama a função para gerar a tabela
gerar_dim_tempo(start_date, end_date, output_file)

Explicação do Script

  1. Datas Geradas: O script cria todas as datas entre 1999 e 2024.

  2. Cálculo de Feriados: Inclui feriados fixos e móveis (Carnaval e Páscoa).

  3. Colunas Adicionais:

    • Ano, Trimestre, Mês, Nome do Mês.

    • Dia da Semana e Nome do Dia.

    • Feriado (1/0) e Fim de Semana (1/0).

  4. Formato CSV: A tabela é gerada em formato compatível com ferramentas de BI, como Power BI, Tableau e Snowflake.


Estrutura do Script

O script fornecido gera uma tabela Dim_Tempo em formato CSV, contendo os seguintes campos:

Coluna

Descrição

data_completa

A data completa no formato YYYY-MM-DD.

ano

Ano da data (ex.: 2024).

trimestre

Trimestre do ano (1, 2, 3 ou 4).

mes

Mês da data (1 a 12).

nome_mes

Nome do mês (ex.: Janeiro, Fevereiro).

dia

Dia do mês (1 a 31).

dia_semana

Dia da semana (1 = Segunda-feira, ..., 7 = Domingo).

nome_dia_semana

Nome do dia da semana (ex.: Segunda-feira, Terça-feira).

fim_de_semana

Identifica se é final de semana (1 = Sim, 0 = Não).

semana_ano

Número da semana no ano (1 a 52).

dia_ano

Número do dia no ano (1 a 365/366).

feriado

Indica se a data é feriado (1 = Sim, 0 = Não).


Principais Componentes do Script

  1. Verificação de Feriados:O script utiliza uma lista de feriados fixos (ex.: Natal, Ano Novo) e calcula os feriados móveis como Carnaval e Páscoa.

  2. Geração de Datas:A partir de uma data inicial (start_date) até uma data final (end_date), o script percorre cada dia e calcula as informações associadas a ele, como trimestre, semana, dia do ano, etc.

  3. Criação do CSV:Todas as linhas geradas são exportadas para um arquivo CSV, facilitando a importação da tabela em um banco de dados ou ferramenta de BI.


Exemplo de Uso no Star Schema

No Star Schema, a Dim_Tempo pode ser associada a uma Tabela Fato de vendas. Por exemplo:

Dim_Tempo

data_key

ano

trimestre

mes

nome_mes

dia_semana

feriado

2024-01-01

2024

1

1

Janeiro

2 (Segunda)

1 (Sim)

2024-01-02

2024

1

1

Janeiro

3 (Terça)

0 (Não)

Fato_Vendas

data_key

produto_id

quantidade_vendida

valor_venda

2024-01-01

101

150

3000

2024-01-02

101

200

4000

A Dimensão Tempo é um elemento fundamental para análises temporais precisas em qualquer modelo de Data Warehousing. O script apresentado permite criar essa tabela de forma automatizada, incluindo feriados e finais de semana, o que enriquece ainda mais as análises. Incorporar a Dim_Tempo no Star Schema traz agilidade, padronização e flexibilidade para a geração de relatórios e dashboards.

 
 
 

Comments


bottom of page