Como as tarefas repetitivas do calendário devem ser armazenadas no banco de dados?

14

Isto é para um pequeno projeto pessoal de microgestão. Basicamente, eu armazeno tarefas em um banco de dados SQLite3 parecido com este:

    id INTEGER PRIMARY KEY AUTOINCREMENT
    label TEXT
    deadline INTEGER

Portanto, cada tarefa tem uma data de vencimento (prazo final) que é armazenada como um carimbo de data e hora do Unix. Até aí tudo bem, eu posso fazer entradas como "tomorrow: visit grandma" e uma nova linha é criada com "visit grandma" como etiqueta e amanhã será transformada como tempo Unix para o prazo final.

Agora eu gostaria de inserir novos tipos de tarefas: rotinas - tarefas repetidas em um padrão de tempo, como "todos os dias: cozinha limpa". Como essas tarefas podem ser armazenadas ou modeladas?

No momento, estou pensando que, no caso de uma tarefa que precisa ser executada todos os dias, gerar novas linhas na minha tabela com o mesmo rótulo e o campo do prazo aumentado em um dia. Nesse caso, preciso fixar um limite no futuro. Por exemplo, se eu criar uma rotina para todos os dias, ela criará uma nova linha para todos os dias do ano restante.

Existe uma maneira mais simples de fazer isso? Estou perdendo alguns princípios óbvios de design de banco de dados?

François e Vespa
fonte
3
Sim. Use uma ferramenta de agendamento adequada em vez de inventar outro agendador de tarefas. Após o término do protesto do SOPA, leia en.wikipedia.org/wiki/Open_Source_Job_Scheduler . Isso já foi resolvido, muitas vezes.
S.Lott
obrigado Lott! Sim, eu suspeitava que houvesse uma solução elegante para isso! Vou esperar o final do SOPA ou verificar se há uma tradução nos outros países da Wikipedia. Edit: na verdade, acabei de perceber que a fonte HTML ainda está disponível na Wikipedia nos EUA, a tela apagada é como um truque CSS, estou no meu o caminho para um pequeno script greasemonkey :) #
16555 François ッ Vespa
1
Nota geral: a maioria das postagens abaixo não leva em consideração a questão de como os dados são realmente armazenados. Quero dizer, dada uma tarefa que se repete toda segunda-feira por 2 anos, quantas linhas precisarão ser gravadas no disco?
precisa saber é o seguinte
Ou veja esta resposta .
Kris Harper
@ root45 nice, na verdade eu uso o lynx na linha de comando, ainda mais fácil :) #
François Vespa

Respostas:

7

Você pode criar uma tabela separada para repetir. Mas, honestamente, eu colocaria na mesma tabela com um campo de tipo.

Algo assim:

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 
Idiotas
fonte
interessante, estou explorando uma possível solução semelhante a esta, ainda estou trabalhando em minhas funções SQL, vou postar se for bem
16195 François ッ Vespa
Interessante, estou tentando criar a consulta que pode buscar tarefas recorrentes e não recorrentes e depois classificá-las pela data de vencimento. Qualquer pista?
Harshal Patil
2

Além do comentário de S.Lott, Martin Fowler - PDF de eventos recorrentes para calendários pode ajudá-lo (achei um pouco difícil).

Observe também que várias ferramentas da interface do usuário oferecem a função que você está descrevendo imediatamente (com um modelo de tarefa simples). Eu consideraria esse problema um problema difícil de resolver, sem essas ferramentas.

NoChance
fonte
1

Na minha opinião, existem duas opções:

  • Armazene uma grande quantidade de linhas iguais para itens recorrentes, no entanto, eles precisam terminar (até uma data de término ou um número finito de itens) e devem ser marcados como itens recorrentes. Quando você altera o evento, precisa atualizá-los todos, mas quando deseja desviar uma vez, pode simplesmente 'interromper' a conexão entre um evento e torná-lo um evento normal.
  • Armazene o evento como um item recorrente, com um determinado esquema de repetição, e calcule para uma determinada data quais itens recorrentes vencem na data especificada. Isso dá a possibilidade de repetição infinita.
Geerten
fonte
é assim que eu vejo também #
François # Vespa
1

Se este é um projeto pessoal e você deseja apenas uma maneira de armazenar suas tarefas, recomendo o TaskCoach . É um aplicativo de desktop, multiplataforma, código aberto, fácil de iniciar e com recursos muito bons.

