Jak najlepiej reprezentować "cykliczne wydarzenia" w bazie danych?

Próbuję stworzyć aplikację zdarzeń zależną od harmonogramu i kalendarza w C#, dla której kluczowym wymogiem jest reprezentowanie powtarzających się zdarzeń w bazie danych. Jak najlepiej reprezentować powtarzające się wydarzenia w bazie danych?

Więcej Szczegółów:

Podczas tworzenia zdarzenia wysyłam również zaproszenia do określonych użytkowników i zaproszeni powinni mieć możliwość logowania się na spotkanie tylko w określonym oknie (czas trwania spotkania) lub mogą odmówić logowania, gdy zapraszający próbuje się zalogować na 5 minut przed planowanym rozpoczęciem spotkania.

Author: Varma, 2009-10-16

6 answers

The sysjobs, sysjobsschedule i sysschedules tabele w SQL Server robią całkiem dobrą robotę. Nie wymyślałbym koła na nowo, tylko skopiowałbym ich projekt.

Oto kilka ważnych pól z sysschedules

Freq_type

Jak często praca działa w tym harmonogramie.

1 = tylko jeden raz

4 = codziennie

8 = tygodniowy

16 = miesięczny

32 = miesięcznie, relative to freq_interval

64 = uruchamia się po uruchomieniu usługi SQL Server Agent

128 = uruchamia się, gdy komputer jest bezczynny

Freq_interval

Dni wykonania zadania. Zależy od wartości freq_type. Domyślną wartością jest 0, co oznacza, że freq_interval jest nieużywany. Wartość efektu freq_type na freq_interval

1 (raz) freq_interval jest nieużywany (0)

4 (Codziennie) Co dni freq_interval

8 (tygodniowy) freq_interval jest jednym lub więcej z następujących: 1 = niedziela 2 = poniedziałek 4 = wtorek 8 = środa 16 = czwartek 32 = piątek 64 = Sobota

16 (miesięcznie) w dniu freq_interval miesiąca

32 (miesięczny, względny) freq_interval jest jedną z następujących wartości: 1 = niedziela 2 = poniedziałek 3 = wtorek 4 = środa 5 = czwartek 6 = piątek 7 = sobota 8 = dzień 9 = dzień powszedni 10 = Dzień weekendowy

64 (uruchamia się po uruchomieniu usługi SQL Server Agent) freq_interval jest nieużywany (0)

128 (uruchamia się, gdy komputer jest bezczynny) freq_interval jest nieużywany (0)

Freq_subday_type

Jednostki dla freq_subday_interval. Może być jedną z następujących wartości: Opis wartości (Jednostka)

1 w określonym czasie

2 sekundy

4 minuty

8 godzin

Freq_subday_interval

Liczba okresów freq_subday_type występujących pomiędzy każdym wykonanie zadania.

Freq_relative_interval

Gdy freq_interval występuje w każdym miesiącu, jeśli freq_interval wynosi 32 (względny miesięcznie). Może być jedną z następujących wartości:

0 = freq_relative_interval jest nieużywany

1 = Pierwszy

2 = Drugi

4 = trzeci

8 = czwarty

16 = ostatni

Freq_recurrence_factor

Liczba tygodni lub miesięcy pomiędzy zaplanowanym wykonaniem zadania. freq_recurrence_factor jest używany tylko wtedy, gdy freq_type wynosi 8, 16 lub 32. Jeśli ta kolumna zawiera 0, to freq_recurrence_factor jest nieużywany.

 38
Author: Bob,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-16 18:41:12

Cóż, aby zapisać samą regułę powtarzania, możesz użyć wyciętej wersji RFC 5545 (i naprawdę sugeruję, abyś mocno ją przyciął). Oprócz czegokolwiek innego, to ułatwi eksport do innych aplikacji, Jeśli chcesz.

Po podjęciu tej decyzji, po stronie bazy danych musisz ustalić, czy chcesz przechowywać każde wystąpienie zdarzenia, czy tylko jeden rekord dla powtarzającego się zdarzenia, rozszerzając go w miarę potrzeby. Oczywiście znacznie łatwiej jest odpytywać bazę danych, gdy masz już wszystko rozszerzone - ale to sprawia, że trudniejsze w utrzymaniu.

Chyba, że masz ochotę napisać dość skomplikowany SQL, który może być trudny do przetestowania (i będziesz chciał dużo testów jednostkowych dla wszystkich rodzajów przypadków narożnych) sugerowałbym, abyś zrobił samą bazę danych stosunkowo "głupią" i napisał większość logiki biznesowej w języku takim jak Java lub C# - z których każdy może być osadzony w przechowywanych procedury w zależności od bazy danych, oczywiście.

Kolejną rzeczą, którą musisz sobie zadać, jest to, czy musisz radzić sobie z wyjątkami do zdarzeń - jedno zdarzenie w serii zmieniające czas/lokalizację itp.

