56 votes

Mise en place d'un schéma de base de données pour une application de calendrier

Je veux écrire une application de calendrier. C'est vraiment récurrent que jeter une clé dans les travaux pour la DB schéma. J'aimerais quelques avis sur la façon de l'organiser.

Si un utilisateur crée un événement, et les apports qu'il répète tout le monde lundi, pour toujours? Comment pourrais-je stocker tout ça dans la base de données? Je ne peux pas créer une infinité d'événements. Dois-je simplement mettre un tableau dans il y qui détient les informations pertinentes afin que je puisse calculer où tous les événements aller? Si oui, je serais obligé de les calculer à chaque fois que l'utilisateur consulte une nouvelle partie du calendrier. Que faire si ils page par mois, mais ils ont une tonne de périodique des éléments?

Aussi, le schéma doit gérer lorsqu'un utilisateur clique sur un élément et dit "Modifier celui-ci dans la séquence" pas tous les éléments dans la séquence. Puis-je diviser le seul élément de la séquence?

Mise à jour 1

Je n'ai pas regardé iCal à tous. Pour être clair, je pense que l'économie de l'info qui vous permet de calculer les éléments exceptionnels, et la séparation n'importe qui diffèrent de la séquence est un excellent moyen de stocker pour être en mesure de le transférer. Mais je pense que dans une application, ce serait trop lent, à faire de la date de mathématiques de tous sur la place.

25voto

Justin Points 156

J'ai été aux prises avec le même problème, et j'ai été réellement en jouant avec le "tableau de cache" idée suggérée ci-dessus, mais alors j'ai trouvé une alternative (suggéré ici) qui ne semble pas avoir été représenté encore.

Construire un tableau contenant tous les événements

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

Puis ajouter un tableau pour les exceptions à ces événements. Ce tableau utilise une clé composite, constitué de l'id d'événement qui correspond à la table des événements, et un ID d'instance de choisir l'événement particulier dans la série.

EventID (key)
InstanceID (key)
InstanceDate - the modified date of the exception 
IsCancelled - a flag to skip this date when traversing the series
... other attributes that can be modified

Il semble garder la table des événements normalisé, et évite de fractionnement de la série pour gérer les exceptions.

17voto

JasonV Points 485

J'ai récemment créé un calendrier d'application et ce fut l'un des nombreux défis que j'ai rencontrés.

J'ai finalement venu avec une demi-hack-ish solution. J'ai créé une colonne event_type. Dans cette colonne, j'avais: "tous les jours", "hebdomadaire", "mensuel", ou "chaque année". J'ai également eu un date_debut et un end_date colonnes. Tout le reste a été traitée dans le backend de code.

Je n'ai jamais essayé de les diviser un événement si un utilisateur a modifié un seul événement. Il n'était pas nécessaire dans la situation. Cependant, vous pouvez diviser un événement par la modification de la end_date de la première, la création d'un nouvel événement avec une nouvelle date de début et la end_date de l'original, et enfin, un nouvel événement pour celui que vous venez de choisir à modifier. Cela aboutirait à la création de 3 événements.

Hack-ish, je sais. Je ne pouvais pas penser à un moyen astucieux pour gérer ce problème à l'époque.

4voto

ChristianLinnell Points 774

Maintenez l'élément périodique dans le tableau des événements, comme d'habitude, mais signalé comme récurrents avec les dates de début/ fin.

Si l'utilisateur modifie une seule instance de la nomination, il suffit de créer un nouvel événement, peut-être avec un 'parentId' qui est égale à la récurrence de l'événement id.

Créer une logique qui provoque le calendrier pour remplacer tous les événements récurrents sur un jour en particulier avec les événements avec une correspondance de parent Id.

Votre question au sujet de la performance est essentiellement la vitesse par rapport à l'ancien problème de stockage. Je ne pense vraiment pas que le calcul nécessaire à dépasser le besoin d'espace pour stocker tellement de rendez-vous. Viens de lire sur l'optimisation des bases de données d'indexation etc.

3voto

Ben Dunlap Points 1101

Pourriez-vous le pont entre les deux mondes avec un "cache" de la table, dans lequel vous pré-calculer le prochain X jours d'événements?

Donc, trois tables:

recurring_event_specs
one_time_events
cached_recurring_events

Pour toute partie du calendrier dans un délai de X jours d'aujourd'hui, votre requête UNION one_time_events et cached_recurring_events.

Ensuite, vous n'aurez à le faire à la volée les calculs de date si l'utilisateur a essayé de regarder une partie du calendrier de plus de X jours dans le futur. J'imagine que vous pouvez trouver un sane X qui permettrait de couvrir la majorité des conditions normales d'utilisation.

L' cached_recurring_events table a besoin d'être mis à jour chaque fois qu'un utilisateur ajoute un nouvel événement récurrent, et peut-être une fois par jour en mode hors connexion, par un cron-travail/prévu-tâche. Mais que les jours où aucun nouvel événement récurrent a été créé.

1voto

Daniel Bardi Points 139

Pour ce faire, la meilleure solution consiste à stocker une chaîne de modèle de récurrence basée sur des normes (iCal) .. et à laisser vide s'il s'agit d'un seul événement. Quelques API peuvent analyser le modèle de récurrence et créer des objets événement que vous pouvez lier à des éléments d'interface utilisateur. Aucune des occurrences n'a besoin d'être stockée dans la base de données, seul l'événement initial (occurrence) ..

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X