¿Cómo deben almacenarse las tareas de calendario repetitivas en la base de datos?

14

Esto es para un pequeño proyecto personal para microgestión. Básicamente, almaceno tareas en una base de datos SQLite3 que se ve así:

    id INTEGER PRIMARY KEY AUTOINCREMENT
    label TEXT
    deadline INTEGER

Por lo tanto, cada tarea tiene una fecha de vencimiento (fecha límite) que se almacena como una marca de tiempo de Unix. Hasta ahora todo bien, puedo hacer entradas como "mañana: visita a la abuela" y se crea una nueva fila con "visita a la abuela" como la etiqueta y mañana se transforma como hora Unix para la fecha límite.

Ahora me gustaría ingresar un nuevo tipo de tareas: rutinas - tareas repetidas en un patrón de tiempo, como "todos los días: cocina limpia". ¿Cómo se pueden almacenar o modelar tales tareas?

Por el momento, estoy pensando que, en el caso de una tarea que debe hacerse todos los días, generar nuevas filas en mi tabla que tengan la misma etiqueta, y el campo de la fecha límite se incrementará en un día. En este caso, necesito fijar un límite en el futuro. Por ejemplo, si creo una rutina para cada día, se crea una nueva fila para todos los días del año restante.

¿Hay una manera más simple de hacer esto? ¿Me faltan algunos principios obvios de diseño de bases de datos?

François ッ Vespa ت
fuente
3
Si. Use una herramienta de planificador adecuada en lugar de inventar otro planificador de trabajos. Después de que termine la protesta de SOPA, lea en.wikipedia.org/wiki/Open_Source_Job_Scheduler . Esto ya se ha resuelto muy bien muchas veces.
S.Lott
gracias Lott! Sí, sospechaba que había una solución elegante para esto. Esperaré el final de SOPA o comprobaré si hay una traducción en los otros países de Wikipedia. Editar: en realidad acabo de darme cuenta de que la fuente HTML todavía está disponible en Wikipedia EE. UU., La pantalla apagada es como un truco CSS, estoy en mi camino para un pequeño script de greasemonkey :)
François ッ Vespa ت
1
Nota general: la mayoría de las publicaciones a continuación no tienen en cuenta la pregunta de cómo se almacenan realmente los datos. Quiero decir, dada una tarea que se repite todos los lunes durante 2 años, ¿cuántas filas deberán escribirse en el disco?
NoPuerto
O mira esta respuesta .
Kris Harper
@ root45 agradable, en realidad uso lince desde la línea de comandos, aún más fácil :)
François ッ Vespa ت

Respuestas:

7

Puede hacer una tabla separada para que vuelva a ocurrir. Pero, sinceramente, lo pondría en la misma tabla con un campo de tipo.

Algo como esto:

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 
Imbéciles
fuente
interesante, en realidad estoy explorando una posible solución similar a esta, todavía estoy trabajando en mis funciones SQL, publicaré si tiene éxito
François ッ Vespa ت
Interesante, estoy tratando de llegar a una consulta que pueda recuperar tareas recurrentes y no recurrentes y luego ordenarlas por su fecha de vencimiento. ¿Cualquier pista?
Harshal Patil
2

Además del comentario de S.Lott, Martin Fowler: PDF de eventos recurrentes para calendarios puede ayudarlo (lo encontré un poco difícil).

También tenga en cuenta que varias herramientas de interfaz de usuario ofrecen la función que está describiendo de forma inmediata (con un modelo de tarea simple). Consideraría este problema como un problema de diseño de base de datos difícil de resolver sin tales herramientas.

Ninguna posibilidad
fuente
1

En mi opinión, hay dos opciones:

  • Almacene una gran cantidad de filas iguales para elementos recurrentes, sin embargo, tienen que finalizar (ya sea a través de una fecha de finalización o un número finito de elementos) y deben marcarse como un elemento recurrente. Cuando cambia el evento, debe actualizarlos todos, pero cuando desea desviarse una vez, simplemente puede "romper" la conexión entre un evento y convertirlo en un evento normal.
  • Almacene el evento como un elemento recurrente, con un cierto esquema de repetición, y calcule para una fecha determinada qué elementos recurrentes vencen en la fecha dada. Esto da la posibilidad de repetición infinita.
Geerten
fuente
así es como yo lo veo también
François ッ Vespa ت
1

Si se trata de un proyecto personal y solo desea una forma de almacenar sus tareas, le recomiendo TaskCoach . Es una aplicación de escritorio, multiplataforma, de código abierto, fácil de comenzar y tiene muy buenas características.

