Design del tavolo per le vacanze

3

Sto creando un sistema per archiviare vacanze ed eventi. Ho una conoscenza di base dello schema per le date statiche (ad esempio, ogni 23 marzo).

Il mio problema sta nelle relative date (ad esempio: ogni 3 venerdì di marzo).

Per le date statiche possiamo tranquillamente avere uno schema che assomiglia a questo:

+----------+--------------+
| Col Name |     Type     |
+----------+--------------+
| Id       | Int          |
| Name     | varchar(255) |
| Month    | Int          |
| Day      | Int          |
+----------+--------------+

Come sarebbe possibile aggiungere le date relative in questo schema?

    
posta Erick 29.06.2015 - 04:55
fonte

3 risposte

3

Quello che hai non è abbastanza flessibile.

Le esigenze di base sono che devi essere in grado di esprimere per es. il seguente:

  • U.S.. Il Memorial Day è l'ultimo lunedì di maggio.
  • U.S.. Il Ringraziamento è il quarto giovedì di novembre.
  • Natale è il 25 dicembre.
  • La Pasqua è ... forse solo raschiare Wikipedia ?

Un modo semplice per esprimere questo è aggiungere campi per i possibili modi per definire le vacanze:

  • Mese
  • Giorno della settimana
  • Settimana del mese (usa il negativo per contare all'indietro per esempio Memorial Day)
  • Giorno del mese

Questo non è l'ideale, perché puoi inserire facilmente dati non validi (ad esempio lunedì, prima settimana e 25 ° giorno), ma è semplice e facile da capire .

Ci sono altri modi per definire le vacanze che ho visto altrove, ma in pratica richiedono l'implementazione di un motore delle regole che è molto complesso e facile da abusare. Questi behemoth hanno una cattiva reputazione che è meritata, ma a volte sono davvero lo strumento migliore per il lavoro.

    
risposta data 29.06.2015 - 05:42
fonte
2

Hai una vacanza e le informazioni di base su di essa.

Holiday:
  holidayId (pk)
  name

Che tipo di vacanze abbiamo? Ci sono le vacanze fisse, le vacanze in movimento e le vacanze "Non ho intenzione di disturbare il calcolo" (Pasqua, ti sto guardando).

Per questo, avresti dei sottotitoli.

Ci sono le vacanze fisse e ripetute. Cose come il Natale e il prossimo luglio. Queste sono festività che cadono lo stesso giorno del mese ogni anno.

FixedHoliday
  FixedHoldiayId (pk)
  HolidayId (fk)
  MonthOfYear
  DayOfMonth

Allora hai anche i mobili. Festa del lavoro (primo lunedì di settembre), Giornata della memoria (lo scorso lunedì di maggio), Ringraziamento (giovedì di novembre).

Il modo più semplice per avvicinarti è dare un giorno intervallo per il giorno.

MoveableHoliday
  MoveableHoldaiYid (pk)
  HolidayId (fk)
  MonthOfYear 
  DayOfWeek
  EarliestDay
  LatestDay

Se il tuo database supporta un tipo di intervallo potresti volerlo usare. Non tutti lo fanno, e quindi l'approccio a due date.

Perché due giorni? Diamo un'occhiata al Labor day. Il primo che può essere è il 1 settembre st - se il lunedì cade sul primo. L'ultimo che il primo lunedì può cadere è il 6 settembre th . Lunedì 7 settembre th significherebbe che il 1 settembre st era un lunedì ed era il Labor Day.

Per il Memorial Day, l'ultimo lunedì di maggio (che ha 31 giorni), l'intervallo per le date valide è il 25 th attraverso il 31 st .

Alcune righe di esempio:

MoveableHoliday | Labor | Memorial | Thanksgiving
  MonthOfYear   | Sep   | May      | Nov
  DayOfWeek     | Mon   | Mon      | Thurs
  EarliestDay   | 1     | 25       | 22
  LatestDay     | 6     | 31       | 28

Questo ci porta all'approccio "Non ho intenzione di calcolare quello" - è la prima domenica dopo la prima luna piena che si verifica dopo il 21 st di marzo ... e sì Se ci si è veramente scavati dentro, si potrebbe scrivere una stored procedure che contiene il calcolo per la luna piena (o averla in un'altra tabella, ancora una volta, che ha bisogno di popolare quella tabella), oppure si può semplicemente dì "non ce ne sono abbastanza per davvero fare la differenza " e basta popolarlo.

Questo è molto simile alla vacanza fissa, tranne che è solo per un anno.

SpecificDayHoliday
  SpecificDayHolidayId (pk)
  HolidayId (fk)
  MonthOfYear
  DayOfMonth
  Year

A questo punto, compila il tavolo come vuoi per quanto lontano vuoi.

Ora puoi mettere insieme le tabelle SpecificDayHoliday e FixedHoldiay e rendere Anno opzionale. Tuttavia, ritengo che ciò renda più facile lavorare con ogni tabella - ognuno di essi ha un singolo tipo di valore che va dentro di essi. In particolare, SpecificDayHoliday consente a più valori HolidayID di essere uguali nella tabella. FixedHoliday e MoveableHoliday devono avere un vincolo sulla tabella che rende HolidayId univoco all'interno della tabella.

    
risposta data 29.06.2015 - 06:09
fonte
0

Ho capito che è meglio memorizzare il conteggio del giorno su cui si trova l'evento / la festa. Ho dato un'occhiata al compleanno del Queens in Australia e ogni due lunedì di giugno, non si sposta al mese successivo. Per la maggior parte dell'Australia accetti l'Australia occidentale che è il compleanno della regina. nell'Australia occidentale il giorno della nascita della regina è ogni 5 ° lunedì di settembre, ma a volte cade anche a ottobre.

Osservando il tuo problema, penso che sarebbe un motivo per memorizzare il conteggio del giorno di cui la festività è destinata a cadere dato un mese base. Se il mese di base viene superato, passa al mese successivo e continua il conteggio.

    
risposta data 29.06.2015 - 05:44
fonte

Leggi altre domande sui tag