sql >> Database teknologi >  >> RDS >> Database

Se ferier med datamodellerens øjne

Fest!! Familie tid!! Lang køretur!! En dag på stranden!! Alle disse ord summer i vores sind, når vi tænker på ferie. Har du nogensinde overvejet, hvordan en multinational virksomhed holder styr på ferier over hele kloden? Der skal være en dataordbog for at vedligeholde alle disse detaljer, så de kan sikre problemfri forretning med deres lokale partnere.

Denne artikel vil forklare en sådan datamodel.

Projektkravene i en nøddeskal

Jeg har ganske enkle og ligetil krav denne gang. Jeg skal bygge en dataordbog til ferier i mange lande. Jeg vil bygge det som en komponent, der kan integreres i hoveddatamodellen, når og hvor det er nødvendigt.

Om nogle interessante fakta om ferier på tværs af lande

Med hensyn til dets projektkrav er dette et af de enkleste problemer i datamodellering. Alligevel er det svært nok at designe en datamodel til det. Normalt falder helligdage på en fast dato hvert år, men det er ikke tilfældet for hver helligdag i alle lande. Hvis vi analyserer ferier på tværs af forskellige lande, kan vi nemt forudse de komplikationer, der er involveret i dette datamodeldesign.

Lad os tage et kig på nogle interessante fakta om ferier i forskellige lande:

  • Mange helligdage, især patriotiske, holdes på en fast dato hvert år.

    Eksempel:

    Uafhængighedsdag i USA og Indien fejres henholdsvis den 4. juli og den 15. august.

  • Nogle helligdage fejres på en bestemt dag hvert år – men ikke altid den samme kalenderdato.

    Eksempel:

    Thanksgiving day i USA fejres den 4. torsdag i november. Sidste år (2015) faldt dette den 26. november; i år bliver det den 24. november.

  • Nogle helligdage fejres på en fast dato på et år, men hvis datoen falder på lørdag eller søndag, flyttes helligdagen med vilje til den følgende mandag for at holde en lang weekend. Sådan en helligdag kaldes nogle gange 'Mandagiseret' .

    Eksempler:

    I Australien og New Zealand fejres ANZAC Day den 6. februar, men skulle denne dato falde på lørdag eller søndag, holdes helligdagen på mandag en dag eller to senere.

    Et andet godt eksempel er Labor Day i Kina. Denne helligdag er også 'mandagiseret'.

  • Datoerne for nogle helligdage flyttes med en uge, hvis de kolliderer med en anden helligdag.

    Eksempel:

    Familie- og samfundsdag i Australien fejres den første mandag i oktober, men hvis Labor Day også falder på den første mandag, flyttes familiedagen til den anden mandag i oktober.

  • Ikke alle helligdage overholdes som helligdage , dvs. helligdage, hvor banker, finansielle institutter, aktiemarkeder og regeringskontorer er lukkede. (I USA og Canada er helligdage kendt som føderale eller lovbestemte helligdage.)
  • Fædrelandsferier overholdes strengt på den samme dato hvert år. Alle institutter og kontorer (inklusive banker) i alle regioner i landet er lukket den dag. Men i nogle lande, såsom USA og Canada, vil disse helligdage falde på en weekend, også blive overholdt den følgende mandag – det vil sige, at banker og regeringskontorer vil være lukket den mandag.
  • Helligdage med samme navn holdes på forskellige dage i forskellige lande.

    Eksempel:

    Labor Day fejres den 1. maj i Indien, hvorimod den fejres den første mandag i september i Canada.

  • Nogle helligdage er traditionelt bundtet med fridage, der ikke er helligdage.

    Eksempel:

    Labor Day i Kina og Sydafrika holdes på én dag, men to andre fridage er inkluderet.

  • Andre dage, selvom de teknisk set ikke er helligdage, er sædvanligvis tilladt som ikke-arbejdsdage.

    Eksempel:

    I USA er fredagen efter Thanksgiving uofficielt kendt som Black Friday. Det er ikke en offentlig helligdag, men mange virksomheder giver deres ansatte fri.

  • Nogle helligdage observeres forskelligt i forskellige regioner i et land.

    Eksempel:

    Sommerferie i Storbritannien fejres den første mandag i august i Skotland, men den samme helligdag holdes den sidste mandag i august i England, Guernsey, Jersey, Nordirland og Wales.

  • Visse regionale eller lokale helligdage afholdes kun i én del af et land. Disse kan være knyttet til religiøse, etniske eller kulturelle begivenheder.

    Eksempel:

    Louis Riel-dagen fejres kun i den canadiske provins Manitoba.

  • Nogle helligdage for visse helligdage er baseret på en 'før' eller 'efter' betingelse.

    Eksempler:

    • National Patriot's Day fejres i den canadiske provins Quebec mandagen før den 25. maj.
    • Omvendelsesdag i Tyskland fejres onsdagen umiddelbart før 23. november.
    • Jeune Genevois i Schweiz observeres torsdagen efter den første søndag i september.
  • Visse helligdage er baseret på ældre kalendere, der ikke matcher den almindeligt anvendte gregorianske kalender. Derfor varierer deres datoer hvert år.

    Eksempler:

    • Påske fejres den første søndag efter fuldmånen den 21. marts eller snarest efter den.
    • Diwali (en gammel hinduistisk festival) fejres over flere dage, fra slutningen af ​​den hinduistiske månemåned Ashvin og begyndelsen af ​​måneden Kartika. Normalt falder dette et sted mellem midten af ​​oktober og midten af ​​november i den gregorianske kalender.
  • Ortodoks jul – Dette følger den ældre julianske kalender. Fra 2016 er der en forskel på 13 dage mellem den julianske kalender og den gregorianske kalender. Som et resultat falder den ortodokse jul den 7. januar 2016.

