Database
 sql >> Base de Dados >  >> RDS >> Database

Vendo feriados com os olhos do modelador de dados


Celebração!! Tempo para a família!! Longa viagem!! Um dia na praia!! Todas essas palavras zumbem em nossas mentes quando pensamos em feriados. Você já pensou em como uma empresa multinacional acompanha as férias em todo o mundo? Deve haver um dicionário de dados para manter todos esses detalhes para que possam garantir negócios perfeitos com seus parceiros locais.

Este artigo explicará esse modelo de dados.

Os requisitos do projeto em poucas palavras


Eu tenho requisitos bastante simples e diretos desta vez. Preciso construir um dicionário de dados para feriados em muitos países. Quero construí-lo como um componente que pode ser integrado ao modelo de dados principal quando e onde for necessário.

Sobre alguns fatos interessantes sobre feriados em vários países


Em termos de seus requisitos de projeto, este é um dos problemas mais simples na modelagem de dados. No entanto, é difícil projetar um modelo de dados para isso. Normalmente, os feriados caem em uma data fixa todos os anos, mas esse não é o caso de todos os feriados em todos os países. Se analisarmos feriados em vários países, podemos prever facilmente as complicações envolvidas no design desse modelo de dados.

Vamos dar uma olhada em alguns fatos interessantes sobre feriados em vários países:

  • Muitos feriados, especialmente os patrióticos, são observados em uma data fixa todos os anos.

    Exemplo:

    O Dia da Independência nos EUA e na Índia é observado em 4 de julho e 15 de agosto, respectivamente.

  • Alguns feriados são comemorados em um dia específico a cada ano – mas nem sempre na mesma data do calendário.

    Exemplo:

    O Dia de Ação de Graças nos EUA é comemorado na 4ª quinta-feira de novembro. No ano passado (2015) isso caiu em 26 de novembro; este ano, será 24 de novembro.

  • Alguns feriados são celebrados em uma data fixa em um ano, mas se a data cair no sábado ou no domingo, o feriado é propositalmente transferido para a segunda-feira seguinte para observar um fim de semana prolongado. Esse feriado às vezes é chamado de 'Segunda-feira' .

    Exemplos:

    Na Austrália e na Nova Zelândia, o ANZAC Day é comemorado no dia 6 de fevereiro, mas se essa data cair no sábado ou no domingo, o feriado é comemorado na segunda-feira um ou dois dias depois.

    Outro bom exemplo é o Dia do Trabalho na China. Este feriado também é "segunda-feira".

  • As datas de alguns feriados são alteradas em uma semana se colidirem com algum outro feriado.

    Exemplo:

    O Dia da Família e da Comunidade na Austrália é comemorado na primeira segunda-feira de outubro, mas se o Dia do Trabalho também cair na primeira segunda-feira, o Dia da Família será transferido para a segunda segunda-feira de outubro.
  • Nem todos os feriados são considerados feriados bancários , ou seja, feriados quando bancos, instituições financeiras, bolsas de valores e escritórios do governo estão fechados. (Nos EUA e Canadá, feriados bancários são conhecidos como feriados federais ou estatutários.)
  • Os feriados patrióticos são estritamente observados na mesma data todos os anos. Todos os institutos e escritórios (incluindo bancos) em todas as regiões do país estão fechados nesse dia. No entanto, em alguns países, como EUA e Canadá, se esses feriados caírem em um fim de semana, eles também serão observados na segunda-feira seguinte – ou seja, bancos e agências governamentais estarão fechados nessa segunda-feira.

  • Feriados com o mesmo nome são observados em dias diferentes em diferentes países.

    Exemplo:

    O Dia do Trabalho é observado em 1º de maio na Índia, enquanto é observado na primeira segunda-feira de setembro no Canadá.

  • Alguns dias de folga de feriados são tradicionalmente empacotados com dias de folga fora dos feriados.

    Exemplo:

    O Dia do Trabalho na China e na África do Sul é observado em um dia, mas outros dois dias de folga estão incluídos.

  • Outros dias, embora não sejam tecnicamente feriados, são normalmente permitidos como dias não úteis.

    Exemplo:

    Nos EUA, a sexta-feira após o Dia de Ação de Graças é oficialmente conhecida como Black Friday. Não é um feriado do governo, mas muitas empresas dão folga a seus funcionários.

  • Alguns feriados são observados de forma diferente em diferentes regiões de um país.

    Exemplo:

    O Summer Bank Holiday no Reino Unido é comemorado na primeira segunda-feira de agosto na Escócia, mas o mesmo feriado é observado na última segunda-feira de agosto na Inglaterra, Guernsey, Jersey, Irlanda do Norte e País de Gales.

  • Certos feriados regionais ou locais são observados em apenas uma parte de um país. Estes podem estar ligados a eventos religiosos, étnicos ou culturais.

    Exemplo:

    Louis Riel Day é comemorado apenas na província canadense de Manitoba.

  • Alguns dias de observância para certos feriados são baseados em uma condição 'antes' ou 'depois'.

    Exemplos:
    • O Dia Nacional do Patriota é comemorado na província canadense de Quebec na segunda-feira antes 25 de maio.
    • O Dia do Arrependimento na Alemanha é observado na quarta-feira imediatamente antes 23 de novembro.
    • Jeune Genevois na Suíça é observado na quinta-feira seguindo no primeiro domingo de setembro.

  • Certos dias de celebração de feriados são baseados em calendários mais antigos que não correspondem ao calendário gregoriano comumente usado. Portanto, suas datas variam a cada ano.

    Exemplos:
    • A Páscoa é celebrada no primeiro domingo após a lua cheia que ocorre em 21 de março ou logo após.
    • Diwali (um antigo festival hindu) é celebrado durante vários dias, desde o final do mês lunar hindu de Ashvin até o início do mês de Kartika. Normalmente, isso ocorre entre meados de outubro e meados de novembro no calendário gregoriano.
  • Natal Ortodoxo – Segue o calendário juliano mais antigo. A partir de 2016, há uma diferença de 13 dias entre o calendário juliano e o calendário gregoriano. Como resultado, o Natal ortodoxo cai em 7 de janeiro de 2016.