Mam pewne doświadczenie z kalendarzem (spędziłem większość ostatniego roku pracując nad bitem kalendarza Google Sync za pośrednictwem ActiveSync) i ostrzegam, że sprawy szybko się komplikują naprawdę. Wszystko, co możesz uznać za "poza zasięgiem", jest błogosławieństwem. W szczególności, czy musisz pracować w wielu strefach czasowych?

I na koniec - bądź bardzo, bardzo ostrożny, gdy robisz arytmetykę z operacjami kalendarza. Jeśli zamierzasz używać Javy, proszę użyj Joda Time zamiast wbudowanego Calendar/Date klasy. Bardzo ci pomogą.
 24
Author: Jon Skeet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-01 16:11:07

Przyjęta tutaj odpowiedź jest zbyt zawiła. Na przykład, jeśli zdarzenie występuje co 5 dni, 5 jest przechowywane w freq_interval, ale jeśli występuje co 5 tygodni, 5 jest przechowywane w freq_recurrence. Największym problemem jest to, że freq_interval oznacza trzy różne rzeczy w zależności od wartości freq_type(liczba dni między wystąpieniami dla nawrotu dziennego, dzień miesiąca dla nawrotu miesięcznego lub dni tygodnia dla cotygodniowego lub miesięcznego względnego). Również 1,2,4,8... Sekwencja typu to używany, gdy jest niepotrzebny i mniej niż pomocny. Na przykład, freq_relative_interval może być tylko "jedną z" możliwych wartości. Jest to linia z rozwijanym polem lub wpisem typu przycisku radiowego, a nie wpisem typu checkbox, w którym można wybrać wiele opcji. Dla kodowania i dla czytelności człowieka ta sekwencja wchodzi w drogę i po prostu używa 1,2,3,4... jest prostszy, bardziej wydajny, bardziej odpowiedni. Wreszcie, większość aplikacji kalendarza nie potrzebuje interwałów dnia (zdarzeń występujących wiele razy w ciągu dnia - co tyle sekund, minut lub godzin).
Ale, powiedziawszy to, ta odpowiedź pomogła mi udoskonalić moje myśli na temat tego, jak to robię. Po wymieszaniu i dopasowaniu go do innych artykułów i przejściu z tego, co widzę w interfejsie kalendarza Outlooka i kilku innych źródłach, wymyślam to: {]}

Recurs
0 = brak nawrotu
1 = dzienny
2 = tygodniowy
3 = miesięczne

Recurs_interval
tyle jest okresów pomiędzy nawroty. Jeśli zdarzenie powtarza się co 5 dni, będzie miało 5, a powtarza się {[2] } będzie miało 1. Jeśli zdarzenie powtarza się co 2 tygodnie, będzie miało 2, a powtarza się będzie miało 2.

Recurs_day
Jeśli użytkownik wybrał Typ miesięczny, w danym dniu miesiąca (np. 10 lub 14). To jest ta data. Wartością jest 0, jeżeli użytkownik nie wybrał powtarzania miesięcznego lub określonego dnia miesiąca. Wartość od 1 do 31 inaczej.

Recurs_ordinal
jeśli użytkownik wybrał Typ miesięczny, ale porządkowy Typ dnia (np.: pierwszy poniedziałek, drugi czwartek, ostatni piątek). To będzie miało numer porządkowy. Wartością jest 0 jeżeli użytkownik nie wybrał tego typu powtarzania.
1 = pierwszy
2 = second
3 = Trzeci
4 = czwarty
5 = Ostatni

Recurs_weekdays
w przypadku nawrotów tygodniowych i miesięcznych zapisuje się Dni powszednie, w których nawrót zdarza się. 1 = Niedziela
2 = poniedziałek
4 = wtorek
8 = środa
16 = czwartek
32 = piątek
64 = Sobota

Przykłady:
Tak więc, co 4 tygodnie w sobotę i niedzielę będzie

  • powtarzanie = 2 = = > powtarzanie cotygodniowe
  • recurs_interval = 4 = = > CO 4 tygodnie
  • recurs_weekdays = 65 = = >(sobota=64 + niedziela=1)
  • recurs_day i recurs_ordinal = 0 = = > nie używane

Podobnie, co 6 miesięcy w pierwszy piątek miesiąca będzie

  • nawroty = 3 = = > nawroty Miesięczne
  • recurs_interval = 6 = = > co 6 miesiące
  • recurs_ordinal = 1 = = > przy pierwszym wystąpieniu
  • recurs_weekdays = 32 = = > of Friday

Nie chodzi o posiadanie pola, które oznacza trzy zupełnie różne rzeczy w zależności od wartości innego pola.

Po stronie interfejsu użytkownika pozwalam użytkownikowi określić datę, czas rozpoczęcia, Czas zakończenia. Następnie mogą określić, czy chcą mieć typ powtarzania inny niż none. Jeśli tak, aplikacja rozszerza odpowiednią sekcję strony internetowej, aby dać użytkownikowi opcje wymagane dla rzeczy powyżej, wyglądając podobnie jak Opcje programu Outlook, z wyjątkiem tego, że nie ma "każdego dnia tygodnia" w ramach powtarzania dziennego (który jest zbędny z powtarzaniem tygodniowym w każdym Pon-Pt), i nie ma powtarzania rocznego. Jeśli jest powtarzanie to wymagam również od użytkownika podania daty końcowej, która jest w ciągu jednego roku od dnia dzisiejszego (użytkownicy chcą tego w ten sposób, a to upraszcza mój kod) - nie robię niekończącego się powtarzania lub " end after # # occurrences."

