Je veux écrire une application d'agenda. Ce sont vraiment des éléments récurrents qui jettent une clé dans les travaux pour le schéma DB. Je serais ravi de savoir comment organiser cela.
Que se passe-t-il si un utilisateur crée un événement et saisit qu'il répète tout le monde lundi pour toujours? Comment pourrais-je stocker tout cela dans la base de données? Je ne peux pas créer des événements infinis. Dois-je simplement y mettre un tableau qui contient les informations pertinentes afin que je puisse calculer où vont tous les événements? Si c'est le cas, je devrais les calculer chaque fois que l'utilisateur consulte une nouvelle partie du calendrier. Et s'ils parcourent les mois, mais qu'ils ont une tonne d'articles récurrents?
En outre, 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 de la séquence. Dois-je ensuite séparer le seul élément de la séquence?
mise à jour 1
Je n'ai pas du tout regardé iCal. Pour être clair, je pense que sauvegarder les informations qui vous permettent de calculer les éléments récurrents, et séparer ceux qui diffèrent de la séquence est un excellent moyen de les stocker pour pouvoir les transférer. Mais je pense que dans une application, ce serait trop lent pour faire le calcul de la date partout.
J'ai récemment créé une application de calendrier et c'était l'un des nombreux défis auxquels j'ai été confronté.
J'ai finalement trouvé une solution semi-hack-ish. J'ai créé un event_type
colonne. Dans cette colonne, j'avais: daily
, weekly
, monthly
ou yearly
. J'ai aussi eu un start_date
Et un end_date
Colonnes. Tout le reste a été géré dans le code backend réel.
Je n'ai jamais essayé de diviser un événement si un utilisateur ne modifiait qu'un seul événement. Ce n'était pas nécessaire dans la situation. Cependant, vous pouvez fractionner un événement en modifiant la date de fin du premier, en créant un nouvel événement avec un nouveau start_date
et le end_date
de l'original, et enfin, un nouvel événement pour celui que vous venez de modifier. Ce processus finirait par créer 3 événements.
Hack-ish, je sais. Je ne pouvais pas penser à une façon intelligente de gérer ce problème à l'époque.
J'ai eu du mal avec le même problème, et je jouais en fait avec l'idée de "table de cache" suggérée ci-dessus, mais je suis ensuite tombé sur une alternative ( suggérée ici ) qui ne semble pas avoir été encore représenté.
Créer une table 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
Ajoutez ensuite un tableau pour les exceptions à ces événements. Cette table utilise une clé composite, composée de l'ID d'événement qui est mappé à la table des événements, et un ID d'instance pour sélectionner l'événement particulier de 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ée et évite de fractionner les séries pour gérer les exceptions.
Pourquoi ne pas utiliser Google Agenda comme base de données pour cette application d'agenda en s'appuyant sur API Google Agenda pour stocker et récupérer les événements d'agenda?
L'API Calendar est une API REST accessible via des appels HTTP explicites; l'API expose la plupart des fonctionnalités disponibles dans l'interface Web Google Calendar, de sorte que votre application de calendrier peut autant de fonctionnalités que Google Calendrier fait (beaucoup de fonctionnalités !!!).
Votre application n'a qu'à implémenter OAuth 2.0 pour les API Google, qui peut être simplifié à l'aide d'un service de connexion unique tel que Auth pour fournir les jetons d'accès appropriés. Ensuite, votre application de calendrier peut utiliser ces jetons en conjonction avec l'API Calendrier pour fournir un stockage et une récupération sans faille des événements de calendrier au format JSON.
Les utilisateurs créent des événements dans leur propre "nouveau calendrier". Ce calendrier est partagé avec vous sous la forme d'un compte gmail dédié à cette application - le compte gmail de l'application .
Fondamentalement, Google Agenda devient votre base de données, grâce à laquelle vous pouvez avoir le compte gmail de l'application non seulement stocker tous les événements de votre application, mais également vous permettre de visualiser et éditez ces événements avec une interface intuitive.
Conservez l'élément récurrent dans le tableau des événements comme normal, mais marqué comme récurrent avec les dates de début/fin appropriées.
Si l'utilisateur modifie une seule instance du rendez-vous, créez simplement un nouvel événement, peut-être avec un "parentId" égal à l'ID de l'événement récurrent.
Construisez une logique qui oblige le calendrier à remplacer tous les événements récurrents d'un jour particulier par des événements avec des ID parents correspondants.
Votre question sur les performances est essentiellement l'ancien problème de vitesse par rapport au stockage. Je ne pense vraiment pas que le calcul requis dépasserait l'espace requis pour stocker autant de rendez-vous. Lisez simplement sur l'optimisation de la base de données, l'indexation, etc.
Pourriez-vous faire le pont entre les deux mondes avec une table de "cache", dans laquelle vous pré-calculez les prochains X jours d'événements?
Donc trois tableaux:
recurring_event_specs
one_time_events
cached_recurring_events
Pour toute partie du calendrier dans les X jours à compter d'aujourd'hui, votre requête sera UNION one_time_events
et cached_recurring_events
.
Ensuite, vous n'auriez à effectuer des calculs de date à la volée que si l'utilisateur tentait de consulter une partie du calendrier plus de X jours à l'avenir. J'imagine que vous pourriez trouver un X sain d'esprit qui couvrirait la majorité de l'utilisation normale.
Le cached_recurring_events
la table devrait être mise à jour chaque fois qu'un utilisateur ajoute un nouvel événement récurrent - et éventuellement une fois par jour hors ligne, par une tâche cron/planifiée. Mais uniquement les jours où aucun nouvel événement récurrent n'a été créé.
La meilleure façon de procéder 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. Il existe quelques API qui peuvent analyser le modèle de récurrence et créer des objets d'é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, uniquement l'événement initial (occurrence).
Ne pourriez-vous pas stocker les événements par jour avec l'heure de début et de fin? Cela générera beaucoup de données pour les événements qui se produisent tous les jours (peut-être non relationnels pour cela) mais cela facilitera les requêtes et il sera possible de faire des exceptions (par exemple, le lieu de l'événement a brûlé ou les employés sont en grève). Pour générer les jours de l'événement, je suggère d'implémenter cela dans le front-end dérivé d'un modèle ICal-ish.