sql >> Database >  >> RDS >> Database

Feestdagen bekijken met de ogen van Data Modeler

Viering!! Familie tijd!! Lange rit!! Een dag op het strand!! Al deze woorden zoemen in ons hoofd als we aan vakantie denken. Heb je er ooit over nagedacht hoe een multinational vakanties over de hele wereld bijhoudt? Er moet een datadictionary zijn om al deze details bij te houden, zodat ze naadloos zaken kunnen doen met hun lokale partners.

In dit artikel wordt een dergelijk datamodel uitgelegd.

De projectvereisten in een notendop

Ik heb deze keer vrij eenvoudige en duidelijke vereisten. Ik moet een datadictionary bouwen voor vakanties in veel landen. Ik wil het bouwen als een component die waar en wanneer nodig kan worden geïntegreerd in het hoofdgegevensmodel.

Over enkele interessante feiten over vakanties in verschillende landen

In termen van de projectvereisten is dit een van de eenvoudigste problemen bij gegevensmodellering. Toch is het al moeilijk genoeg om er een datamodel voor te ontwerpen. Meestal vallen feestdagen elk jaar op een vaste datum, maar dit is niet voor elke feestdag in elk land het geval. Als we vakanties in verschillende landen analyseren, kunnen we gemakkelijk de complicaties voorzien die gepaard gaan met dit datamodelontwerp.

Laten we eens kijken naar enkele interessante feiten over vakanties in verschillende landen:

  • Veel feestdagen, vooral patriottische, worden elk jaar op een vaste datum gevierd.

    Voorbeeld:

    Onafhankelijkheidsdag in de VS en India wordt respectievelijk gevierd op 4 juli en 15 augustus.

  • Sommige feestdagen worden elk jaar op een specifieke dag gevierd, maar niet altijd op dezelfde kalenderdatum.

    Voorbeeld:

    Thanksgiving day wordt in de VS gevierd op de 4e donderdag in november. Vorig jaar (2015) viel dit op 26 november; dit jaar is het 24 november.

  • Sommige feestdagen worden gevierd op een vaste datum in een jaar, maar als de datum op zaterdag of zondag valt, wordt de feestdag opzettelijk verschoven naar de volgende maandag om een ​​lang weekend in acht te nemen. Zo'n feestdag wordt soms 'Maandag' . genoemd .

    Voorbeelden:

    In Australië en Nieuw-Zeeland wordt ANZAC-dag gevierd op 6 februari, maar als die datum op zaterdag of zondag valt, wordt de feestdag een dag of twee later op maandag gevierd.

    Een ander goed voorbeeld is de Dag van de Arbeid in China. Deze feestdag is ook 'maandag'.

  • De datums van sommige feestdagen worden een week verschoven als ze botsen met een andere feestdag.

    Voorbeeld:

    Family and Community Day wordt in Australië gevierd op de eerste maandag van oktober, maar als Labor Day ook op de eerste maandag valt, wordt Family Day verschoven naar de tweede maandag in oktober.

  • Niet alle feestdagen worden beschouwd als feestdagen d.w.z. feestdagen waarop banken, financiële instellingen, beurzen en overheidskantoren gesloten zijn. (In de VS en Canada staan ​​feestdagen bekend als federale of wettelijke feestdagen.)
  • Patriottische feestdagen worden elk jaar strikt op dezelfde datum in acht genomen. Alle instituten en kantoren (inclusief banken) in alle regio's van het land zijn op die dag gesloten. Als deze feestdagen in sommige landen, zoals de VS en Canada, in een weekend vallen, worden ze echter ook op de volgende maandag in acht genomen, dat wil zeggen dat banken en overheidskantoren op die maandag gesloten zijn.
  • Feestdagen met dezelfde naam worden op verschillende dagen in verschillende landen gevierd.

    Voorbeeld:

    Dag van de Arbeid wordt gevierd op 1 mei in India, terwijl het wordt gevierd op de eerste maandag van september in Canada.

  • Sommige vrije dagen op feestdagen worden traditioneel gebundeld met niet-vakantiedagen.

    Voorbeeld:

    Dag van de Arbeid in China en Zuid-Afrika wordt op één dag gevierd, maar twee andere vrije dagen zijn inbegrepen.

  • Andere dagen, hoewel technisch gezien geen feestdagen, zijn gewoonlijk toegestaan ​​als niet-werkdagen.

    Voorbeeld:

    In de VS staat de vrijdag na Thanksgiving onofficieel bekend als Black Friday. Het is geen officiële feestdag, maar veel bedrijven geven hun werknemers een vrije dag.

  • Sommige feestdagen worden in verschillende regio's binnen een land anders gevierd.

    Voorbeeld:

    Summer Bank Holiday in het VK wordt gevierd op de eerste maandag van augustus in Schotland, maar dezelfde feestdag wordt gevierd op de laatste maandag van augustus in Engeland, Guernsey, Jersey, Noord-Ierland en Wales.

  • Bepaalde regionale of lokale feestdagen worden in slechts één deel van een land waargenomen. Deze kunnen verband houden met religieuze, etnische of culturele evenementen.

    Voorbeeld:

    Louis Riel Day wordt alleen gevierd in de Canadese provincie Manitoba.

  • Sommige nalevingsdagen voor bepaalde feestdagen zijn gebaseerd op een 'voor' of 'na' voorwaarde.

    Voorbeelden:

    • Nationale Vaderdag wordt gevierd in de Canadese provincie Quebec op de maandag voor 25 mei.
    • Berouwdag in Duitsland wordt gevierd op de woensdag direct voor 23 november.
    • Jeune Genevois in Zwitserland wordt waargenomen op de donderdag volgende de eerste zondag van september.
  • Bepaalde feestdagen zijn gebaseerd op oudere kalenders die niet overeenkomen met de veelgebruikte Gregoriaanse kalender. Daarom variëren hun data elk jaar.

    Voorbeelden:

    • Pasen wordt gevierd op de eerste zondag na volle maan op of het vroegst na 21 maart.
    • Diwali (een oud hindoeïstisch festival) wordt gedurende meerdere dagen gevierd, vanaf het einde van de hindoe-maanmaand Ashvin en het begin van de maand Kartika. Meestal valt dit ergens tussen half oktober en half november in de Gregoriaanse kalender.
  • Orthodoxe Kerstmis – Dit volgt de oudere Juliaanse kalender. Vanaf 2016 is er een verschil van 13 dagen tussen de Juliaanse kalender en de Gregoriaanse kalender. Als gevolg hiervan valt de orthodoxe kerst op 7 januari 2016.

