Feier!! Familienzeit!! Lange Fahrt!! Ein Tag am Strand!! All diese Wörter schwirren uns in den Sinn, wenn wir an Urlaub denken. Haben Sie jemals darüber nachgedacht, wie ein multinationales Unternehmen die Feiertage auf der ganzen Welt verfolgt? Es muss ein Datenwörterbuch geben, um all diese Details zu pflegen, damit sie reibungslose Geschäfte mit ihren lokalen Partnern sicherstellen können.
Dieser Artikel erklärt ein solches Datenmodell.
Die Projektanforderungen in Kürze
Diesmal habe ich ganz einfache und unkomplizierte Anforderungen. Ich muss ein Datenwörterbuch für Feiertage in vielen Ländern erstellen. Ich möchte es als eine Komponente bauen, die bei Bedarf in das Hauptdatenmodell integriert werden kann.
Über einige interessante Fakten über Feiertage in verschiedenen Ländern
In Bezug auf die Projektanforderungen ist dies eines der einfachsten Probleme in der Datenmodellierung. Es ist jedoch schwierig genug, ein Datenmodell dafür zu entwerfen. Normalerweise fallen Feiertage jedes Jahr auf ein festes Datum, aber das ist nicht bei jedem Feiertag in jedem Land der Fall. Wenn wir Feiertage in verschiedenen Ländern analysieren, können wir leicht die Komplikationen vorhersehen, die mit diesem Datenmodelldesign verbunden sind.
Werfen wir einen Blick auf einige interessante Fakten über Feiertage in verschiedenen Ländern:
-
Viele Feiertage, insbesondere patriotische, werden jedes Jahr an einem festen Datum begangen.
Beispiel:
Der Unabhängigkeitstag in den USA und Indien wird am 4. Juli bzw. 15. August begangen.
-
Einige Feiertage werden jedes Jahr an einem bestimmten Tag gefeiert – aber nicht immer am selben Kalenderdatum.
Beispiel:
Thanksgiving Day wird in den USA am 4. Donnerstag im November gefeiert. Letztes Jahr (2015) fiel dieser auf den 26. November; dieses Jahr ist es der 24. November.
-
Einige Feiertage werden an einem festen Datum in einem Jahr gefeiert, aber wenn das Datum auf einen Samstag oder Sonntag fällt, wird der Feiertag absichtlich auf den folgenden Montag verschoben, um ein langes Wochenende zu feiern. Ein solcher Feiertag wird manchmal als „mondayized“ bezeichnet .
Beispiele:
In Australien und Neuseeland wird der ANZAC-Tag am 6. Februar gefeiert, sollte dieses Datum jedoch auf einen Samstag oder Sonntag fallen, wird der Feiertag ein oder zwei Tage später am Montag begangen.
Ein weiteres gutes Beispiel ist der Tag der Arbeit in China. Dieser Feiertag ist auch „Montagisiert“.
-
Die Daten einiger Feiertage werden um eine Woche verschoben, wenn sie mit anderen Feiertagen kollidieren.
Beispiel:
Der Familien- und Gemeinschaftstag wird in Australien am ersten Montag im Oktober gefeiert, aber wenn der Labor Day auch auf den ersten Montag fällt, wird der Familientag auf den zweiten Montag im Oktober verschoben.
- Nicht alle Feiertage gelten als Bankfeiertage , d. h. Feiertage, an denen Banken, Finanzinstitute, Börsen und Behörden geschlossen sind. (In den USA und Kanada sind Bankfeiertage als bundesstaatliche oder gesetzliche Feiertage bekannt.)
- Patriotische Feiertage werden jedes Jahr am gleichen Tag begangen. Alle Institute und Ämter (einschließlich Banken) in allen Regionen des Landes sind an diesem Tag geschlossen. In einigen Ländern, wie den USA und Kanada, werden diese Feiertage jedoch, wenn sie auf ein Wochenende fallen, auch am darauffolgenden Montag begangen – das heißt, Banken und Behörden sind an diesem Montag geschlossen.
-
Feiertage mit demselben Namen werden in verschiedenen Ländern an verschiedenen Tagen begangen.
Beispiel:
Der Tag der Arbeit wird in Indien am 1. Mai begangen, während er in Kanada am ersten Montag im September begangen wird.
-
Einige Feiertage werden traditionell mit arbeitsfreien Tagen gebündelt.
Beispiel:
Der Tag der Arbeit in China und Südafrika wird an einem Tag begangen, aber zwei weitere freie Tage sind inbegriffen.
-
Andere Tage, die technisch gesehen keine Feiertage sind, werden üblicherweise als arbeitsfreie Tage zugelassen.
Beispiel:
In den USA wird der Freitag nach Thanksgiving inoffiziell als Black Friday bezeichnet. Es ist kein gesetzlicher Feiertag, aber viele Unternehmen geben ihren Mitarbeitern an diesem Tag frei.
-
Einige Feiertage werden in verschiedenen Regionen innerhalb eines Landes unterschiedlich eingehalten.
Beispiel:
Der Sommerfeiertag im Vereinigten Königreich wird in Schottland am ersten Montag im August gefeiert, aber derselbe Feiertag wird am letzten Montag im August in England, Guernsey, Jersey, Nordirland und Wales begangen.
-
Bestimmte regionale oder lokale Feiertage werden nur in einem Teil eines Landes eingehalten. Diese können mit religiösen, ethnischen oder kulturellen Ereignissen verbunden sein.
Beispiel:
Der Louis-Riel-Tag wird nur in der kanadischen Provinz Manitoba gefeiert.
-
Einige Gedenktage für bestimmte Feiertage basieren auf einer „Vorher“- oder „Nachher“-Bedingung.
Beispiele:
- Der National Patriot’s Day wird in der kanadischen Provinz Quebec am Montag vorher begangen den 25. Mai.
- Der Bußtag wird in Deutschland am Mittwoch unmittelbar vor begangen 23. November.
- Jeune Genevois in der Schweiz wird am folgenden Donnerstag begangen am ersten Sonntag im September.
-
Bestimmte Feiertage basieren auf älteren Kalendern, die nicht mit dem allgemein verwendeten gregorianischen Kalender übereinstimmen. Daher variieren ihre Daten jedes Jahr.
Beispiele:
- Ostern wird am ersten Sonntag nach dem Vollmond gefeiert, der am oder frühestens nach dem 21. März auftritt.
- Diwali (ein altes hinduistisches Fest) wird über mehrere Tage gefeiert, vom Ende des hinduistischen Mondmonats Ashvin bis zum Beginn des Monats Kartika. Normalerweise fällt dies irgendwo zwischen Mitte Oktober und Mitte November im gregorianischen Kalender.
- Orthodoxe Weihnachten – Dies folgt dem älteren Julianischen Kalender. Ab 2016 gibt es einen Unterschied von 13 Tagen zwischen dem Julianischen Kalender und dem Gregorianischen Kalender. Folglich fällt das orthodoxe Weihnachtsfest auf den 7. Januar 2016.
Zusammenfassung der Fakten
Es ist wichtig zu beachten, dass ich nur den international anerkannten gregorianischen Kalender berücksichtige (der dem Sonnenzyklus folgt) zur Automatisierung der Datenbefüllung für Feiertage für Jahre und die Länder. In diesem Artikel berücksichtige ich keine lunisolaren, hebräischen oder hinduistischen Kalender (die dem Mondzyklus folgen). Diese Kalender werden jedoch in bestimmten Regionen der Welt befolgt. Vorerst können Feiertage basierend auf diesen Kalendern manuell in das System eingegeben werden .
Zusammenfassend lässt sich sagen, dass Feiertage in verschiedenen Ländern anhand ihrer Daten kategorisiert werden können:
- Feste Feiertage – Feiertage, die jedes Jahr an einem festen Datum liegen.
- Bewegliche Feiertage – Feiertage, die auf einen bestimmten Tag fallen, wie der erste Montag im Februar oder der dritte Donnerstag im November.
- Anpassbare Feiertage – Feiertage, die unter eine der beiden Kategorien fallen, aber manchmal an anderen Tagen begangen werden, um zu vermeiden, dass sie mit anderen Feiertagen (oder mit dem Wochenende) kollidieren, oder auf die nächste Woche verschoben werden, weil sie mit anderen Feiertagen am selben Datum kollidieren.
- Feiertage basierend auf anderen Kalendern – Feiertage, die auf dem Mond-, orthodoxen oder hinduistischen Kalender basieren. Diese werden vorerst manuell in unser Modell eingespeist.
Außerdem können wir Feiertage basierend auf wo in zwei Kategorien einteilen sie werden eingehalten:
- Nationale Feiertage – Feiertage, die auf Landesebene eingehalten werden.
- Regionale oder lokale Feiertage – Feiertage, die in einem bestimmten Staat oder einer bestimmten Region eines Landes begangen werden.
In fast allen Ländern gelten nationale und regionale Feiertage als Bankfeiertage auf Landes- oder Regionalebene. Allerdings sind nicht alle Feiertage Feiertage, also sollten wir angeben, welche Feiertage Feiertage sind und welche nicht.
An dieser Stelle sollten wir auch einige theoretische Szenarien für bestimmte Unternehmensbereiche betrachten. Zum Beispiel:
- In einigen Ländern erhalten Banken und andere Finanzinstitute am ersten Tag jedes Quartals einen freien Tag.
- Einige Organisationen geben nach der Veröffentlichung ihrer Quartalsergebnisse einen Tag frei.
Wir werden sicherstellen, dass diese Punkte auch in unser Datenmodelldesign aufgenommen werden.
Entwurf eines umfassenden Urlaubsdatenmodells
Beim Entwerfen des Datenmodells werde ich die US-Konvention verwenden, dass die Woche am Sonntag beginnt. Es wird nicht allzu schwierig sein, dies später bei Bedarf zu ändern.
Dieses gesamte Datenmodell dreht sich um drei Themenbereiche:"Kalender", "Feiertage" und "Land".
Der Themenbereich „Kalender“
In diesem Bereich gibt es eine Haupttabelle namens calendar
die Daten für viele Jahre speichert. Es wird auch einige zusätzliche Spalten geben, um vorberechnete numerische Werte zu speichern, die uns helfen werden, Daten für bestimmte bewegliche Feiertage abzuleiten. Die Spalten sind wie folgt:
week_of_month
week_of_quarter
week_of_year
day_of_year
day_of_quarter
Es gibt zwei weitere Tabellen in diesem Themenbereich:day_of_week
und month_of_year
.
Wie der Name schon sagt, speichern wir in diesen Tabellen Details zu einzelnen Tagen und Monaten. Daher haben sie immer 7 bzw. 12 Datensätze. Einige Dinge, die Sie in diesem Abschnitt beachten sollten, sind:
- In beiden Tabellen können wir den Wochenstart über eine Sequenzspalte konfigurieren. Dasselbe können wir mit dem Jahresanfang tun.
- Die Primärschlüssel beider Tabellen werden im
calendar
Tisch. Sie speichern numerische Werte für Wochentage und Monate des Jahres. - Der Wert eines Jahres kann aus dem
calendar_date
extrahiert werden Spalte, aber ich behalte immer nochcalendar_year
als eigene Spalte. Dadurch können wir die Tabelle in dieser Spalte partitionieren, was wiederum eine bessere Leistung für zugrunde liegende SQLs ermöglicht. - Die Größe von Zahlenspalten wurde basierend auf möglichen Werten für die Spalte definiert. Beispiel:
day_of_year
muss ein Wert zwischen 1 und 365 sein, also definiere ich Zahl(3) als Datentyp der Spalte.
Der Themenbereich „Urlaub“
Wie wir bereits gesagt haben, gibt es zwei Arten von Feiertagen – feste und bewegliche. Also erstellen wir zwei verschiedene Tabellen, eine für jeden Typ.
Der holiday_fixed
Tabelle verwendet day_of_month
und month_of_year_id
Spalten zum Speichern numerischer Werte für Tag und Monat. Anhand dieser Werte können wir ein Datum für einen festen Feiertag ableiten.
In ähnlicher Weise der holiday_moveable
Die Tabelle verwendet die folgenden Spalten, um ein Datum für jeden beweglichen Feiertag abzuleiten:
Der is_bank_holiday
Spalte gibt an, ob der Feiertag ein Bankfeiertag ist, d. h. alle Finanzinstitute an diesem Tag geschlossen sind. Diese Spalte ist in beiden Tabellen erforderlich.
Der is_mondayized
ändert das Datum für Feiertage, die auf einen Samstag oder Sonntag fallen, aber am darauffolgenden Montag begangen werden.
Lassen Sie uns auch eine weitere Tabelle erstellen, nämlich holiday_miscellaneous
, um Datensätze für Feiertage basierend auf nicht-gregorianischen Kalendern zu speichern. Datensätze werden manuell in diese Tabelle eingefügt.
Alle diese drei Tabellen haben eine Spalte, die auf holiday_category
Tisch. Diese enthält Daten über die Art des Urlaubs. Hier kann es verschiedene Kategorien geben, darunter:
- Öffentlich / Feiertag – Banken sind behördlich geschlossen und es findet kein Handel statt.
- Staatsfeiertag – Feiertage auf Landesebene.
- Nationalfeiertag – In der Regel ein patriotischer Jahrestag oder ein gesetzlich festgelegter Tag, der landesweit begangen wird.
- Lokaler Feiertag – Von der lokalen Regierung erklärt und nur in einer bestimmten Region eingehalten.
- Beachtung – Feiertage, die nicht an ihrem eigentlichen Datum, sondern an einem anderen Tag (oft Montag) begangen werden. Erlaubt den Leuten normalerweise, ein dreitägiges Wochenende zu haben.
Sie müssen die state_id
bemerkt haben Spalte in allen drei Feiertagstabellen. Lassen Sie uns im nächsten Abschnitt über die Bedeutung dieser Spalte sprechen.
Der Themenbereich „Land“
Wir haben zwei Tabellen in diesem Themenbereich:
country
– die Ländernamen und IDs speichert;state
– die Namen und IDs von Bundesstaaten und/oder Regionen für jedes einzelne Land speichert.
Schließlich beziehen wir uns auf diesen state
Tabelle in allen drei Feiertagstabellen, um zu bestimmen, zu welcher Region, zu welchem Staat und zu welchem Land ein Feiertag gehört.
Da viele Feiertage auf Landesebene gefeiert werden, ist es nicht sinnvoll, Aufzeichnungen auf Landesebene für solche Feiertage im holiday
Tisch. Das würde extrem überflüssig werden. Stattdessen können wir einen Datensatz im state
Tabelle mit „ALL“ als Zustandsname. Dieser Datensatz kann mit allen Feiertagen dieses Landes abgebildet werden, wodurch die Notwendigkeit entfällt, riesige Datensätze im holiday
Tabelle unnötig.
Das endgültige Urlaubsdatenmodell
Sehen wir uns hier das vollständige Urlaubsdatenmodell an:
Es gibt mehrere Möglichkeiten, wie wir mit diesem Modell herumspielen können. Zum Beispiel:
-
Rufen Sie eine Liste aller Feiertage ab, die in einem bestimmten Land, z. B. Polen, eingehalten werden.
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’) ;
-
Finden Sie das Datum für Thanksgiving Day im Jahr 2018 – denken Sie daran, dass dies in allen Bundesstaaten der USA am vierten Donnerstag im November gefeiert wird.
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’ )
-
Erhalten Sie eine Liste, wann der Unabhängigkeitstag in allen Ländern gefeiert wird. Normalerweise findet dies jedes Jahr an einem festen Datum statt, und der Tag wird in allen Teilen des Landes streng eingehalten.
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;
Einsatz des Urlaubsdatenmodells
Möchten Sie mit diesem Datenmodell herumspielen? Tue es. Hier sind nur einige der Abfragen, die wir uns ausgedacht haben:
- Hier finden Sie die Daten, an denen der Tag der Arbeit in verschiedenen Ländern begangen wird.
- Erhalten Sie eine Liste aller Feiertage 2016 für jeden Teil des Vereinigten Königreichs.
- Erstellen Sie eine Liste aller Feiertage, die 2016 in Frankreich eingehalten wurden.
- Rufen Sie die Liste aller Feiertage auf, die 2016 in der kanadischen Provinz Manitoba begangen wurden.
Wie haben Sie es geschafft, Urlaubsdetails in Ihrer Anwendung zu hinterlegen? Ich würde gerne Ihre Ideen hören. Bitte zögern Sie nicht, Ihre Erfahrungen mit der Speicherung dieser Metadaten sowie Ihre Meinung zu unserer Lösung zu teilen.