Разработка системы Календаря как Google Calendar [закрыто]

Мне нужно создать что-то похожее на Календарь Google, поэтому я создал таблицу событий, которая содержит все события для пользователя.

Сложной частью является обработка повторяющихся событий, строка в таблице событий имеет поле event_type, которое сообщает вам, что это за событие, поскольку событие может быть только на одну дату, ИЛИ повторяющееся событие каждые x дней. ,

Основная задача дизайна - обработка повторяющихся событий.

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

Ребята, что вы думаете?

15.08.2008 19:10:15
16 ОТВЕТОВ

Я бы сказал, начать с стандарта. Если вы будете использовать его в качестве модели, то сможете делать все, что касается календаря Google, Outlook, Mac (программы) и практически мгновенно интегрироваться с ними.

Оттуда, время, чтобы забить ваш Ajax и Javascript, потому что вы не можете иметь роскошный веб-интерфейс с перетаскиванием и несколько календарей без тонны Ajax и Javascript.

3
15.08.2008 19:14:02

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

Повторяющиеся события должны иметь дату начала и дату окончания (которая может быть нулевой для событий, которые продолжаются каждые X дней «навсегда»). Вам нужно будет решить, какую частоту вы хотите разрешить - каждые X дней N-й день каждого месяца, каждый день недели и т. Д.

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

Если бы я собирался заняться этим (и изо всех сил старался бы не изобретать это колесо), я бы искал библиотеки с открытым исходным кодом или, по крайней мере, проекты с открытым исходным кодом с календарями, которые вы можете посмотреть , Любые рекомендации, ребята?

0
15.08.2008 19:17:51

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

Это имеет два преимущества:

  1. Нет сложных процедур, чтобы определить дату следующего события
  2. Отдельные случаи могут быть отредактированы без влияния на остальные

Надеюсь, это даст вам пищу для размышлений :)

1
15.08.2008 19:19:04

У вас должны быть дата начала, дата окончания и срок действия. Однодневные события будут иметь одинаковую дату начала и дату окончания, что также позволяет вам проводить частичные дневные события. Что касается повторяющихся событий, тогда начальная и конечная даты будут для одного и того же дня, но с разным временем, тогда у вас будет перечисление или таблица, в которой указана частота повторения (ежедневно, еженедельно, ежемесячно и т. Д.).

Это позволяет вам сказать «это событие появляется каждый день» для ежедневных, «это событие появляется на 2-й день каждой недели» для еженедельных, «это событие появляется на 5-й день каждого месяца» для ежемесячных », это событие появляется на 215-й день каждого года »в течение года, если дата меньше даты истечения срока годности.

2
15.08.2008 19:20:32

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

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

1
15.08.2008 19:22:35

@GateKiller

Я не думал о случае, когда вы редактируете отдельные случаи. В этом случае имеет смысл хранить события отдельно.

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

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

1
15.08.2008 19:25:04

Даррен,

Именно так я и спроектировал свою таблицу событий, но, подумав, скажем, у меня есть 100 000 пользователей, которые создали события, эта таблица будет довольно сильно поражена, особенно если я собираюсь рассылать электронные письма, чтобы напомнить людям об их события (события могут быть также для определенного времени суток!), поэтому я мог бы опрашивать эту таблицу каждые 15 минут потенциально!

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

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

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

ChanChan,

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

2
15.08.2008 19:31:54

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

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

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

Если сделать опрос более эффективным, если вы проводите опрос каждые 15 минут, а ваша база данных и / или сервер не могут справиться с нагрузкой, то вы уже обречены. Ваша база данных не сможет обрабатывать пользователей, если не будет много, гораздо более частых опросов, не потревожив.

5
15.08.2008 20:06:09

Как уже говорилось, не изобретайте велосипед , просто улучшайте его.