De feiten samenvatten

Het is belangrijk op te merken dat ik alleen de internationaal geaccepteerde Gregoriaanse kalender in overweging neem (die de zonnecyclus volgt) voor het automatiseren van de datapopulatie voor jaren vakantie en de landen. In dit artikel, Ik overweeg geen lunisolaire, Hebreeuwse of hindoeïstische kalenders (die de maancyclus volgen). Deze kalenders worden echter gevolgd in specifieke regio's van de wereld. Voorlopig kunnen vakanties op basis van deze kalenders handmatig in het systeem worden ingevoerd .

Kortom, feestdagen in verschillende landen kunnen worden gecategoriseerd op basis van hoe hun datums zijn afgeleid:

  • Vaste feestdagen – Feestdagen die elk jaar op een vaste datum vallen.
  • Verplaatsbare feestdagen – Feestdagen die op een specifieke dag vallen, zoals de eerste maandag van februari of de derde donderdag van november.
  • Aanpasbare feestdagen – Feestdagen die onder een van beide categorieën vallen, maar soms op andere dagen in acht worden genomen om te voorkomen dat ze in botsing komen met andere vieringen (of in strijd zijn met het weekend) of verschoven naar de volgende week vanwege botsing met andere feestdagen op dezelfde datum.
  • Feestdagen gebaseerd op andere kalenders – Feestdagen die gebaseerd zijn op de maan-, orthodoxe of hindoeïstische kalender. Voorlopig worden deze handmatig in ons model ingevoerd.