Resumindo os fatos


É importante observar que Estou considerando apenas o calendário gregoriano aceito internacionalmente (que segue o ciclo solar) para automatizar a população de dados para feriados por anos e países. Neste artigo, não estou considerando calendários lunisolar, hebraico ou hindu (que seguem o ciclo lunar). No entanto, esses calendários estão sendo seguidos em regiões específicas do globo. Por enquanto, feriados baseados nesses calendários podem ser inseridos no sistema manualmente .

Para resumir, feriados entre países podem ser categorizados com base em como suas datas são derivadas:
  • Feriados Fixos – Feriados que ocorrem em uma data fixa todos os anos.
  • Férias móveis – Feriados que caem em um dia específico, como a primeira segunda-feira de fevereiro ou a terceira quinta-feira de novembro.
  • Feriados ajustáveis – Feriados que se enquadram em qualquer categoria, mas às vezes são observados em outros dias para evitar conflitos com outras celebrações (ou conflitos com o fim de semana) ou transferidos para a próxima semana devido a conflitos com outros feriados na mesma data.
  • Feriados baseados em outros calendários – Observâncias de feriados baseadas no calendário lunar, ortodoxo ou hindu. Por enquanto, eles são alimentados manualmente em nosso modelo.

Podemos ainda dividir os feriados em duas categorias com base em onde são observados:
  • Feriados Nacionais – Feriados que são observados em nível de país.
  • Feriados regionais ou locais – Feriados que são observados em um determinado estado ou região de um país.

Em quase todos os países, os feriados nacionais e regionais são observados como feriados bancários a nível nacional ou regional. Nem todos os feriados são feriados bancários, portanto, devemos designar quais feriados são feriados bancários e quais não são.

