Database
 sql >> база данни >  >> RDS >> Database

Разглеждане на празници с очите на модела на данни

Празненство!! Време за семейството!! Дълъг път!! Един ден на плажа!! Всички тези думи се появяват в съзнанието ни, когато мислим за празници. Замисляли ли сте се как една мултинационална компания следи празниците по целия свят? Трябва да има речник с данни, който да поддържа всички тези подробности, така че да могат да осигурят безпроблемен бизнес с местните си партньори.

Тази статия ще обясни такъв модел на данни.

Изисквания на проекта накратко

Този път имам доста прости и ясни изисквания. Трябва да създам речник с данни за празници в много страни. Искам да го изградя като компонент, който може да бъде интегриран в основния модел на данни, когато и където е необходимо.

За някои интересни факти за празниците в различни страни

По отношение на изискванията на проекта, това е един от най-простите проблеми при моделирането на данни. И все пак е достатъчно трудно да се проектира модел на данни за него. Обикновено празниците падат на определена дата всяка година, но това не е така за всеки празник във всяка страна. Ако анализираме празниците в различни страни, можем лесно да предвидим усложненията, свързани с този дизайн на модела на данни.

Нека да разгледаме някои интересни факти за празниците в различни страни:

  • Много празници, особено патриотични, се отбелязват на определена дата всяка година.

    Пример:

    Денят на независимостта в САЩ и Индия се чества съответно на 4 юли и 15 август.

  • Някои празници се празнуват на определен ден всяка година – но не винаги на една и съща календарна дата.

    Пример:

    Денят на благодарността в САЩ се празнува на 4 четвъртък на ноември. Миналата година (2015 г.) това падна на 26 ноември; тази година ще бъде 24 ноември.

  • Някои празници се празнуват на определена дата в годината, но ако датата пада в събота или неделя, празникът нарочно се измества към следващия понеделник, за да се спазва дълъг уикенд. Такъв празник понякога се нарича „Понеделник“ .

    Примери:

    В Австралия и Нова Зеландия денят на ANZAC се празнува на 6 февруари, но ако тази дата падне в събота или неделя, празникът се отбелязва в понеделник ден или два по-късно.

    Друг добър пример е Денят на труда в Китай. Този празник също е „понеделник“.

  • Датите на някои празници се изместват със седмица, ако се сблъскват с друг празник.

    Пример:

    Денят на семейството и общността в Австралия се празнува в първия понеделник на октомври, но ако Денят на труда се пада и на първия понеделник, тогава Денят на семейството се измества към втория понеделник на октомври.

  • Не всички празници се спазват като банкови празници т.е. празници, когато банките, финансовите институти, фондовите пазари и държавните служби са затворени. (В САЩ и Канада банковите празници са известни като федерални или законови празници.)
  • Патриотичните празници се спазват стриктно на една и съща дата всяка година. В този ден са затворени всички институти и офиси (включително банки) във всички региони на страната. Въпреки това, в някои страни, като САЩ и Канада, ако тези празници попадат в уикенда, те ще се спазват и на следващия понеделник – тоест банките и държавните служби ще бъдат затворени в този понеделник.
  • Празниците с едно и също име се отбелязват в различни дни в различните страни.

    Пример:

    Денят на труда се отбелязва на 1 май в Индия, докато в Канада се отбелязва на първия понеделник на септември.

  • Някои празнични почивни дни традиционно се съчетават с непразнични дни.

    Пример:

    Денят на труда в Китай и Южна Африка се отбелязва в един ден, но са включени два други почивни дни.

  • Други дни, макар и технически да не са празници, обикновено се допускат като неработни дни.

    Пример:

    В САЩ петъкът след Деня на благодарността е неофициално известен като Черен петък. Това не е правителствен празник, но много компании дават на служителите си почивен ден.

  • Някои празници се наблюдават по различен начин в различните региони в рамките на една държава.

    Пример:

    Лятна банкова ваканция в Обединеното кралство се празнува в първия понеделник на август в Шотландия, но същият празник се отбелязва в последния понеделник на август в Англия, Гърнси, Джърси, Северна Ирландия и Уелс.

  • Определени регионални или местни празници се отбелязват само в една част на страната. Те може да са свързани с религиозни, етнически или културни събития.

    Пример:

    Денят на Луис Риел се празнува само в канадската провинция Манитоба.

  • Някои дни за спазване на определени празници се основават на условие „преди“ или „след“.

    Примери:

    • Денят на националния патриот се отбелязва в канадската провинция Квебек в понеделник преди 25 май.
    • Денят на покаянието в Германия се отбелязва в сряда непосредствено преди 23 ноември.
    • Jeune Genevois в Швейцария се наблюдава в четвъртък следващия първата неделя на септември.
  • Някои празнични дни се основават на по-стари календари, които не съответстват на често използвания григориански календар. Следователно датите им варират всяка година.

    Примери:

    • Великден се празнува в първата неделя след пълнолунието на или най-скоро след 21 март.
    • Дивали (древен индуистки фестивал) се празнува в продължение на няколко дни, от края на индуисткия лунен месец Ашвин и началото на месец Картика. Обикновено това пада някъде между средата на октомври и средата на ноември според григорианския календар.
  • Православна Коледа – Това следва по-стария юлиански календар. От 2016 г. има разлика от 13 дни между юлианския и григорианския календар. В резултат на това православната Коледа се пада на 7 януари 2016 г.

