sql >> Databasteknik >  >> RDS >> Database

Igen och igen! Hantera återkommande händelser i en datamodell

En återkommande händelse är per definition en händelse som återkommer med ett intervall; det kallas också en periodisk händelse. Det finns många applikationer som låter sina användare ställa in återkommande händelser. Hur hanterar ett databassystem återkommande händelser? I den här artikeln kommer vi att utforska ett sätt att hantera dem på.

Återkommande är inte lätt för ansökningar att hantera. Det kan bli en orkanuppgift, särskilt när det gäller att täcka alla möjliga återkommande scenarion – inklusive att skapa evenemang varannan vecka eller kvartalsvis eller tillåta omschemaläggning av alla framtida händelser.

Två sätt att hantera återkommande händelser

Jag kan tänka mig minst två sätt att hantera periodiska uppgifter i en datamodell. Innan vi diskuterar dem, låt oss snabbt gå igenom kraven för denna uppgift. I ett nötskal betyder effektiv förvaltning:

  • Användare får skapa regelbundna och återkommande evenemang.
  • Dagliga, veckovisa, varannan vecka, månadsvisa, kvartalsvisa, vartannat år och årliga evenemang kan skapas utan begränsningar för slutdatum.
  • Användare kan schemalägga eller avbryta en instans av en händelse eller alla framtida instanser av en händelse.

Med tanke på dessa parametrar kommer två sätt att hantera återkommande händelser i datamodellen att tänka på. Vi kommer att kalla dem för det naiva och expertsättet.

Det naiva sättet: Lagra alla möjliga återkommande instanser av en händelse som separata rader i en tabell. I den här lösningen kräver vi bara en tabell, nämligen event . Den här tabellen har kolumner som event_title , startdatum , slutdatum , is_full_day_event , etc. startdatum och slutdatum kolumner är tidsstämpeldatatyper; på så sätt kan de ta emot händelser som inte varar hela dagen.

Proffsen: Detta är ett ganska okomplicerat tillvägagångssätt och det enklaste att implementera.