Neste ponto, também devemos considerar alguns cenários teóricos para áreas de negócio específicas. Por exemplo:
  • Em alguns países, os bancos e outras instituições financeiras recebem um dia de folga no primeiro dia de cada trimestre.
  • Algumas organizações dão um dia de folga depois de publicar seus resultados trimestrais.

Garantiremos que esses pontos também sejam incluídos em nosso design de modelo de dados.


Projetando um modelo abrangente de dados de feriados


Ao projetar o modelo de dados, usarei a convenção americana de que a semana começa no domingo. Não será muito difícil mudar isso mais tarde, se necessário.

Todo este modelo de dados girará em torno de três áreas temáticas:“Calendário”, “Férias” e “País”.

A área de assunto "Calendário"


Nesta área, há uma tabela principal chamada calendar que armazena datas por muitos anos. Também haverá algumas colunas adicionais para armazenar valores numéricos pré-calculados, que nos ajudarão a derivar datas para determinados feriados móveis. As colunas são as seguintes:
  • week_of_month
  • week_of_quarter
  • week_of_year
  • day_of_year
  • day_of_quarter

Há mais duas tabelas nesta área de assunto:day_of_week e month_of_year .



Como seus nomes sugerem, armazenaremos detalhes de dias e meses individuais nessas tabelas. Portanto, eles sempre terão 7 e 12 registros respectivamente. Algumas coisas a ter em mente para esta seção são:

  • Podemos configurar o início da semana por meio de uma coluna de sequência em ambas as tabelas. Podemos fazer o mesmo com o início do ano.
  • As chaves primárias de ambas as tabelas são referidas no calendar tabela. Eles armazenam valores numéricos para dias da semana e meses do ano.
  • O valor de um ano pode ser extraído de calendar_date coluna, mas ainda mantenho calendar_year como uma coluna separada. Isso nos permite particionar a tabela nessa coluna, o que, por sua vez, permite um melhor desempenho para SQLs subjacentes.
  • O tamanho das colunas numéricas foi definido com base nos valores possíveis para a coluna. Por exemplo, o day_of_year deve ser algum valor entre 1 e 365, então defino number(3) como o tipo de dados da coluna.

A área temática "Férias"


Como dissemos antes, existem dois tipos de feriados – fixos e móveis. Então vamos criar duas tabelas diferentes, uma para cada tipo.



O holiday_fixed tabela usa day_of_month e month_of_year_id colunas para armazenar valores numéricos para dia e mês. Usando esses valores, podemos derivar uma data para um feriado fixo.

Em linhas semelhantes, o holiday_moveable tabela usará as seguintes colunas para derivar uma data para cada feriado móvel:


O is_bank_holiday coluna significa se o feriado é um feriado bancário, ou seja, todas as instituições financeiras estão fechadas nesse dia. Esta coluna é obrigatória em ambas as tabelas.

O is_mondayized A coluna modifica a data para feriados que caem em um sábado ou domingo, mas são observados na segunda-feira seguinte.

Vamos também criar outra tabela, chamada holiday_miscellaneous , para armazenar registros de feriados com base em calendários não gregorianos. Os registros serão inseridos nesta tabela manualmente.

Todas essas três tabelas têm uma coluna referenciando a holiday_category tabela. Este contém dados sobre a natureza do feriado. Pode haver várias categorias aqui, incluindo:

  • Feriado Público/Banco – Os bancos estão oficialmente fechados e nenhuma negociação ocorre.
  • Feriado Estadual – Feriados no nível estadual.
  • Feriado Nacional – Geralmente um aniversário patriótico ou um dia definido por lei que é comemorado em todo o país.
  • Feriado local – Declarado pelo governo local e observado apenas em uma região específica.
  • Observação – Feriados que não são comemorados em suas datas reais, mas em algum outro dia (geralmente segunda-feira). Geralmente permite que as pessoas tenham um fim de semana de três dias.