Opsummering af fakta

Det er vigtigt at bemærke, at Jeg overvejer kun den internationalt accepterede gregorianske kalender (som følger solcyklussen) til automatisering af datapopulationen for ferier i årevis og landene. I denne artikel, jeg overvejer ikke Lunisolar, hebraiske eller hinduistiske kalendere (som følger månens cyklus). Disse kalendere bliver dog fulgt i bestemte områder af kloden. Indtil videre kan ferier baseret på disse kalendere indlæses manuelt i systemet .

For at opsummere kan ferier på tværs af lande kategoriseres baseret på, hvordan deres datoer er udledt:

  • Faste helligdage – Helligdage, der finder sted på en fast dato hvert år.
  • Bevægelige helligdage – Helligdage, der falder på en bestemt dag, f.eks. den første mandag i februar eller den tredje torsdag i november.
  • Justerbare helligdage – Helligdage, der falder ind under begge kategorier, men som nogle gange overholdes på andre dage for at undgå at støde sammen med andre festligheder (eller kollidere med weekenden) eller flyttet til den næste uge på grund af sammenstød med andre helligdage på samme dato.
  • Helligdage baseret på andre kalendere – Helligdage, der er baseret på den månekalender, den ortodokse eller hinduistiske kalender. Indtil videre føres disse manuelt ind i vores model.

Vi kan yderligere inddele helligdage i to kategorier baseret på hvor de observeres:

  • Nationale helligdage – Helligdage, der holdes på landeniveau.
  • Regionale eller lokale helligdage – Helligdage, der holdes i en bestemt stat eller region i et land.

I næsten alle lande overholdes nationale og regionale helligdage som helligdage på lande- eller regionalt niveau. Ikke alle helligdage er dog helligdage, så vi bør udpege, hvilke helligdage der er helligdage, og hvilke der ikke er det.

På dette tidspunkt bør vi også overveje nogle teoretiske scenarier for specifikke forretningsområder. For eksempel:

  • I nogle lande får banker og andre finansielle institutioner en fridag den første dag i hvert kvartal.
  • Nogle organisationer giver en fridag efter at have offentliggjort deres kvartalsresultater.

Vi vil sørge for, at disse punkter også er inkluderet i vores datamodeldesign.

Design af en omfattende feriedatamodel

Mens jeg designer datamodellen, vil jeg bruge den amerikanske konvention om, at ugen begynder på søndag. Det vil ikke være for svært at ændre dette senere, hvis det er nødvendigt.

Hele denne datamodel vil dreje sig om tre emneområder:"Kalender", "Ferie" og "Land".

Emneområdet "Kalender"

I dette område er der en hovedtabel ved navn calendar der gemmer dadler i mange år. Der vil også være nogle ekstra kolonner til at gemme forudberegnet numeriske værdier, som vil hjælpe os med at udlede datoer for visse flytbare helligdage. Kolonnerne er som følger:

  • week_of_month
  • week_of_quarter
  • week_of_year
  • day_of_year
  • day_of_quarter

Der er yderligere to tabeller i dette emneområde:day_of_week og month_of_year .

Som deres navne antyder, gemmer vi detaljer om individuelle dage og måneder i disse tabeller. Derfor vil de altid have henholdsvis 7 og 12 poster. Nogle ting at huske på for dette afsnit er:

  • Vi kan konfigurere starten af ​​ugen ved hjælp af en sekvenskolonne i begge disse tabeller. Vi kan gøre det samme med starten af ​​året.
  • De primære nøgler i begge tabeller henvises til i calendar bord. De gemmer numeriske værdier for ugedage og måneder af året.
  • Værdien af ​​et år kan udtrækkes fra calendar_date kolonne, men jeg beholder stadig calendar_year som en separat kolonne. Dette giver os mulighed for at opdele tabellen i denne kolonne, hvilket igen muliggør bedre ydeevne for underliggende SQL'er.
  • Størrelsen af ​​talkolonner er blevet defineret ud fra mulige værdier for kolonnen. For eksempel day_of_year skal være en eller anden værdi mellem 1 og 365, så jeg definerer tal(3) som kolonnens datatype.