En caso de que esté desarrollando una aplicación de tarea, la forma más probable es agregar una nueva fila para cada tarea recurrente. La lógica es que cada tarea es una entidad separada en sí misma y debe completarse antes de que la misma tarea se inicie al día siguiente. Si solo lo incrementa, simplemente no puede capturar el historial de la tarea.

En caso de que sienta, que solo le daría una gran lista si no se completaran algunas tareas, entonces podría desencadenar un evento una vez que se complete la tarea recurrente para que la nueva tarea se genere como una nueva fila solo cuando la tarea esté marcado como completado. Según lo sugerido por Morons, podría usar una tabla separada con un indicador para las tareas recurrentes en la tabla original junto con los datos para la recurrencia (días, semanas, tiempo recurrente) para que pueda tener un script simple que pueda generar las tareas recurrentes basadas en fecha o condición o por etiqueta.

Pero si está seguro de que la tarea es seguramente repetitiva sin ningún cambio (como el cepillado diario) y no necesita un seguimiento exhaustivo, puede probar la siguiente estructura

  • Indicador de recurrencia: para indicar que la tarea es recurrente
  • Periodo recurrente: día, semana, mes
  • Número de tareas creadas: esto incrementaría la tarea en función del período recurrente. Entonces, si la tarea comienza hoy y tiene un período recurrente de un día, solo se incrementará en uno mañana
  • Número de tareas completadas: esto aumentaría si la tarea se completara

La lógica es la diferencia entre las tareas completadas y las tareas creadas siempre deben ser el período recurrente si la tarea siempre se completa. Por lo tanto, dividir la diferencia de días por el período recurrente le daría una indicación de cuánto tiempo ha estado pendiente la tarea.

Gracias por Kareem por señalar esto

En mi humilde opinión, las aplicaciones de tareas son difíciles de construir para las personas en general.

Ubermensch
fuente
gracias por la respuesta constructiva! este es un proyecto por diversión y me gustaría hacerlo lo más flexible posible, con consultas como 'se repetirá cada 4 días excepto si es miércoles'
François ッ Vespa ت
1

Con mucho, la operación más frecuente será enumerar todos los eventos que ocurren en un período de tiempo. Optimice sus datos para que esa pregunta pueda ser respondida con una simple consulta SQL. Crearía dos tablas:

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 ...);

Indice la tabla de eventos por hora de inicio y finalización. Entonces, todas las consultas se pueden responder desde la tabla de eventos muy rápidamente. Cuando se edita una recurrencia, simplemente elimine y vuelva a crear todos los eventos correspondientes.

Este consejo se repite descaradamente de un libro de Tom Kite.

Kevin Cline
fuente
1

Las tareas repetidas deben tener una fecha de inicio y una fecha de finalización. Para una tarea de fecha única, serían la misma fecha.

Cree algún tipo de tabla de "Fechas" que tenga un registro para cada día que considere relevante desde el comienzo de sus necesidades en el futuro que desee: 31/12/2100, por ejemplo, y conviértalo a su formato.

Una consulta podría verse así:

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]
JeffO
fuente
0

Hice algo similar hace años implementando una interfaz como el Programador de tareas de Windows y, básicamente, para cada tarea tiene StartDate, EndDate (puede ser nulo), StartTime y RecurringDays que contiene días de la semana en que la tarea debe programarse.

Mauro Destro
fuente
Eso es interesante. ¿hubo algunos límites de diseño, es decir, consultas que no se pudieron hacer (como "repetir cada día de la semana")?
François ッ Vespa ت
0

Puede usar dos tablas: una para la descripción de las tareas, la otra para su estado (hecho / no hecho, y otra información: tiempo empleado, estado de salida, ubicación del archivo de registro, etc.) La tabla de descripción contendría el nombre de la tarea y la fecha o frecuencia con la que debe ejecutarse: solo habrá una fila por tarea. Todos los días, un proceso llenaría la tabla de estado de las tareas que se realizarán hoy, a partir de la tabla de descripción (puede completar una semana o un mes por adelantado).

Generar la tabla de estado mediante programación le brinda toda la flexibilidad que desea para la frecuencia (p. Ej., "Todos los días de la semana, excepto feriados bancarios para el país X", incluso podría almacenarse como una cadena). Tener una tabla de estado le permite verificar si las tareas fallan o con qué frecuencia (por ejemplo: "se suponía que debía ejecutar todos los días: ¿con qué frecuencia tenía tiempo para hacerlo?").

Vincent Zoonekynd
fuente