Você deve ter notado o state_id coluna em todas as três tabelas de feriados. Vamos falar sobre o significado desta coluna na próxima seção.

A área temática "País"


Temos duas tabelas nesta área de assunto:
  1. country – que armazena nomes e IDs de países;
  2. state – que armazena nomes e IDs de estado e/ou região para cada país individual.



Eventualmente, vamos nos referir a este state tabela em todas as três tabelas de feriados para determinar a qual região, estado e país um feriado pertence.

Como muitos feriados são celebrados em nível de país, não faz sentido manter registros estaduais desses feriados no holiday tabela. Isso se tornaria extremamente redundante. Em vez disso, podemos ter um registro no state tabela com 'ALL' como um nome de estado. Este registro pode ser mapeado com todos os feriados daquele país, eliminando assim a necessidade de manter registros enormes no holiday mesa desnecessariamente.


O modelo de dados de feriados finais


Vamos dar uma olhada no modelo completo de dados de férias aqui:




Existem várias maneiras de brincar com esse modelo. Por exemplo:

  • Obtenha uma lista de todos os feriados observados em um determinado país, digamos, Polônia.

    Select hm.holiday_name, calendar_date, hm.is_bank_holiday from calendar c, holiday_moveable hm
    Where hm.month_of_year_id = c.month_of_year_id
    and hm.day_of_week_id =c.day_of_week_id
    and c.calendar_year = 2016
    And hm.state_id = (select state_id from state s, country c where s.country_id = c.id and c.country_name = ‘POLAND’ )
    UNION ALL
    Select hf.holiday_name, calendar_date, hf.is_bank_holiday from calendar c, holiday_fixed hm
    Where hm.month_of_year_id = c.month_of_year_id
    and hm.day_of_month = to_number(to_char(c.calendar_date,’DD’))
    and c.calendar_year = 2016
    And hm.state_id = (select state_id from state s, country c where s.country_id = c.id and c.country_name = ‘POLAND’)
    ;
    


  • Encontre a data para o Dia de Ação de Graças em 2018 – Lembre-se, isso é comemorado em todos os estados dos EUA na quarta quinta-feira de novembro.

    Select hm.holiday_name, calendar_date, hm.is_bank_holiday from calendar c, holiday_moveable hm
    Where hm.month_of_year_id = c.month_of_year_id
    And hm.day_of_week_id =c.day_of_week_id
    And c.calendar_year = 2018
    And hm.holiday_name = ‘THANKSGIVING’
    And hm.state_id = (select state_id from state s, country c where s.country_id = c.id and c.country_name = ‘USA’ )
    


  • Obtenha uma lista de quando o Dia da Independência é comemorado em todos os países. Normalmente, isso ocorre em uma data fixa todos os anos, e o dia é rigorosamente observado em todas as áreas do país.

    Select c.country_name, calendar_date from calendar c, holiday_fixed hf, state s, country c
    Where hf.state_id = s.id and s.country_id = c.id
    And s.state_name = ‘ALL’
    And c.month_of_year_id = hf.month_of_year_id
    And c.day_of_month = trunc(calendar_date)
    And hf.holiday_name = ‘INDEPENDENCE DAY’
    and c.calendar_year = 2016;
    

Usando o modelo de dados de feriados


Gostaria de brincar com este modelo de dados? Vá em frente. Aqui estão apenas algumas das consultas que pensamos:
  • Encontre as datas em que o Dia do Trabalho é observado em vários países.
  • Receba uma lista de todos os feriados de 2016 para todas as partes do Reino Unido.
  • Faça uma lista de todos os feriados bancários observados na França em 2016.
  • Veja a lista de todos os feriados observados na província canadense de Manitoba em 2016.

Como você conseguiu armazenar os detalhes das férias em seu aplicativo? Eu amaria ouvir suas ideias. Sinta-se à vontade para compartilhar sua experiência com o armazenamento desses metadados, bem como sua opinião sobre nossa solução.