We kunnen vakanties verder onderverdelen in twee categorieën op basis van waar ze worden waargenomen:

  • Nationale feestdagen – Feestdagen die op landelijk niveau worden waargenomen.
  • Regionale of lokale feestdagen – Feestdagen die in een bepaalde staat of regio van een land worden gevierd.

In bijna alle landen worden nationale en regionale feestdagen op landelijk of regionaal niveau als feestdagen beschouwd. Niet alle feestdagen zijn echter feestdagen, dus we moeten aangeven welke feestdagen feestdagen zijn en welke niet.

Op dit punt moeten we ook enkele theoretische scenario's voor specifieke bedrijfsgebieden in overweging nemen. Bijvoorbeeld:

  • In sommige landen krijgen banken en andere financiële instellingen een vrije dag op de eerste dag van elk kwartaal.
  • Sommige organisaties geven een vrije dag nadat ze hun kwartaalresultaten hebben gepubliceerd.

We zullen ervoor zorgen dat deze punten ook worden opgenomen in ons datamodelontwerp.

Een uitgebreid model voor vakantiegegevens ontwerpen

Bij het ontwerpen van het datamodel zal ik de Amerikaanse conventie gebruiken dat de week op zondag begint. Het zal niet zo moeilijk zijn om dit later te wijzigen indien nodig.

Dit hele datamodel zal rond drie thema's draaien:"Kalender", "Vakantie" en "Land".

Het onderwerpgebied "Kalender"

In dit gebied is er een hoofdtabel genaamd calendar die data voor vele jaren bewaart. Er zullen ook enkele extra kolommen zijn om vooraf berekende numerieke waarden op te slaan, wat ons zal helpen datums af te leiden voor bepaalde verplaatsbare feestdagen. De kolommen zijn als volgt:

  • week_of_month
  • week_of_quarter
  • week_of_year
  • day_of_year
  • day_of_quarter

Er zijn nog twee tabellen in dit onderwerpgebied:day_of_week en month_of_year .

Zoals hun namen doen vermoeden, zullen we details van individuele dagen en maanden in deze tabellen opslaan. Daarom zullen ze altijd respectievelijk 7 en 12 records hebben. Enkele dingen om in gedachten te houden voor deze sectie zijn:

  • We kunnen het begin van de week configureren door middel van een volgordekolom in beide tabellen. We kunnen hetzelfde doen met het begin van het jaar.
  • Er wordt verwezen naar de primaire sleutels van beide tabellen in de calendar tafel. Ze slaan numerieke waarden op voor dagen van de week en maanden van het jaar.
  • De waarde van een jaar kan worden gehaald uit de calendar_date kolom, maar ik bewaar nog steeds calendar_year als aparte kolom. Dit stelt ons in staat om de tabel in deze kolom te partitioneren, wat op zijn beurt betere prestaties mogelijk maakt voor onderliggende SQL's.
  • De grootte van nummerkolommen is gedefinieerd op basis van mogelijke waarden voor de kolom. Bijvoorbeeld de day_of_year moet een waarde tussen 1 en 365 zijn, dus ik definieer getal (3) als het gegevenstype van de kolom.

Het onderwerp "Vakantie"

Zoals we al eerder zeiden, zijn er twee soorten vakanties:vast en verplaatsbaar. We maken dus twee verschillende tabellen, één voor elk type.

De holiday_fixed tabel gebruikt day_of_month en month_of_year_id kolommen om numerieke waarden voor dag en maand op te slaan. Met behulp van deze waarden kunnen we een datum afleiden voor een vaste feestdag.

Op vergelijkbare regels, de holiday_moveable tabel gebruikt de volgende kolommen om een ​​datum af te leiden voor elke verplaatsbare feestdag:

De is_bank_holiday kolom geeft aan of de feestdag een feestdag is, d.w.z. alle financiële instellingen zijn op die dag gesloten. Deze kolom is vereist in beide tabellen.

De is_mondayized kolom past de datum aan voor feestdagen die op een zaterdag of zondag vallen maar op de volgende maandag vallen.

