Comment les tâches de calendrier répétitives doivent-elles être stockées dans la base de données?


14

Il s'agit d'un petit projet personnel de micro-gestion. Fondamentalement, je stocke les tâches dans une base de données SQLite3 qui ressemble à ceci:

    id INTEGER PRIMARY KEY AUTOINCREMENT
    label TEXT
    deadline INTEGER

Ainsi, chaque tâche a une date d'échéance (date limite) qui est stockée sous forme d'horodatage Unix. Jusqu'ici tout va bien, je peux faire des entrées telles que "demain: visite grand-mère" et une nouvelle ligne est créée avec "visite grand-mère" comme étiquette et demain transformée en heure Unix pour la date limite.

Maintenant, je voudrais entrer dans un nouveau type de tâches: routines - tâches répétées selon un schéma temporel, comme "tous les jours: nettoyer la cuisine". Comment ces tâches peuvent-elles être stockées ou modélisées?

Pour le moment, je pense que, dans le cas d'une tâche qui doit être effectuée tous les jours, pour générer de nouvelles lignes dans ma table qui auraient la même étiquette, et le champ délai incrémenté d'une journée. Dans ce cas, je dois fixer une limite à l'avenir. Par exemple, si je crée une routine pour chaque jour, cela crée une nouvelle ligne pour tous les jours de l'année restante.

Existe-t-il un moyen plus simple de procéder? Suis-je en train de manquer certains principes de conception de base de données évidents?


3
Oui. Utilisez un outil de planification approprié au lieu d'inventer un autre planificateur de travaux. Après la fin de la protestation SOPA, lisez en.wikipedia.org/wiki/Open_Source_Job_Scheduler . Cela a été résolu, bien, déjà de nombreuses fois.
S.Lott

merci Lott! oui je soupçonnais qu'il y avait une solution élégante pour cela! Je vais attendre la fin de SOPA ou vérifier s'il y a une traduction dans les autres pays Wikipedia Modifier: en fait, je viens de remarquer que la source HTML est toujours disponible dans Wikipedia US, l'écran noir est comme une astuce CSS, je suis sur mon chemin pour un petit script greasemonkey :)
François ッ Vespa Ê

1
Remarque générale: la plupart des articles ci-dessous ne prennent pas en compte la question de savoir comment les données sont réellement stockées. Je veux dire, étant donné une tâche qui se répète tous les lundis pendant 2 ans, combien de lignes devront être écrites sur le disque?
NoChance


@ root45 nice, j'utilise en fait lynx depuis la ligne de commande, c'est encore plus facile :)
François ッ Vespa Ê

Réponses:


7

Vous pouvez créer une table séparée pour qu'elle se reproduise. Mais honnêtement, je le mettrais dans la même table avec un champ de type.

Quelque chose comme ça:

ID - Int Pk

TaskDescription - TEXT

Type - Text - (Re-Occurring, or Single Occurrence) 

Due- TimeStamp - for Single Occurrence is the Date time

LastTimeCompleted - Time Stamp

ReoccurringUnit - Text - "Days", Weeks, Month, Ext

ReoccurringEveryX - Int - Reoccurring interval 

intéressant, j'explore actuellement une solution possible similaire à celle-ci, je travaille toujours mes fonctions SQL, je posterai en cas de succès
François ッ Vespa Ê

Intéressant, j'essaie de trouver la requête qui peut récupérer les tâches récurrentes et non récurrentes, puis les trier par leur date d'échéance. Un indice?
Harshal Patil

2