Оформить заказ VCalendar , это с открытым исходным кодом, и поставляется на PHP, ASP и ASP.Net (C #)!

Также вы можете проверить Day Pilot, который предлагает календарь, написанный на Asp.Net 2.0. Они предлагают облегченную версию, которую вы можете проверить, и если она работает для вас, вы можете приобрести лицензию.

Обновление (30.09.09):

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

4
30.09.2009 19:30:30

undefined написал:

… Этот стол будет очень сильно поражен, особенно если я собираюсь рассылать электронные письма, чтобы напомнить людям об их событиях (события могут быть также для определенного времени суток!), Поэтому я мог бы опрашивать эту таблицу каждые 15 минут потенциально !

Создайте таблицу для уведомлений. Опрос только это.

Обновите таблицу уведомлений при обновлении событий (повторяющихся или иных).

РЕДАКТИРОВАТЬ: представление базы данных может не нарушать нормальные формы, если это проблема. Но вы, вероятно, захотите отследить, какие уведомления были отправлены, а какие еще не отправлены.

0
23.05.2017 10:31:20

Дерек Парк, я буду создавать каждый экземпляр события в таблице, и эта таблица будет регенерироваться каждый месяц (так что любое событие, для которого было задано reoccurr 'forever', будет регенерировано за один месяц заранее с использованием службы Windows или возможно на уровне сервера sql). Опрос будет проводиться не каждые 15 минут, а только для опросов, связанных с уведомлениями по электронной почте. Когда кто-то хочет просмотреть свои события в течение месяца, мне нужно будет распаковать все свои события, повторно происходящие события и выяснить, какие события отображать (поскольку повторное событие могло быть создано 6 месяцев назад, но относится к месяц пользователь просматривает).

Зак, я не слишком озабочен наличием совершенно нормализованной базы данных, тот факт, что я думаю о создании вторичной таблицы, уже нарушает одно из правил, хе-хе. Мои основные таблицы базы данных следуют «правилам», но я не против создавать вторичные таблицы / столбцы в тех случаях, когда это приносит пользу производительности.

0
15.08.2008 22:08:13

Именно так я и спроектировал свою таблицу событий, но, подумав, скажем, у меня есть 100 000 пользователей, которые создали события, эта таблица будет довольно сильно поражена, особенно если я собираюсь рассылать электронные письма, чтобы напомнить людям об их события (события могут быть также для определенного времени суток!), поэтому я мог бы опрашивать эту таблицу каждые 15 минут потенциально!

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

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

Затем вы можете разделить информацию между несколькими базами данных для масштабирования. то есть пользователи 1-10000 календарей существуют на сервере 1, 10001-20000 существуют на сервере 2 и т. д.

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

0
16.08.2008 04:22:20

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

Этот запрос возвращает вам серию, которая начинается с элемента 3:

SELECT * FROM events WHERE id = 3 OR parentid = 3

Чтобы получить все элементы за этот месяц, при условии, что у вас есть дата начала и окончания в таблице событий, все, что вам нужно сделать, это:

SELECT * FROM events WHERE startdate >= '2008-08-01' AND enddate <= '2008-08-31'

Управлять созданием / модификацией серий программно не будет очень сложно, но на самом деле это будет зависеть от набора функций, который вы хотите предоставить, и от того, как вы думаете, он будет использоваться. Если вы хотите провести различие между сериями и событиями, у вас может быть отдельная таблица рядов и обнуляемый series_id для ваших событий, что позволит вам свободно разбираться с отдельными событиями, сохраняя при этом контроль над вашей серией.

2
16.08.2008 04:45:24

Я занимаюсь именно этой проблемой, и я полностью разместил iCalendar ( rfc 2445 ) до прочтения этой темы, поэтому я понятия не имею, насколько хорошо это будет или не будет интегрироваться с этим. В любом случае, дизайн, который я придумал, выглядит примерно так:

  • Вы не можете сохранить все экземпляры повторяющегося события, по крайней мере, до того, как они произойдут, поэтому у меня просто есть одна таблица, в которой первый экземпляр события хранится в виде фактической даты, необязательного срока действия, а также обнуляемых полей repeat_unit и repeat_increment описать повторение. Для единичных экземпляров поля повторения равны нулю, в противном случае единицами измерения будут «день», «неделя», «месяц», «год», а приращение - это просто кратное число единиц, добавляемых к дате начала следующего вхождения.
  • Сохранение прошлых событий представляется полезным только в том случае, если вам нужно установить отношения с другими объектами в вашей модели, и даже в этом случае нет необходимости иметь явную таблицу «экземпляров событий» в каждом случае. Если другие объекты уже имеют данные «экземпляра» даты / времени, то, скорее всего, будет достаточно внешнего ключа к событию (или таблицы соединений для многих ко многим).
  • Чтобы «изменить этот экземпляр» / «изменить все будущие экземпляры», я планировал просто продублировать события и удалить устаревшие. Таким образом, чтобы изменить отдельные экземпляры, вы должны удалить старый экземпляр при его последнем появлении, сделать копию для нового уникального экземпляра с изменениями и без повторений и другую копию оригинала в следующем экземпляре, которая повторяется в будущее. Изменение всех будущих экземпляров аналогично, вы просто истекаете срок действия оригинала и делаете новую копию с изменениями и подробностями повторения.

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

  1. Это затрудняет представление событий типа MWF. Это возможно, но вынуждает пользователя создавать три отдельных события, которые повторяются еженедельно для M, W, F в отдельности, и любые изменения, которые он хочет внести, должны быть выполнены также для каждого отдельно. Подобные события не особенно полезны в моем приложении, но они оставляют бородавку на модели, что делает ее менее универсальной, чем мне бы хотелось.
  2. Копируя события для внесения изменений, вы нарушаете связь между ними, что может быть полезно в некоторых сценариях (или, может быть, это иногда может быть проблематично). Таблица событий теоретически может содержать поле идентификатора «copied_from», чтобы отслеживать, где событие произошло, но я не до конца продумал, насколько полезным будет что-то подобное. С одной стороны, иерархические отношения между родителями и дочерними объектами - трудная задача для запроса SQL, поэтому преимущества должны быть довольно значительными, чтобы перевесить стоимость запроса этих данных. Вы могли бы использовать вложенный набор вместо этого, я полагаю.

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

(:month + (:year * 12)) - (MONTH(occursOn) + (YEAR(occursOn) * 12))

Основываясь на последнем примере, вы можете использовать MOD, чтобы определить, является ли разница в месяцах правильным кратным:

MOD(:month + (:year * 12)) - (MONTH(occursOn) + (YEAR(occursOn) * 12), repeatIncrement) = 0

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

4
22.08.2008 22:19:10

Ра-Ajax Calendar пускатель комплект есть образец обработки события RenderDate , который может изменить даты специально. Хотя «повторяющиеся события» - это скорее алгоритмическая вещь, и я сомневаюсь, что очень немногие календари вам сильно помогут ...

0
25.11.2008 01:01:24

Если кто-то делает Ruby, есть отличная библиотека Runt, которая делает подобные вещи. Стоит проверить. http://runt.rubyforge.org/

0
1.02.2009 17:15:07