Nackdelarna: Det naiva sättet har några betydande nackdelar, inklusive:

  • Behovet av att lagra alla möjliga instanser av en händelse. Om du tar hänsyn till en stor användarbas krävs en stor bit utrymme. Utrymmet är dock ganska billigt, så denna punkt har ingen större inverkan.
  • En mycket rörig uppdateringsprocess. Anta att en händelse är omplanerad. I så fall måste någon uppdatera alla instanser av det. Ett stort antal DML-operationer måste utföras vid omläggning, vilket skapar en negativ inverkan på applikationsprestanda.
  • Hantering av undantag. Alla undantag måste hanteras graciöst, speciellt om du måste gå tillbaka och redigera det ursprungliga mötet efter att ha gjort ett undantag. Anta till exempel att du flyttar den tredje instansen av en återkommande händelse framåt med en dag. Vad händer om du senare redigerar tidpunkten för den ursprungliga händelsen? Infogar du en annan händelse på den ursprungliga dagen och lämnar den du flyttade fram? Ta bort länken till undantaget? Försök att ändra det på lämpligt sätt?
  • Expertens sätt: Lagra ett återkommande mönster och generera tidigare och framtida händelseförekomster programmatiskt. Denna lösning tar upp nackdelarna med den naiva lösningen. Vi kommer att förklara expertlösningen i detalj i den här artikeln.

    Den föreslagna modellen




    Skapa evenemang

    Alla schemalagda händelser, oavsett deras regelbundna eller återkommande karaktär, loggas i händelsen tabell. Alla händelser är inte återkommande händelser, så vi behöver en flaggkolumn, is_recurring , i den här tabellen för att explicit specificera återkommande händelser. event_title och event_description kolumner lagrar ämnet och en kort sammanfattning av händelser. Händelsebeskrivningar är valfria, vilket är anledningen till att den här kolumnen är nullbar.

    Som deras namn antyder, start_date och slutdatum kolumner håller start- och slutdatum för händelser. Vid vanliga händelser lagrar dessa kolumner faktiska start- och slutdatum. Men de lagrar också datumen för de första och sista förekomsterna av periodiska händelser. Vi behåller end_date kolumnen som null, eftersom användare kan konfigurera återkommande händelser utan slutdatum. I det här fallet skulle framtida händelser fram till ett hypotetiskt slutdatum (säg ett år) visas i användargränssnittet.

    is_full_date_event kolumn anger om en händelse är en heldagshändelse. I fallet med en heldagshändelse, start_time och sluttid kolumner skulle vara null; det är anledningen till att hålla båda dessa kolumner nullbara.

    created_by och created_date kolumner lagrar vilken användare som skapade en händelse och datumet då händelsen skapades.

    Därefter är det parent_event_id kolumn. Detta spelar en stor roll i vår datamodell. Jag kommer att förklara dess betydelse senare.

    Hantera upprepningar

    Nu kommer vi direkt till huvudproblemformuleringen:Vad händer om en återkommande händelse skapas i event tabell – det vill säga är_återkommande flaggan för händelsen är "Y"?

    Som förklarats tidigare kommer vi att lagra ett återkommande mönster för händelser så att vi kan konstruera alla dess framtida händelser. Låt oss börja med att skapa recurring_pattern tabell. Den här tabellen har följande kolumner:

    • Event_id – Den här kolumnen är hänvisad från event tabell, och den fungerar som den primära nyckeln i den här tabellen. Den visar det identifierande förhållandet mellan händelse och recurring_pattern tabeller. Den här kolumnen säkerställer också att det finns maximalt ett återkommande mönster för varje händelse.
    • Återkommande_typ-id – Den här kolumnen anger typen av återkommande, oavsett om det är dagligen, veckovis, månadsvis eller årligen.
    • Max_antal_of_occurrances – Det finns tillfällen då vi inte vet det exakta slutdatumet för en händelse men vi vet hur många händelser (möten) som krävs för att slutföra det. Den här kolumnen lagrar ett godtyckligt nummer som definierar det logiska slutet för en händelse.
    • Separation_count – Du kanske undrar hur en händelse varannan vecka eller två gånger om året kan konfigureras om det bara finns fyra möjliga värden av återfallstyp (dagligen, veckovis, månadsvis, årligen). Svaret är separation_count kolumn. Den här kolumnen anger intervallet (i dagar, veckor eller månader) innan nästa händelseinstans tillåts. Till exempel, om en händelse behöver konfigureras för varannan vecka, då separation_count =“1” för att uppfylla detta krav. Standardvärdet för denna kolumn är "0".

    Låt oss överväga betydelsen av de återstående kolumnerna i termer av de olika typerna av återkommande.

    Dagliga återkommande

    Behöver vi verkligen fånga ett mönster för en dagligt återkommande händelse? Nej, eftersom alla detaljer som krävs för att generera ett dagligt återkommande mönster redan är inloggade i händelsen bord.

    Det enda scenariot som kräver ett mönster är när händelser är schemalagda för alternativa dagar eller vart X antal dagar. I det här fallet, separation_count kolumnen hjälper oss att förstå återkommande mönster och härleda ytterligare instanser.

    Veckovis återkommande

    Vi kräver bara en extra kolumn, day_of_week , för att lagra vilken veckodag detta evenemang kommer att äga rum. Om man antar att måndag är den första dagen i veckan och söndag är den sista, skulle möjliga värden vara 1,2,3,4,5,6 och 7. Lämpliga ändringar i koden som genererar enskilda händelser bör göras vid behov. Alla återstående kolumner skulle vara null för veckohändelser.

    Låt oss ta en klassisk typ av veckohändelse:händelsen varannan vecka. I det här fallet säger vi att det händer varannan vecka på en tisdag, den andra dagen i veckan. Så:

    • Det recurring_type_id skulle vara "veckovis".
    • separation_count skulle vara "1".
    • veckodagen skulle vara "2".

    Månatlig återkommande

    Förutom day_of_week , kräver vi ytterligare två kolumner för att möta alla månatliga återkommande scenarion. I korthet är dessa kolumner:

    • Vecka_i_månaden – Den här kolumnen är för händelser som är schemalagda för en viss vecka i månaden – dvs den första, andra, sista, näst sista, etc. Vi kan lagra dessa värden som 1,2,3, 4,.. (räknat från början av månaden) eller -1,-2,-3,... (räknat från slutet av månaden).
    • Dag_i_månaden – Det finns fall då en händelse är schemalagd på en viss dag i månaden, säg den 25:e. Denna kolumn uppfyller detta krav. Som vecka_i_månad , kan den fyllas i med positiva siffror ( "7" för den 7:e dagen från början av månaden) eller negativa siffror ( "-7" för den sjunde dagen från slutet av månaden).

    Låt oss nu överväga ett mer komplicerat exempel - en kvartalshändelse. Anta att ett företag schemalägger en kvartalsvis resultatprognose för den 11 dagen i den första månaden i varje kvartal (vanligtvis januari, april, juli och oktober). Så i det här fallet:

    • Det recurring_type_id skulle vara "månadsvis".
    • separation_count skulle vara "2".
    • dagen_i_månaden skulle vara "11".
    • Alla återstående kolumner skulle vara null.

    I exemplet ovan antar vi att användaren skapar den kvartalsvisa resultatprognosen i januari. Observera att denna separationslogik börjar räknas från månaden, veckan eller dagen då händelsen skapas.

    På liknande rader kan halvårshändelser loggas som månatliga händelser med en separation_count av "5".

    Årligt återkommande

    Årliga återkommande är ganska okomplicerat. Vi har kolumner för särskilda veckodagar och månad, så vi behöver bara en extra kolumn för månaden på året. Vi har döpt den här kolumnen till månad_i_år .

    Hantera undantag från återkommande händelser

    Låt oss nu komma till undantagen. Vad händer om en viss instans av en återkommande händelse ställs in eller omplaneras? Alla sådana instanser loggas separat i event_instance_exception tabell.

    Låt oss ta en titt på två kolumner, Is_rescheduled och is_cancelled . Dessa kolumner anger om den här instansen är omplanerad till något senare datum/tid eller avbryts helt. Varför har jag två separata kolumner för detta? Tja, tänk bara på evenemang som först schemalagts och sedan ställdes in helt. Detta händer, och vi har ett sätt att spela in det med dessa kolumner.

    Förutom dessa två kolumner fungerar alla återstående kolumner på samma sätt som i händelsen bord.

    Varför länka två händelser med hjälp av parent_event_id ?

    Det finns applikationer som tillåter användare att schemalägga alla framtida instanser av en återkommande händelse. I sådana fall har vi två alternativ. Vi kan lagra alla framtida instanser i event_instance_exception (tips:inte en acceptabel lösning). Eller så kan vi skapa en ny händelse med nya datum-/tidsparametrar i händelse tabellen och länka den till dess tidigare händelse (den överordnade händelsen) med hjälp av id_parent_event kolumn.

    Med denna lösning kan vi få alla tidigare förekomster av en händelse, även när dess återkommande mönster har ändrats.

    Hur förbättrar man hanteringen av återkommande händelser?

    Det finns några mer komplexa områden kring återkommande händelser som vi inte har diskuterat. Här är två:

    • Händelser som inträffar på helgdagar. När ett särskilt fall av en händelse inträffar på en allmän helgdag, bör den automatiskt flyttas till arbetsdagen omedelbart efter helgdagen? Eller ska det avbrytas automatiskt? Under vilka omständigheter skulle någon av dessa gälla?
    • Konflikter mellan händelser. Vad händer om vissa händelser (som utesluter varandra) inträffar samma dag?

    Vilka förändringar behöver vi göra för att bygga in dessa förmågor? Berätta för oss dina åsikter i kommentarsektionen.


  1. Hantera roller och statusar i ett system

  2. När indexerar Oracle kolumnvärden null?

  3. Hur man subtraherar minuter från ett Datetime-värde i MariaDB

  4. Hur gör man arvsmodellering i relationsdatabaser?