<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: loribean</title>
    <description>The latest articles on DEV Community by loribean (@loribean).</description>
    <link>https://dev.to/loribean</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1270694%2F06fd9568-c7de-4287-a384-c926a8f4a5af.jpeg</url>
      <title>DEV Community: loribean</title>
      <link>https://dev.to/loribean</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/loribean"/>
    <language>en</language>
    <item>
      <title>Recurring Calendar Events — Database Design.</title>
      <dc:creator>loribean</dc:creator>
      <pubDate>Thu, 01 Feb 2024 04:01:16 +0000</pubDate>
      <link>https://dev.to/loribean/recurring-calendar-events-database-design-45c1</link>
      <guid>https://dev.to/loribean/recurring-calendar-events-database-design-45c1</guid>
      <description>&lt;p&gt;Recently, I've been working on a side project that allows users to manage and schedule tasks. Initially, I thought that the database design would be pretty simple. But, I quickly realized that handling recurring events is much more complex than I initially anticipated. Recurrence is not easy for applications to deal with. It is a herculean task, especially when you consider all possible recurring scenarios - including creating bi-weekly or quarterly events or allowing the rescheduling of all future event instances. So, How should we handle the database storage for recurring events?&lt;/p&gt;

&lt;p&gt;In fact, this problem is pretty similar to the system design interview question:&lt;br&gt;
&lt;em&gt;Consider Google Calendar's recurring events feature. In particular, the ability of a user to create an ad-hoc or recurring event.&lt;br&gt;
In case of recurring events, edit either individual instances of the event or all the remaining instances of the event&lt;br&gt;
How would you design a schema to store event data to support such a feature?&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements:
&lt;/h2&gt;

&lt;p&gt;Users are allowed to create regular and recurring events.&lt;br&gt;
Daily, weekly, bi-weekly, monthly, quarterly, bi-yearly, and yearly events can be created with no end date restrictions.&lt;br&gt;
Users can reschedule or cancel an instance of an event or all future instances of an event.&lt;br&gt;
Changes to schedules should not update past events&lt;/p&gt;

&lt;h2&gt;
  
  
  Naive approach
&lt;/h2&gt;

&lt;p&gt;In the naive approach, the instinct was to store every single instance of a recurring event separately. This led to the creation of two tables, namely tasks and schedules, as illustrated in the schema below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffvfq8tfycmzdaivxkwa8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffvfq8tfycmzdaivxkwa8.png" alt="Image description" width="698" height="776"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here, a user could create a schedule with a set frequency, choosing from options like weekly, daily, or monthly. A background cron job would then generate associated tasks based on the schedule.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros of the Naive Approach:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Straightforward implementation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons of the Naive Approach:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Significant space requirements, especially for a large user base.&lt;/li&gt;
&lt;li&gt;Cumbersome updating process, impacting application performance.&lt;/li&gt;
&lt;li&gt;Complex handling of exceptions, especially in cases of rescheduling.&lt;/li&gt;
&lt;li&gt;How do we handle recurring events with no end_date ?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Creating a database entry for each instance of a recurring task seems unacceptable, because we want infinite forward visibility, and because when a user edits the parameters of a recurring task (e.g. changes it from daily to weekly), we have to update all future tasks. This results in operations that are simply too computationally intensive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Refined approach
&lt;/h2&gt;

&lt;p&gt;This approach envisions infinite sequences of recurring events without cluttering the database. Here's how it works:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsiucq9l0sad9jt271iol.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsiucq9l0sad9jt271iol.png" alt="Image description" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Schedule essentially defines infinite sequences of recurring events, which are not represented in the database, but are visible and editable via the UI&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exclusion Records for Deletions:&lt;/strong&gt; Deleting a specific instance prompts the creation of an "exclusion" record for that day. This prevents unnecessary generation of instances in the recurrence sequence.&lt;br&gt;
&lt;strong&gt;Handling Edits with Exclusion Records:&lt;/strong&gt; Editing a specific instance triggers the creation of an "exclusion" record for that day. Simultaneously, a database record is generated for the edited instance, seamlessly transforming it into a regular task.&lt;br&gt;
&lt;strong&gt;Historical Records for Completed Tasks:&lt;/strong&gt; Completed or past-due tasks get recorded as historical records. This not only preserves a comprehensive history but also prevents miscalculations when editing the entire schedule in the future.&lt;/p&gt;

&lt;p&gt;The refined approach avoids the computational intensity of creating a separate database entry for each instance of a recurring task. Instead, it ensures infinite forward visibility by generating instances programmatically based on recurring patterns. We could also improve on read performance by introducing a caching layer.&lt;br&gt;
That's it! Let me know if you've any suggestions for this design, I'd love to hear and learn more!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Helpful Links&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://martinfowler.com/apsupp/recurring.pdf"&gt;https://martinfowler.com/apsupp/recurring.pdf&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