Przechowuję te pola z selekcjami użytkownika w mojej tabeli zdarzeń i rozwijam je w tabeli harmonogramu, która zawiera wszystkie zdarzenia. Ułatwia to Wykrywanie kolizji (w rzeczywistości robię aplikację rezerwacji obiektu) i edycję pojedynczych zdarzeń lub refaktoryzację przyszłych zdarzeń.

Moi użytkownicy są wszyscy w CST, i dziękuję dobry Boże. Jest to na razie pomocne uproszczenie, a jeśli w przyszłości baza użytkowników będzie się rozszerzać, to mogę dowiedzieć się, jak sobie z tym poradzić, jako dobrze oddzielone zadanie.

UPDATE Od kiedy pierwszy raz to napisałem, dodałem "every weekday". Nasi użytkownicy mieli trochę trudności z myśleniem, że możesz użyć cotygodniowego nawrotu Dla wydarzeń odbywających się od czwartku jednego tygodnia do wtorku następnego tygodnia i tylko w dni powszednie. Informatyka było bardziej intuicyjne dla nich, aby to mieć, nawet jeśli istnieje już inny sposób, że mogą to zrobić.

 6
Author: AgapwIesu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-20 23:27:15

Też o tym myślałem, chociaż nie wdrożyłem go, ale to są moje przemyślenia na proste rozwiązanie.

Podczas konfigurowania zdarzenia powtarzającego się, Poproś użytkownika o określenie "daty zakończenia" i utworzenie pojedynczych zdarzeń dla każdego z nich (w oparciu o opcje powtarzające się). Ponieważ jest to powtarzające się wydarzenie, Ustaw unikalny "powtarzający się identyfikator" dla każdego z nich. Ten identyfikator będzie następnie używany do oznaczania zdarzenia jako powtarzające się, a jeśli zmienisz Zdarzenie przyszłe, możesz poprosić Użytkownika o zastosowanie tego do reszty przyszłych zdarzeń poprzez usunięcie i odtworzenie powtarzających się zdarzeń z nowym "powtarzającym się ID", które również odróżni to powtarzające się Zdarzenie od poprzednich, które się zmieniły.

Mam nadzieję, że to ma sens i chciałbym mieć jakieś komentarze.

 0
Author: Mark Redman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-16 18:44:57

Zapisałbym powtarzające się wydarzenia jako dwie różne rzeczy w bazie danych. Przede wszystkim w tabeli zdarzeń zapisuje się każde zdarzenie. Po drugie, miej tabelę recurrences, w której zapisujesz szczegóły, o które prosisz, aby skonfigurować Zdarzenie powtarzające się. Data rozpoczęcia, częstotliwość, liczba wystąpień itp.

Wtedy możesz pomyśleć o powiązaniu tego wszystkiego razem, umieszczając PK powtórzeń w każdym zapisie zdarzenia jako FK. Ale lepszym projektem byłoby normalizacja tabela event w dwóch tabelach, jeden, który jest tylko barebones zdarzenia, i jeden, który ma szczegóły, które mogą być teraz odnoszące się do wielu wydarzeń. W ten sposób każdy rekord zdarzenia, powtarzający się lub nie, ma FK do PK tabeli eventdetails. Następnie w eventdetails, Nagraj PK powtórzeń gdzieś razem z agendą, zaproszonymi itp. Rekord nawrotów niczego nie napędza. Na przykład, jeśli chcesz wyświetlić listę wszystkich powtarzających się wydarzeń, przejrzyj wiadomości eventdetails dla wszystkich wydarzeń z NULL FK do nawrotów.

Musisz uważać, aby zsynchronizować wszystkie te rzeczy, aby wstawiać lub usuwać zdarzenia, gdy dane powtarzania ulegną zmianie.

 0
Author: Michael Dillon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-16 21:00:58

"poza wszystkim"

Czy dotyczy to "samych wymagań"?

", które ułatwią eksport do innych aplikacji, Jeśli chcesz."

Czy podane wymagania zawierają "eksport kalendarzy do innych aplikacji musi być łatwy"? Odnoszę wrażenie, że problem polegał wyłącznie na zbudowaniu pierwszej APLIKACJI.

To moja własna odpowiedź:

Musisz ograniczyć siebie/swojego użytkownika na rodzajach "recurrency" Twój system będzie w stanie obsługiwać. A "wszystkie powyższe "lub" brak ograniczeń " nie będzie poprawną odpowiedzią, jeśli ty / twój użytkownik chce(y) skończyć z użyteczną aplikacją.

 -4
Author: Erwin Smout,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-16 21:12:37