Ferieområdet "Ferie"

Som vi sagde før, er der to typer ferier – faste og flytbare. Så vi opretter to forskellige tabeller, en for hver type.

holiday_fixed tabel bruger day_of_month og month_of_year_id kolonner til at gemme numeriske værdier for dag og måned. Ved hjælp af disse værdier kan vi udlede en dato for en fast ferie.

På lignende linjer, holiday_moveable tabel vil bruge følgende kolonner til at udlede en dato for hver flytbar helligdag:

is_bank_holiday kolonne angiver, om helligdagen er en helligdag, dvs. alle pengeinstitutter er lukket den dag. Denne kolonne er påkrævet i begge tabeller.

is_mondayized kolonne ændrer datoen for helligdage, der falder på en lørdag eller søndag, men som overholdes den følgende mandag.

Lad os også oprette en anden tabel, nemlig holiday_miscellaneous , for at gemme registreringer for helligdage baseret på ikke-gregorianske kalendere. Poster vil blive indsat i denne tabel manuelt.

Alle disse tre tabeller har én kolonne, der refererer til holiday_category bord. Dette indeholder data om feriens karakter. Der kan være forskellige kategorier her, herunder:

  • Offentlig/helligdag – Banker er officielt lukket, og der finder ingen handel sted.
  • Statsferie – Helligdage på kun statens niveau.
  • National helligdag – Generelt et patriotisk jubilæum eller en dag defineret ved lov, der fejres i hele landet.
  • Lokal helligdag – Erklæret af lokale myndigheder og kun observeret i en bestemt region.
  • Overholdelse – Helligdage, der ikke fejres på deres faktiske datoer, men på en anden dag (ofte mandag). Tillader normalt folk at have en tre-dages weekend.

Du må have lagt mærke til state_id kolonne i alle tre ferietabeller. Lad os tale om betydningen af ​​denne kolonne i næste afsnit.

Emneområdet "Land"

Vi har to tabeller i dette emneområde:

  1. country – som gemmer landenavne og id'er;
  2. state – som gemmer stats- og/eller regionsnavne og id'er for hvert enkelt land.

Til sidst vil vi henvise til denne state tabel i alle tre ferietabeller for at bestemme, hvilken region, stat og land en helligdag tilhører.

Da mange helligdage fejres på landeniveau, giver det ikke mening at føre optegnelser på statsniveau for sådanne helligdage i holiday bord. Det ville blive ekstremt overflødigt. I stedet kan vi have én post i state tabel med 'ALL' som tilstandsnavn. Denne post kan kortlægges med alle helligdage i det pågældende land, hvilket eliminerer behovet for at føre store optegnelser i holiday bord unødvendigt.

Den endelige feriedatamodel

Lad os tage et kig på den komplette feriedatamodel her:




Der er flere måder, vi kan lege med denne model på. For eksempel:

  • Få en liste over alle helligdage i et bestemt land, f.eks. 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’)
    ;
    

  • Find datoen for Thanksgiving Day i 2018 – Husk, at dette fejres i alle stater i USA den fjerde torsdag i november.

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

  • Få en liste over, hvornår uafhængighedsdag fejres i alle lande. Normalt er dette på en fast dato hvert år, og dagen overholdes strengt i alle områder af landet.

    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;
    

Brug af feriedatamodellen

Kunne du tænke dig at lege med denne datamodel? Gå efter det. Her er blot nogle af de forespørgsler, vi fandt på:

  • Find datoerne for Labor Day i forskellige lande.
  • Få en liste over alle helligdage i 2016 for alle dele af Storbritannien.
  • Lav en liste over alle helligdage i Frankrig i 2016.
  • Få listen over alle helligdage i den canadiske provins Manitoba i 2016.

Hvordan lykkedes det dig at gemme ferieoplysninger i din ansøgning? Jeg vil meget gerne høre dine ideer. Du er velkommen til at dele din oplevelse med lagring af disse metadata samt din holdning til vores løsning.


  1. Oracle 11g Express Edition til Windows 64bit?

  2. Sådan downloades Postgres bytea-kolonne som fil

  3. Julen kommer tidligt (Oracle 12.2)

  4. Hvordan løser man MySQL-tegnkodningsproblem?