Обобщаване на фактите

Важно е да се отбележи, че Обмислям само международно приетия григориански календар (който следва слънчевия цикъл) за автоматизиране на популацията от данни за празници за години и държави. В тази статия Не обмислям лунно-слънчеви, еврейски или индуистки календари (които следват лунния цикъл). Въпреки това, тези календари се следват в определени региони на земното кълбо. Засега празниците въз основа на тези календари могат да се подават в системата ръчно .

За да обобщим, празниците в различните държави могат да бъдат категоризирани въз основа на това как са получени техните дати:

  • Фиксирани празници – Празници, които се случват на определена дата всяка година.
  • Преместваеми празници – Празници, които се падат в определен ден, като първия понеделник на февруари или третия четвъртък на ноември.
  • Регулируеми празници – Празници, които попадат в някоя от категориите, но понякога се наблюдават в други дни, за да се избегне сблъсък с други празненства (или сблъсък с уикенда) или се преместват към следващата седмица поради сблъсък с друг празник на същата дата.
  • Празници въз основа на други календари – Празнични празници, които се основават на лунния, православния или индуисткия календар. Засега те се подават ръчно в нашия модел.

Освен това можем да разделим празниците в две категории въз основа на къде те се наблюдават:

  • Национални празници – Празници, които се спазват на ниво държава.
  • Регионални или местни празници – Празници, които се отбелязват в определен щат или регион на дадена страна.

В почти всички страни националните и регионалните празници се отбелязват като празници на национално или регионално ниво. Не всички празници обаче са официални, така че трябва да посочим кои празници са официални и кои не.

На този етап трябва да разгледаме и някои теоретични сценарии за конкретни бизнес области. Например:

  • В някои държави банките и други финансови институции получават почивен ден на първия ден от всяко тримесечие.
  • Някои организации дават почивен ден, след като публикуват тримесечните си резултати.

Ще се уверим, че тези точки също са включени в дизайна на нашия модел на данни.

Проектиране на изчерпателен модел на ваканционни данни

Докато проектирам модела на данни, ще използвам конвенцията на САЩ, че седмицата започва в неделя. Няма да е трудно да промените това по-късно, ако е необходимо.

Целият този модел на данни ще се върти около три предметни области:„Календар“, „Празник“ и „Държава“.

Тематичната област „Календар“

В тази област има основна таблица с име calendar който съхранява фурми в продължение на много години. Ще има и някои допълнителни колони за съхраняване на предварително изчислени числови стойности, които ще ни помогнат да изведем дати за определени подвижни празници. Колоните са както следва:

  • week_of_month
  • week_of_quarter
  • week_of_year
  • day_of_year
  • day_of_quarter

Има още две таблици в тази тематична област:day_of_week и month_of_year .

Както подсказват имената им, ние ще съхраняваме подробности за отделните дни и месеци в тези таблици. Следователно те винаги ще имат съответно 7 и 12 записа. Някои неща, които трябва да имате предвид за този раздел, са:

  • Можем да конфигурираме началото на седмицата с помощта на колона за последователност в двете таблици. Можем да направим същото с началото на годината.
  • Първичните ключове на двете таблици са посочени в calendar маса. Те съхраняват числови стойности за дните от седмицата и месеците от годината.
  • Стойността на годината може да бъде извлечена от calendar_date колона, но все още пазя calendar_year като отделна колона. Това ни позволява да разделим таблицата на тази колона, което от своя страна дава възможност за по-добра производителност за основните SQLs.
  • Размерът на числовите колони е определен въз основа на възможни стойности за колоната. Например day_of_year трябва да е някаква стойност между 1 и 365, така че дефинирам число(3) като тип данни на колоната.

