在(My)SQL数据库中存储事件时间的最佳方法
我正在尝试确定在MySQL数据库中存储事件时间的最佳方法。这些事件应尽可能灵活,并且能够表示"单个事件"(在某个时间开始,不一定需要结束时间),"全天"和"多天"事件,重复事件,重复全天事件,可能是"每月第3个星期六"类型的事件等。
请提出一些经过验证的数据库方案。
解决方案
cron会这样做吗?以此方式记录开始时间和结束时间。
表:事件
- 开始时间(dateTime)
- EndTime(dateTime)为null,无结束时间
- RepeatUnit(int)null = noRepeat,1 =小时,2 =天,3 =周,4 = dayOfMonth,5 =月,6 =年
- NthDayOfMonth(int)
- RepeatMultiple(int),例如,将RepeatUnit设置为3,每两周将其设置为2
- ID-如果需要,StartTime可能适合我们唯一地标识事件。
- 名称(字符串)-为事件指定的名称
这可能会有所帮助。当重复出现时,需要大量的代码来解释。分辨率低于重复单位的部分时间字段必须忽略。做这个月的第三个星期六也不是一件容易的事……仅需要NthDayOfMonth信息才能执行这种功能。
与计算出重复出现的位置所需的代码相比,为此所需的数据库模式很简单。
我们需要两个表。一种用于存储重复事件(表重复事件),另一种用于存储事件(表事件)。简单条目仅存储在事件表中。重复条目存储在repeatevent表中,重复事件的所有单个条目也存储在事件表中。这意味着每次输入重复条目时,都必须输入所有单个结果条目。我们可以通过使用触发器或者作为业务逻辑的一部分来做到这一点。
这种方法的优点是查询事件很简单。它们都在事件表中。如果没有在事件表中存储重复事件,我们将拥有复杂的SQL或者业务逻辑,这将使系统运行缓慢。
create table repeatevent ( id int not null auto_increment, type int, // 0: daily, 1:weekly, 2: monthly, .... starttime datetime not null, // starttime of the first event of the repetition endtime datetime, // endtime of the first event of the repetition allday int, // 0: no, 1: yes until datetime, // endtime of the last event of the repetition description varchar(30) ) create table event ( id int not null auto_increment, repeatevent null references repeatevent, // filled if created as part of a repeating event starttime datetime not null, endtime datetime, allday int, description varchar(30) )
我开发了一个计划程序应用程序,该程序大致遵循iCalendar标准(用于记录事件)。我们可能需要阅读RFC 2445或者Apple Inc. icalendar架构发布的该架构,以查看它们是否与问题有关。
我的数据库架构(当时未考虑重复/全天事件)
event (event_id, # primary key dtstart, dtend, summary, categories, class, priority, summary, transp, created, calendar_id, # foreign key status, organizer_id, # foreign key comment, last_modified, location, uid);
上表中的外键calendar_id
引用了这个
calendar(calendar_id, # primary key name);
而organizer_id
引用了这一点(缺少其他属性,例如通用名等)
organizer(organizer_id, # primary key name);
我们可能会发现其他可读性更高的文档位于此处
希望这可以帮助
使用datetime和mysql内置的NOW()函数。在过程开始时创建记录,在过程结束时更新跟踪结束时间的列。