Разработка схемы базы данных для приложения календаря - PullRequest
46 голосов
/ 04 июня 2009

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

Что, если пользователь создает событие и вводит его, чтобы оно повторялось каждый понедельник, навсегда? Как я могу хранить все это в базе данных? Я не могу создавать бесконечные события. Должен ли я просто поместить туда таблицу, в которой хранится соответствующая информация, чтобы я мог рассчитать, куда идут все события? Если это так, мне придется рассчитывать их каждый раз, когда пользователь просматривает новую часть календаря. Что делать, если они пролистывают месяцы, но у них тонна повторяющихся предметов?

Кроме того, схема должна обрабатывать, когда пользователь щелкает элемент и говорит «Редактировать этот элемент в последовательности», а не все элементы в последовательности. Затем разделить один элемент последовательности?

Обновление 1

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

Ответы [ 7 ]

14 голосов
/ 19 мая 2012

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

Создание таблицы, содержащей все события

EventID (primary key)
Description
StartDate
PeriodType - days, weeks, months, years
PeriodFreq - # of days, weeks, etc between events
EndDate
... other attributes that can be modified

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

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

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

12 голосов
/ 04 июня 2009

Я недавно создал приложение календаря, и это было одной из многих проблем, с которыми я столкнулся.

В конце концов я придумал полу-взломанное решение. Я создал столбец event_type. В этом столбце у меня было либо: daily, weekly, monthly, либо yearly. У меня также были столбцы start_date и end_date. Все остальное было обработано в фактическом бэкэнд-коде.

Я никогда не пытался разделить событие, если пользователь редактировал только одно событие. В ситуации не было необходимости. Однако вы можете разделить событие, изменив конечную дату первого, создав новое событие с новым start_date и end_date оригинала, и, наконец, новое событие для события, которое вы только что выбрали для редактирования. В результате этого процесса будет создано 3 события.

Хак, я знаю. Я не мог придумать умного способа решения этой проблемы в то время.

3 голосов
/ 05 июля 2016

Почему бы не использовать Календарь Google в качестве базы данных для этого приложения календаря, полагаясь на API Календаря Google для хранения и извлечения событий календаря?

Calendar API - это REST API, к которому можно получить доступ через явные HTTP-вызовы; API предоставляет большинство функций, доступных в веб-интерфейсе Календаря Google, поэтому приложение календаря может использовать столько же функций, сколько и Календарь Google (много функций !!!).

В вашем приложении должна быть реализована только OAuth 2.0 для API Google, которую можно легко использовать с помощью службы единого входа, например Auth0 , для предоставления соответствующих токенов доступа. Затем приложение календаря может использовать эти токены в сочетании с API-интерфейсом «Календарь», чтобы обеспечить бесперебойное хранение и извлечение событий календаря в формате JSON.

Пользователи создают события в своем собственном «Новом календаре». Этот календарь доступен вам в виде учетной записи Gmail, предназначенной для этого приложения - учетная запись Gmail в приложении .

По сути, Google Calendar становится вашей базой данных, благодаря чему вы можете иметь учетную запись gmail приложения не только хранить все события вашего приложения, но также позволяет просматривать и редактировать эти события с интуитивно понятным интерфейсом.

3 голосов
/ 04 июня 2009

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

Если пользователь изменяет один экземпляр встречи, просто создайте новое событие, возможно, с «parentId», равным идентификатору повторяющегося события.

Построить логику, которая заставляет календарь переопределять любые повторяющиеся события в определенный день событиями с соответствующими родительскими идентификаторами.

Ваш вопрос о производительности - это в основном старая проблема скорости и памяти. Я действительно не думаю, что требуемый расчет превысил бы место для хранения такого количества встреч. Просто прочитайте об оптимизации базы данных - индексации и т. Д.

2 голосов
/ 04 июня 2009

Не могли бы вы соединить два мира с помощью таблицы "кеша", в которой вы предварительно рассчитали сумму событий на следующие X дней?

Итак, три таблицы:

recurring_event_specs
one_time_events
cached_recurring_events

Для любой части календаря в течение X дней с сегодняшнего дня ваш запрос будет UNION one_time_events и cached_recurring_events.

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

Таблицу cached_recurring_events необходимо будет обновлять всякий раз, когда пользователь добавляет новое повторяющееся событие - и, возможно, один раз в день в автономном режиме, с помощью cron-job / schedule-task. Но только в те дни, когда не было создано ни одного повторяющегося события.

0 голосов
/ 23 мая 2014

Не могли бы вы хранить события в день с временем начала и окончания? Он будет генерировать много данных для событий, которые происходят каждый день (может быть, для этого они не будут реляционными), но это упростит выполнение запросов и сделает возможными исключения (например, место события сгорело или сотрудники бастуют). Чтобы сгенерировать дни для события, я бы предложил реализовать это во внешнем интерфейсе, полученном по некоторому шаблону ICal-ish.

0 голосов
/ 16 сентября 2010

Лучший способ сделать это - сохранить строку шаблона повторения на основе стандартов (iCal) .. и оставить ее пустой, если это одно событие. Существует несколько API-интерфейсов, которые могут анализировать шаблон повторения и создавать объекты событий, которые можно привязать к элементам пользовательского интерфейса .... в базе данных не нужно хранить ни одного вхождения, только начальное событие (вхождение).

...