2009-06-03 11 views
42

Ich möchte eine Kalenderanwendung schreiben. Es sind wirklich wiederkehrende Elemente, die einen Schlag in die Arbeit für das DB-Schema werfen. Ich würde gerne etwas dazu wissen, wie man das organisiert.Verteilen eines Datenbankschemas für eine Kalenderanwendung

Was passiert, wenn ein Benutzer ein Ereignis erstellt und Eingaben, die es jeden Montag wiederholt, für immer wiederholt? Wie kann ich all das in der Datenbank speichern? Ich kann keine unendlichen Ereignisse erstellen. Lege ich einfach einen Tisch hinein, der die relevanten Informationen enthält, damit ich berechnen kann, wohin alle Ereignisse gehen? Wenn ja, müsste ich sie jedes Mal berechnen, wenn der Benutzer einen neuen Teil des Kalenders sieht. Was ist, wenn sie die Monate durchblättern, aber sie haben eine Menge wiederkehrender Artikel?

Darüber hinaus muss das Schema behandelt werden, wenn ein Benutzer auf ein Element klickt und sagt "Bearbeiten Sie dieses in der Sequenz" nicht alle Elemente in der Sequenz. Teilt ich dann den einen Gegenstand von der Sequenz?

aktualisieren 1

Ich habe an iCal überhaupt nicht sah. Um es klar zu sagen, ich denke, die Informationen speichern, mit denen Sie die wiederkehrenden Elemente berechnen können, und die Trennung von allen, die sich von der Reihenfolge unterscheiden, ist eine gute Möglichkeit, es zu speichern, um es übertragen zu können. Aber ich denke, dass das in einer Anwendung zu langsam wäre, um die Datums-Mathematik überall zu machen.

+1

"Teilt ich den einen Gegenstand aus der Sequenz?" Ich glaube, so behandelt das iCal-Dateiformat es. Hast du dieses Format überhaupt studiert? –

+1

Was für eine ausgezeichnete Frage, ich habe mich das neulich gefragt. –

Antwort

12

Ich habe vor kurzem eine Kalenderanwendung erstellt und dies war eine der vielen Herausforderungen, denen ich gegenüberstand.

Ich kam schließlich mit einer halb Hack-ish-Lösung. Ich habe eine Spalte event_type erstellt. In dieser Spalte hatte ich entweder "täglich", "wöchentlich", "monatlich" oder "jährlich". Ich hatte auch eine start_date und eine end_date Spalten. Alles andere wurde im eigentlichen Backend-Code behandelt.

Ich habe nie versucht, ein Ereignis zu teilen, wenn ein Benutzer nur ein Ereignis bearbeitet hat. Es war in der Situation nicht notwendig. Sie können jedoch ein Ereignis aufteilen, indem Sie das Enddatum des ersten Ereignisses ändern, ein neues Ereignis mit einem neuen Startdatum und dem Enddatum des Originals erstellen und schließlich ein neues Ereignis für das Ereignis, das Sie gerade zum Bearbeiten ausgewählt haben. Dieser Prozess würde 3 Ereignisse erzeugen.

Hack-ish, ich weiß. Ich konnte mir zu diesem Zeitpunkt keine kluge Art vorstellen, mit diesem Problem umzugehen.

+0

Ja, das ist mehr oder weniger das, was ich gedacht habe, aber nimmst du keinen Leistungseinbruch für all diese Datumsberechnungen? –

+0

Ja, aber ich hielt es für notwendig. Ich konnte keine saubere Methode finden, um mit einer Datenbank ohne umfangreichen Backend-Code umzugehen. – JasonV

+0

Kann ich Kalender-Event-Scheduler-Datenbankschema abrufen, die mir mitteilen kann, welche Tabellen ich nehmen kann? – Tejinder

2

Halten Sie das wiederkehrende Element in der Ereignistabelle als normal, aber als wiederkehrend mit den entsprechenden Start-/Enddaten gekennzeichnet.

Wenn der Benutzer eine einzelne Instanz des Termins ändert, erstellen Sie einfach ein neues Ereignis, möglicherweise mit einer 'parentId', die der ID des wiederkehrenden Ereignisses entspricht.

Erstellen Sie eine Logik, die bewirkt, dass der Kalender alle wiederkehrenden Ereignisse an einem bestimmten Tag mit Ereignissen mit übereinstimmenden übergeordneten IDs überschreibt.

Ihre Frage zur Leistung ist im Grunde die alte Geschwindigkeit vs. Speicherproblem. Ich glaube wirklich nicht, dass die erforderliche Berechnung den Platzbedarf für die Speicherung so vieler Termine übersteigen würde. Lesen Sie einfach Datenbankoptimierung, Indizierung usw.

+0

Es ist nicht die Leistung der DB, um die ich mir Sorgen mache. Es ist der Backend-Code, der die Datumsmathematik ausführt. Also, wenn ich sage, dieses Ereignis ist jeden 3. Montag, beginnend mit 08 und nie endend, und jetzt sein 2010, müssen Sie herausfinden, wo das sogar auf Ihren Kalender fällt. Vielleicht ist das nicht so intensiv wie ich denke. –

+1

Sie müssen es nur für den sichtbaren Datumsbereich herausfinden. Wie wenn ich drei Monate sehe, müssen Sie nur diese Monate berechnen. Sie müssen nur jeden Datensatz für jeden Tag und dann jeden wiederkehrenden Datensatz (nur einmal) abrufen und herausfinden, welche Tage im sichtbaren Bereich jeweils gilt. Ich kann nicht sehen, dass es zu streng ist. – ChristianLinnell