Caso você esteja desenvolvendo um aplicativo de tarefas, a maneira mais provável é adicionar uma nova linha para cada tarefa recorrente. A lógica é que cada tarefa é uma entidade separada em si mesma e deve ser concluída antes que a mesma tarefa seja iniciada no dia seguinte. Se você apenas incrementá-lo, não poderá capturar o histórico da tarefa.

Caso você ache que isso forneceria uma lista grande se algumas tarefas não fossem concluídas, você poderia acionar um evento assim que a tarefa recorrente fosse concluída, para que a nova tarefa seja gerada como uma nova linha somente quando a tarefa for concluída. marcado como concluído. Conforme sugerido por idiotas, você pode usar uma tabela separada com um sinalizador para tarefas recorrentes na tabela original, juntamente com dados de recorrência (dias, semanas, tempo recorrente), para que você possa ter apenas um script simples que possa gerar as tarefas recorrentes com base em data ou condição ou por rótulo.

Mas se você tiver certeza de que a tarefa é certamente repetitiva, sem qualquer alteração (como escovar diariamente) e não precisar de acompanhamento extensivo, tente a seguinte estrutura

  • Sinalizador de recorrência - para indicar que a tarefa é recorrente
  • Período recorrente - dia, semana, mês
  • Número de tarefas criadas - Isso aumentaria a tarefa com base no período recorrente. Portanto, se a tarefa começar hoje e tiver um período recorrente de um dia, ela aumentará apenas uma amanhã
  • Número de tarefas concluídas - isso aumentaria se a tarefa fosse concluída

A lógica é a diferença entre as tarefas concluídas e as tarefas criadas sempre devem ser o período recorrente, se a tarefa estiver sempre concluída. Portanto, dividir a diferença de dias por período recorrente forneceria uma indicação de quanto tempo a tarefa está pendente.

Obrigado por Kareem por apontar isso

IMHO, aplicativos de tarefas são difíceis de construir para pessoas em geral.

Ubermensch
fonte
obrigado pela resposta construtiva! este é um projeto divertido e eu gostaria de torná-lo o mais flexível possível, com consultas como 'ser repetido a cada 4 dias, exceto se for uma quarta-feira' #
François ッ Vespa
1

De longe, a operação mais frequente será listar todos os eventos que ocorrem em um período de tempo. Portanto, otimize seus dados para que a pergunta possa ser respondida por uma simples consulta SQL. Eu criaria duas tabelas:

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

Índice da tabela de eventos por horários de início e término. Todas as perguntas podem ser respondidas da tabela de eventos rapidamente. Quando uma recorrência é editada, basta excluir e recriar todos os eventos correspondentes.

Este conselho é descaradamente repetido em um livro de Tom Kite.

Kevin Cline
fonte
1

Tarefas repetidas devem ter uma data de início e uma data de término. Para uma tarefa de data única, eles seriam a mesma data.

Crie algum tipo de tabela "Datas" que possua um registro para cada dia que julgue relevante desde o início de suas necessidades até o futuro desejado: 31/12/2100, por exemplo, e converta para o seu formato.

Uma consulta pode parecer com:

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
fonte
0

Fiz algo semelhante anos atrás, implementando uma interface como o Windows Task Scheduler e, basicamente, para cada tarefa que você tem StartDate, EndDate (pode ser nulo), StartTime e RecurringDays que contêm os dias da semana em que a tarefa deve ser agendada.

Mauro Destro
fonte
Isso é interessante. houve alguns limites de design, ou seja, consultas que não puderam ser feitas (como 'ser repetido todos os dias da semana')?
François e Vespa
0

Você pode usar duas tabelas: uma para a descrição das tarefas, a outra para seu status (concluído / não concluído e outras informações: tempo gasto, status de saída, local do arquivo de log etc.). A tabela de descrição conteria o nome da tarefa e a data ou frequência em que deve ser executada: haveria apenas uma linha por tarefa. Todos os dias, um processo preenche a tabela de status para as tarefas a serem realizadas hoje, a partir da tabela de descrição (você pode preencher uma semana ou um mês de antecedência).

A geração da tabela de status programaticamente fornece toda a flexibilidade que você deseja para a frequência (por exemplo, "todos os dias da semana, exceto feriados do país X" - pode até ser armazenada como uma sequência). Ter uma tabela de status permite verificar se ou com que freqüência as tarefas falham (por exemplo: "Eu deveria executar todos os dias: com que frequência eu tinha tempo para fazer isso?").

Vincent Zoonekynd
fonte