Как повторяющиеся задачи календаря должны храниться в базе данных?

14

Это для небольшого личного проекта по микроуправлению. По сути, я храню задачи в базе данных SQLite3, которая выглядит следующим образом:

    id INTEGER PRIMARY KEY AUTOINCREMENT
    label TEXT
    deadline INTEGER

Таким образом, у каждой задачи есть срок выполнения (крайний срок), который сохраняется как метка времени Unix. Пока все хорошо, я могу делать такие записи, как «завтра: посещение бабушки», и создается новый ряд с «посещением бабушки» в качестве метки и завтра трансформируется в Unix, время для крайнего срока.

Теперь я хотел бы ввести новый тип задач: рутины - задачи, повторяющиеся по схеме времени, например, «каждый день: чистая кухня». Как такие задачи могут быть сохранены или смоделированы?

На данный момент я думаю, что в случае задачи, которую нужно выполнять каждый день, генерировать в моей таблице новые строки с одинаковой меткой и полем крайнего срока, увеличенным на один день. В этом случае мне нужно установить предел в будущем. Например, если я создаю процедуру для каждого дня, она создает новую строку для каждого дня оставшегося года.

Есть ли более простой способ сделать это? Я упускаю некоторые очевидные принципы проектирования баз данных?

Франсуа ッ Веспа ت
источник
3
Да. Используйте подходящий инструмент планировщика вместо изобретения еще одного планировщика заданий. После окончания протеста SOPA прочитайте en.wikipedia.org/wiki/Open_Source_Job_Scheduler . Это было решено, к счастью, уже много раз.
С.Лотт
спасибо Лотт! да, я подозревал, что для этого было элегантное решение! Я подожду окончания SOPA или проверю, есть ли перевод в других странах Википедии. Редактировать: на самом деле я только что заметил, что исходный код HTML все еще доступен в Википедии, США, затемнение экрана похоже на трюк CSS, я нахожусь на моем путь для небольшого сценария с изображением жирных обезьян :)
Франсуа ッ Веспа
1
Общее примечание: большинство постов ниже не учитывают вопрос о том, как на самом деле хранятся данные. Я имею в виду, учитывая задание, которое повторяется каждый понедельник в течение 2 лет, сколько строк нужно будет записать на диск?
NoChance
Или посмотрите этот ответ .
Крис Харпер
@ root45 здорово, я на самом деле использую lynx из командной строки, даже проще :)
Франсуа ッ Vespa ت

Ответы:

7

Вы можете сделать отдельную таблицу для повторения. Но, честно говоря, я бы просто положил его в одну таблицу с полем типов.

Что-то вроде этого:

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 
Идиоты
источник
интересно, я на самом деле изучаю возможное решение, подобное этому, я все еще работаю над своими функциями SQL, я буду публиковать в случае успеха
Франсуа ッ Vespa
Интересно, что я пытаюсь найти запрос, который может извлекать как повторяющиеся, так и неповторяющиеся задачи, а затем сортировать их по дате выполнения. Любая подсказка?
Харшал Патил
2

В дополнение к комментарию С. Лотта, Мартин Фаулер - Повторяющиеся события для календарей PDF может помочь вам (мне было немного сложно).

Также обратите внимание, что несколько инструментов пользовательского интерфейса предлагают функцию, которую вы описываете из коробки (с простой моделью задачи). Я бы посчитал эту проблему трудной для решения проблемы проектирования баз данных без таких инструментов.

Без шансов
источник
1

На мой взгляд, есть два варианта:

  • Сохраняйте большое количество одинаковых строк для повторяющихся элементов, однако они должны заканчиваться (либо через конечную дату, либо через конечное число элементов) и должны быть помечены как повторяющиеся элементы. Когда вы изменяете событие, вы должны обновить их все, но когда вы хотите отклониться один раз, вы можете просто «разорвать» связь между одним событием и сделать его нормальным событием.
  • Сохраните событие как повторяющийся элемент с определенной схемой повторения и рассчитайте на определенную дату, какие повторяющиеся элементы должны быть выполнены на указанную дату. Это дает возможность для бесконечного повторения.
Geerten
источник
вот как я это вижу
Франсуа ッ Веспа
1

Если это личный проект, и вы просто хотите сохранить свои задачи, я рекомендую TaskCoach . Это настольное приложение, мультиплатформенное, с открытым исходным кодом, простое в освоении и обладающее действительно хорошими функциями.