2

Könnten Sie die beiden Welten mit einer "Cache" -Tabelle überbrücken, in der Sie die nächsten X Tage im Wert von Ereignissen vorberechnen?

So drei Tabellen:

recurring_event_specs 
one_time_events 
cached_recurring_events 

Für jeden Teil des Kalenders in X Tagen von heute, Ihre Anfrage wird UNION one_time_events und cached_recurring_events.

Dann müssten Sie nur noch Datumsberechnungen durchführen, wenn der Benutzer versucht, einen Teil des Kalenders länger als X Tage in der Zukunft zu betrachten. Ich könnte mir vorstellen, dass Sie ein gesundes X finden könnten, das den Großteil des normalen Gebrauchs abdecken würde.

Die Tabelle cached_recurring_events müsste aktualisiert werden, wenn ein Benutzer ein neues wiederkehrendes Ereignis hinzufügt - und möglicherweise einmal täglich offline durch einen cron-job/geplante Task. Aber nur an Tagen, an denen kein neues wiederkehrendes Ereignis erstellt wurde.

0

Der beste Weg, dies zu tun, ist eine standardisierte Wiederholungsmuster-Zeichenfolge (iCal) zu speichern .. und lassen Sie es leer, wenn es ein einzelnes Ereignis ist. Es gibt einige APIs, die das Wiederholungsmuster syntaktisch analysieren und Ereignisobjekte erstellen können, die Sie an UI-Elemente binden können. Keine der Vorkommen muss jemals in der Datenbank gespeichert werden, nur das Anfangsereignis (Vorkommen).

+0

Wie kann ich mit dieser Methode alle Ereignisse eines Ereignisses innerhalb einer bestimmten Zeit auswählen, ohne diese Zeichenfolge für jedes Element vollständig zu analysieren? – Kurucu

12

Ich habe mit dem gleichen Problem zu kämpfen, und ich spielte tatsächlich mit der oben vorgeschlagenen "Cache-Tabelle" Idee, aber dann stieß ich auf eine Alternative (suggested here), die scheint noch nicht dargestellt worden zu sein.

Erstellen Sie eine Tabelle, die alle Ereignisse

EventID (primary key) 
Description 
StartDate 
PeriodType - days, weeks, months, years 
PeriodFreq - # of days, weeks, etc between events 
EndDate 
... other attributes that can be modified 

Dann eine Tabelle hinzufügen, für Ausnahmen auf diese Ereignisse enthalten. Diese Tabelle verwendet einen zusammengesetzten Schlüssel, der aus der EventID besteht, die der Ereignistabelle zugeordnet ist, und einer Instanz-ID, um das bestimmte Ereignis in der Reihe auszuwählen.

Es scheint, die Ereignistabelle normalisiert zu halten und vermeidet die Aufspaltung von Serien, um Ausnahmen zu behandeln.

+0

können Sie Ihr aktuelles Schema veröffentlichen/teilen –

0

Konnten Sie die Ereignisse nicht pro Tag mit Start- und Endzeit speichern? Es wird eine Menge Daten für Ereignisse generieren, die jeden Tag passieren (vielleicht nicht-relational), aber es wird die Abfrage erleichtern und es wird möglich sein, Ausnahmen zu machen (zB wenn der Veranstaltungsort abgebrannt ist oder Mitarbeiter auffallen). Um die Tage für das Ereignis zu generieren, würde ich vorschlagen, das im Frontend zu implementieren, das auf einem ICal-ish-Muster abgeleitet ist.

+0

OP-Problem mit diesem ist, wie behandeln Sie endlose Enddaten. – nbeuchat

4

Warum verwenden Sie Google Kalender nicht als Datenbank für diese Kalenderanwendung, indem Sie Google Calendar's API zum Speichern und Abrufen von Kalenderereignissen verwenden?

Die Kalender-API ist eine REST-API, auf die über explizite HTTP-Aufrufe zugegriffen werden kann. Die API stellt die meisten Funktionen auf der Google Kalender-Weboberfläche zur Verfügung, sodass Ihre Kalenderanwendung so viele Funktionen wie Google Kalender bietet (viele Funktionen !!!).

Ihre Anwendung muss nur OAuth 2.0 für Google-APIs implementieren, was mit einem einmaligen Anmeldedienst wie Auth0 einfach gemacht werden kann, um die entsprechenden Zugriffstoken bereitzustellen. Anschließend kann Ihre Kalenderanwendung diese Token in Verbindung mit der Kalender-API verwenden, um das nahtlose Speichern und Abrufen von Kalenderereignissen in einem JSON-Format zu ermöglichen.

Benutzer erstellen Ereignisse innerhalb ihres eigenen "neuen Kalenders". Dieser Kalender wird Ihnen in Form eines Google Mail-Kontos für diese Anwendung zur Verfügung gestellt: das Google Mail-Konto der Anwendung.

Grundsätzlich wird Google Kalender zu Ihrer Datenbank, wobei Sie das Google Mail-Konto der Anwendung nicht nur alle Ihre Anwendungsereignisse speichern können, sondern Ihnen auch ermöglichen, diese Ereignisse mit einer intuitiven Benutzeroberfläche anzuzeigen und zu bearbeiten.

Verwandte Themen