提问人:deceze 提问时间:9/19/2008 更新时间:11/17/2015 访问量:8291
在 (My)SQL 数据库中存储事件时间的最佳方式
Best way to store event times in (My)SQL database
问:
我正在尝试确定在MySQL数据库中存储事件时间的最佳方式。这些应该尽可能灵活,能够表示“单个事件”(在某个时间开始,不一定需要结束时间)、“全天”和“多天”事件、重复事件、重复全天事件、可能是“每月第三个星期六”类型的事件等。
请提出一些久经考验的数据库方案。
答:
cron 也是这样做的?以这种方式记录开始和结束时间。
评论
表:事件
- 开始时间 (dateTime)
- EndTime (dateTime) null 表示无结束时间
- RepeatUnit (int) null = noRepeat,1 = 小时,2 = 天,3 = 周,4 = dayOfMonth,5 = 月,6 = 年
- NthDayOfMonth (整数)
- RepeatMultiple (int) 例如,将 RepeatUnit 设置为 3,每两周将其设置为 2
- Id - 如果需要,StartTime 可能适合你唯一标识事件。
- Name (string) - 指定给事件的名称(如果需要)
这可能会有所帮助。当重复出现时,需要相当数量的代码来解释。必须忽略分辨率低于重复单位的部分时间字段。做这个月的第三个星期六也不容易......NthDayOfMonth 信息仅用于执行此类功能。
与计算重复位置所需的代码相比,此操作所需的数据库架构很简单。
评论
您需要两个表。一个用于存储重复事件(表 repeatevent),另一个用于存储事件(表 event)。简单条目仅存储在事件表中。重复条目存储在 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);
while 引用这个(缺少其他属性,如通用名称等)organizer_id
organizer(organizer_id, # primary key
name);
您可能会发现另一个更具可读性的文档位于此处
希望这会有所帮助
评论
使用 datetime 和 mysql 内置的 NOW() 函数。在流程开始时创建记录,更新跟踪流程结束时结束时间的列。
评论