En plus du commentaire de S.Lott, Martin Fowler - Événements récurrents pour les calendriers PDF peut vous aider (je l'ai trouvé un peu difficile).

Notez également que plusieurs outils d'interface utilisateur offrent la fonction que vous décrivez prête à l'emploi (avec un modèle de tâche simple). Je considérerais ce problème comme un problème de conception de base de données difficile à résoudre sans ces outils.


1

À mon avis, il y a deux options:

  • Stockez une grande quantité de lignes égales pour les éléments récurrents, mais ils doivent se terminer (soit par une date de fin, soit par un nombre fini d'éléments) et doivent être marqués comme élément récurrent. Lorsque vous modifiez l'événement, vous devez tous les mettre à jour, mais lorsque vous souhaitez dévier une fois, vous pouvez simplement «rompre» la connexion entre un événement et en faire un événement normal.
  • Stockez l'événement en tant qu'élément récurrent, avec un certain schéma de répétition, et calculez pour une date donnée quels éléments récurrents sont dus à la date donnée. Cela donne la possibilité d'une répétition infinie.

c'est comme ça que je le vois aussi
François ッ Vespa Ê

1

S'il s'agit d'un projet personnel et que vous souhaitez simplement stocker vos tâches, je recommande TaskCoach . C'est une application de bureau, multi-plateforme, open source, facile à démarrer et dotée de très bonnes fonctionnalités.

Si vous développez une application de tâche, la façon la plus probable consiste à ajouter une nouvelle ligne pour chaque tâche récurrente. La logique est que chaque tâche est une entité distincte en soi et elle doit être terminée avant que la même tâche ne soit lancée le lendemain. Si vous l'incrémentez simplement, vous ne pouvez tout simplement pas capturer l'historique de la tâche.

Dans le cas où vous pensez que cela vous donnerait simplement une grande liste si quelques tâches n'étaient pas terminées, vous pourriez déclencher un événement une fois la tâche récurrente terminée afin que la nouvelle tâche soit générée en tant que nouvelle ligne uniquement lorsque la tâche est terminée. marqué comme terminé. Comme suggéré par Morons, vous pouvez utiliser une table distincte avec un indicateur pour les tâches récurrentes dans la table d'origine avec des données pour la récurrence (jours, semaines, temps de récurrence) afin que vous puissiez simplement avoir un script simple qui pourrait générer les tâches récurrentes basées sur date ou une condition ou par étiquette.

Mais si vous êtes sûr que la tâche est sûrement répétitive sans aucun changement (comme un brossage quotidien) et n'a pas besoin d'un suivi approfondi, alors vous pouvez simplement essayer la structure suivante

  • Indicateur de récurrence - pour indiquer que la tâche est récurrente
  • Période récurrente - jour, semaine, mois
  • Nombre de tâches créées - Cela incrémenterait la tâche en fonction de la période de récurrence. Donc, si la tâche commence aujourd'hui et a une période récurrente d'un jour, elle augmentera simplement d'une demain
  • Nombre de tâches terminées - Cela augmenterait si la tâche était terminée

La logique est la différence entre les tâches terminées et les tâches créées doivent toujours être la période de récurrence si la tâche est toujours terminée. Ainsi, la division de la différence de jours par période récurrente vous donnerait une indication de la durée de la tâche en attente.

Merci pour Kareem de l'avoir signalé

À mon humble avis, les applications de tâches sont difficiles à créer pour les personnes en général.


merci pour la réponse constructive! c'est un projet pour le plaisir et j'aimerais le rendre aussi flexible que possible, avec des requêtes comme 'à répéter tous les 4 jours sauf si c'est un mercredi'
François ッ Vespa Ê

1

L'opération de loin la plus fréquente consistera à répertorier tous les événements survenus dans une période donnée. Optimisez donc vos données afin de pouvoir répondre à cette question par une simple requête SQL. Je créerais deux tables:

CREATE TABLE events(start TIMESTAMP, end TIMESTAMP, name TEXT, user_id LONG,
                    recurrence_id LONG, ...);
CREATE TABLE recurrences(id LONG, start TIMESTAMP, end TIMESTAMP, name TEXT, 
                         frequency ...);

Indexez la table d'événements par heures de début et de fin. Ensuite, toutes les requêtes peuvent être traitées très rapidement à partir du tableau des événements. Lorsqu'une récurrence est modifiée, supprimez et recréez simplement tous les événements correspondants.

Ce conseil est répété sans vergogne dans un livre de Tom Kite.


1

Les tâches répétées doivent avoir une date de début et une date de fin. Pour une tâche à date unique, ce serait la même date.

Créez une sorte de tableau "Dates" qui a un enregistrement pour chaque jour que vous jugez pertinent dès le début de vos besoins aussi loin que vous le souhaitez: 31/12/2100 par exemple et convertissez-le à votre format.

Une requête pourrait ressembler à:

Select 
  t.id
  , t.label
  , d.UnixDate
from Tasks as t
inner join Dates as d
on d.UnixDate >= t.StartDate
  and d.UnixDate <= t.EndDate
where t.id = [ID Param]

0

J'ai fait quelque chose de similaire il y a des années en mettant en œuvre une interface comme le Planificateur de tâches Windows et, fondamentalement, pour chaque tâche, vous avez StartDate, EndDate (peut être nul), StartTime et RecurringDays qui contient des jours de la semaine où la tâche doit être planifiée.


C'est intéressant. y avait-il des limites de conception, c'est-à-dire des requêtes qui ne pouvaient pas être faites (comme «à répéter tous les jours de la semaine»)?
François ッ Vespa Ê

0

Vous pouvez utiliser deux tableaux: un pour la description des tâches, l'autre pour leur statut (fait / non fait, et d'autres informations: temps passé, statut de sortie, emplacement du fichier journal, etc.) Le tableau de description contiendrait le le nom de la tâche et la date ou la fréquence à laquelle elle doit être exécutée: il n'y aurait qu'une seule ligne par tâche. Chaque jour, un processus remplissait la table d'état des tâches à accomplir aujourd'hui, à partir de la table de description (vous pouvez remplir une semaine ou un mois à l'avance).

La génération de la table d'état par programme vous donne toute la flexibilité que vous souhaitez pour la fréquence (par exemple, "tous les jours de la semaine sauf les jours fériés pour le pays X" - elle peut même être stockée sous forme de chaîne). Le fait d'avoir un tableau d'état vous permet de vérifier si ou à quelle fréquence les tâches échouent (par exemple: "Je devais exécuter tous les jours: à quelle fréquence ai-je eu le temps de le faire?").

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.