Если вы разрабатываете приложение задачи, то наиболее вероятный способ - добавить новую строку для каждой повторяющейся задачи. Логика заключается в том, что каждая задача сама по себе является отдельной сущностью, и ее необходимо выполнить до того, как та же задача будет запущена на следующий день. Если вы просто увеличиваете его, вы просто не можете захватить историю задачи.

В случае, если вы чувствуете, что это просто даст вам большой список, если несколько задач не будут выполнены, вы можете вызвать событие после завершения повторяющейся задачи, чтобы новая задача генерировалась как новая строка только тогда, когда задача помечено как завершенное. Как предложил Моронс, вы можете использовать отдельную таблицу с флагом для повторяющихся задач в исходной таблице вместе с данными для повторения (дни, недели, время повторения), чтобы у вас мог быть простой сценарий, который мог бы генерировать повторяющиеся задачи на основе дата или условие или по ярлыку.

Но если вы уверены, что задача, безусловно, повторяющаяся без каких-либо изменений (например, ежедневная кисть) и не требует обширного отслеживания, тогда вы можете просто попробовать следующую структуру

  • Флаг повторения - чтобы указать, что задача повторяется
  • Период повторения - день, неделя, месяц
  • Количество созданных задач - Это увеличит задачу на основе повторного периода. Таким образом, если задание начинается сегодня и имеет период повторения один день, оно будет просто увеличиваться на единицу завтра
  • Количество выполненных заданий - увеличивается, если задание выполнено

Логика заключается в том, что разница между выполненными и созданными задачами всегда должна быть периодом повторения, если задача всегда завершена. Таким образом, деление разницы дней на повторяющийся период даст вам представление о том, как долго задача еще не завершена.

Спасибо за Карим за указание на это

ИМХО, задачи приложений сложно построить для людей в целом.

Ubermensch
источник
спасибо за конструктивный ответ! это интересный проект, и я хотел бы сделать его максимально гибким, с такими запросами, как «повторять каждые 4 дня, за исключением случаев, когда это среда»
Франсуа ッ Vespa
1

Безусловно, наиболее частой операцией будет перечисление всех событий, происходящих за определенный период времени. Поэтому оптимизируйте свои данные, чтобы на этот вопрос можно было ответить простым SQL-запросом. Я бы создал две таблицы:

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

Индексируйте таблицу событий по времени начала и окончания. Тогда на все запросы можно очень быстро ответить из таблицы событий. Когда повторение редактируется, просто удалите и заново создайте все соответствующие события.

Этот совет беззастенчиво повторяется из книги Тома Кайта.

Кевин Клайн
источник
1

Повторные задачи должны иметь дату начала и дату окончания. Для одной задачи даты они были бы той же самой датой.

Создайте какую-нибудь таблицу «Даты», в которой есть одна запись на каждый день, который, по вашему мнению, является актуальным с самого начала ваших потребностей, настолько далеко в будущем, насколько вы хотите: например, 31.12.21, и конвертируйте его в свой формат.

Запрос может выглядеть так:

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
источник
0

Несколько лет назад я сделал нечто подобное, реализовав интерфейс, такой как планировщик задач Windows, и в основном для каждой задачи у вас есть StartDate, EndDate (может быть нулевым), StartTime и RecurringDays, которые содержат дни недели, когда задача должна быть запланирована.

Мауро Дестро
источник
Это интересно. были ли какие-то ограничения дизайна, то есть запросы, которые нельзя было выполнить (например, «повторять каждый день недели»)?
Франсуа ッ Vespa ت
0

Вы можете использовать две таблицы: одну для описания задач, другую для их состояния (выполнено / не выполнено и другую информацию: затраченное время, состояние выхода, местоположение файла журнала и т. Д.) Таблица описания будет содержать название задачи, а также дата или частота, с которой она должна выполняться: для каждой задачи будет только одна строка. Каждый день процесс заполняет таблицу состояния для задач, которые нужно выполнить сегодня, из таблицы описания (вы можете заполнить одну неделю или один месяц вперед).

Генерация таблицы состояния программным образом дает вам всю необходимую вам гибкость для частоты (например, «каждый будний день, кроме выходных дней для страны X» - она ​​может даже храниться в виде строки). Наличие таблицы состояния позволяет проверить, если или как часто задачи не выполняются (например: «Я должен был запускаться каждый день: как часто я успевал это делать?»).

Винсент Зонекинд
источник