Теманата област „Празник“

Както казахме преди, има два вида почивки – фиксирани и преместваеми. Така че ще създадем две различни таблици, по една за всеки тип.

holiday_fixed таблицата използва day_of_month и month_of_year_id колони за съхраняване на числови стойности за ден и месец. Използвайки тези стойности, можем да извлечем дата за фиксиран празник.

На подобни линии, holiday_moveable таблицата ще използва следните колони, за да изведе дата за всеки преместваем празник:

is_bank_holiday колона показва дали празникът е празничен ден, т.е. всички финансови институции са затворени в този ден. Тази колона е задължителна и в двете таблици.

is_mondayized колоната променя датата за празниците, които се падат в събота или неделя, но се спазват на следващия понеделник.

Нека също така създадем друга таблица, а именно holiday_miscellaneous , за съхраняване на записи за празници въз основа на негригориански календари. Записите ще бъдат вмъкнати в тази таблица ръчно.

Всички тези три таблици имат една колона, препращаща holiday_category маса. Това съдържа данни за естеството на празника. Тук може да има различни категории, включително:

  • Обществен/банков празник – Банките са официално затворени и не се търгуват.
  • Държавен празник – Официални празници само на държавно ниво.
  • Национален празник – Обикновено патриотичен юбилей или ден, определен от закона, който се отбелязва в цялата страна.
  • Местна почивка – Декларирано от местната власт и се наблюдава само в конкретен регион.
  • Спазване – Празници, които не се празнуват на действителните си дати, а в някой друг ден (често понеделник). Обикновено позволява на хората да имат тридневен уикенд.

Сигурно сте забелязали state_id колона и в трите празнични таблици. Нека поговорим за значението на тази колона в следващия раздел.

Предметната област „Държава“

Имаме две таблици в тази тематична област:

  1. country – който съхранява имена на държави и идентификационни номера;
  2. state – който съхранява имената и идентификаторите на щати и/или региони за всяка отделна държава.

В крайна сметка ще се позоваваме на това state таблица във всичките три празнични таблици, за да определите към кой регион, щат и държава принадлежи даден празник.

Тъй като много празници се празнуват на ниво държава, няма смисъл да се водят записи на държавно ниво за такива празници в holiday маса. Това би станало изключително излишно. Вместо това можем да имаме един запис в state таблица с „ВСИЧКИ“ като име на щат. Този запис може да бъде картографиран с всички празници на тази страна, като по този начин се елиминира необходимостта от водене на огромни записи в holiday таблица ненужно.

Окончателният модел на данните за празниците

Нека да разгледаме пълния модел на данни за празниците тук:




Има няколко начина, по които можем да си играем с този модел. Например:

  • Вземете списък с всички празници, наблюдавани в определена страна, да речем Полша.

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

  • Намерете датата за Деня на благодарността през 2018 г. – Не забравяйте, че това се празнува във всички щати на САЩ в четвъртия четвъртък на ноември.

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

  • Вземете списък с това кога се празнува Денят на независимостта във всички страни. Обикновено това е на определена дата всяка година и денят се спазва стриктно във всички райони на страната.

    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;
    

Използване на ваканционния модел на данни

Искате ли да поиграете с този модел на данни? Направи го. Ето само някои от запитванията, които измислихме:

  • Намерете датите, на които се отбелязва Денят на труда в различни държави.
  • Вземете списък с всички празници през 2016 г. за всяка част на Обединеното кралство.
  • Направете списък на всички празници, наблюдавани във Франция през 2016 г.
  • Вземете списъка с всички празници, наблюдавани в канадската провинция Манитоба през 2016 г.

Как успяхте да съхраните подробности за празниците в приложението си? Ще се радвам да чуя вашите идеи. Моля, не се колебайте да споделите опита си със съхраняването на тези метаданни, както и мнението си за нашето решение.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Първи стъпки с Cloud Firestore за iOS

  2. Съвети за заключвания за четене/запис в зависимост от нивото на изолация на транзакциите в MSSQL

  3. Как да използвате Prisma

  4. Интересни неща за тригерите ВМЕСТО

  5. SCD тип 1