Laten we ook een andere tabel maken, namelijk holiday_miscellaneous , om records voor feestdagen op te slaan op basis van niet-Gregoriaanse kalenders. Records worden handmatig in deze tabel ingevoegd.

Al deze drie tabellen hebben één kolom die verwijst naar de holiday_category tafel. Hierin staan ​​gegevens over de aard van de vakantie. Er kunnen hier verschillende categorieën zijn, waaronder:

  • Openbaar / Feestdagen – Banken zijn officieel gesloten en er vindt geen handel plaats.
  • Status feestdag – Feestdagen alleen op staatsniveau.
  • Nationale feestdag – Over het algemeen een patriottische verjaardag of een wettelijk vastgelegde dag die landelijk wordt gevierd.
  • Lokale feestdag – Aangegeven door de lokale overheid en alleen waargenomen in een specifieke regio.
  • Naleving – Feestdagen die niet op hun werkelijke data worden gevierd, maar op een andere dag (vaak maandag). Staat mensen meestal toe een driedaags weekend te hebben.

Je hebt vast de state_id . opgemerkt kolom in alle drie de vakantietabellen. Laten we het hebben over de betekenis van deze kolom in de volgende sectie.

Het onderwerpgebied "Land"

We hebben twee tabellen in dit onderwerpgebied:

  1. country – waarin landnamen en ID's worden opgeslagen;
  2. state – waarin staats- en/of regionamen en ID's voor elk afzonderlijk land worden opgeslagen.

Uiteindelijk zullen we verwijzen naar deze state tabel in alle drie de vakantietabellen om te bepalen tot welke regio, staat en land een vakantie behoort.

Aangezien veel feestdagen op landniveau worden gevierd, heeft het geen zin om dergelijke feestdagen op staatsniveau bij te houden in de holiday tafel. Dat zou extreem overbodig worden. In plaats daarvan kunnen we één record hebben in de state tabel met 'ALL' als staatsnaam. Dit record kan in kaart worden gebracht met alle feestdagen van dat land, waardoor het niet nodig is om enorme records bij te houden in de holiday onnodig aan tafel.

Het definitieve vakantiegegevensmodel

Laten we hier eens kijken naar het volledige vakantiegegevensmodel:




Er zijn verschillende manieren waarop we met dit model kunnen spelen. Bijvoorbeeld:

  • Krijg een lijst van alle feestdagen in een bepaald land, bijvoorbeeld Polen.

    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’)
    ;
    

  • Zoek de datum voor Thanksgiving Day in 2018 – Onthoud dat dit in alle staten van de VS op de vierde donderdag in november wordt gevierd.

    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’ )
    

  • Krijg een lijst van wanneer Onafhankelijkheidsdag in alle landen wordt gevierd. Meestal is dit elk jaar op een vaste datum en wordt de dag in alle delen van het land strikt nageleefd.

    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;
    

Het vakantiegegevensmodel gebruiken

Wil je spelen met dit datamodel? Ga ervoor. Hier zijn slechts enkele van de vragen die we hebben bedacht:

  • Zoek de datums waarop de Dag van de Arbeid in verschillende landen wordt gevierd.
  • Ontvang een lijst van alle feestdagen in 2016 voor elk deel van het VK.
  • Maak een lijst van alle officiële feestdagen in Frankrijk in 2016.
  • Krijg de lijst met alle feestdagen die in 2016 in de Canadese provincie Manitoba zijn waargenomen.

Hoe is het je gelukt om vakantiegegevens op te slaan in je applicatie? Ik zou graag uw ideeën horen. Aarzel niet om uw ervaring met het opslaan van deze metadata te delen, evenals uw mening over onze oplossing.


  1. JDeveloper gebruiken met MySQL Database en Oracle Database op AWS RDS, deel 1

  2. Hoe een externe MySQL-verbinding in te stellen

  3. Postgres-queryoptimalisatie (een indexscan afdwingen)

  4. MySQL - FOUT 1045 - Toegang geweigerd