在SQL中存储依赖日期

在SQL中存储依赖日期,sql,Sql,在很多情况下,我的数据库结构类似于: 表事件(EventID INT PrimaryKey、开始日期时间、完成日期时间);及 表EventTask(EventTaskID INT PrimaryKey、EventID INT ForeignKey、TaskStart DATETIME、TaskFinish DATETIME) 事件和事件任务等之间的1对多关系 当事件表中的日期更改时,EventTask日期也需要更改—使用提供的日期函数并不困难,但日期操作总是有点棘手 我想知道用两个整数替换Tas

在很多情况下,我的数据库结构类似于:

表事件(EventID INT PrimaryKey、开始日期时间、完成日期时间);及 表EventTask(EventTaskID INT PrimaryKey、EventID INT ForeignKey、TaskStart DATETIME、TaskFinish DATETIME)

事件和事件任务等之间的1对多关系

当事件表中的日期更改时,EventTask日期也需要更改—使用提供的日期函数并不困难,但日期操作总是有点棘手

我想知道用两个整数替换TaskStart DATETIME和TaskFinish DATETIME是否更好:一个用于Event.Start偏移量(与Event.Start不同的分钟数)和一个持续时间

这样,日期更新变得更加健壮,因为只有一行需要更新


(我规定这仅适用于事件任务日期完全依赖于事件日期的情况)

是的,我觉得这完全合理。主要的缺点是为了找到EventTasks的实际时间,您必须执行计算。这会减慢返回时间的速度,尤其会影响过滤器中涉及EventTask时间的查询,例如“查找在时间X和Y之间发生的所有任务”。这些任务以前可能使用过索引,但现在不能再使用了。

是的,这听起来完全合理。主要的缺点是为了找到EventTasks的实际时间,您必须执行计算。这会减慢返回时间的速度,尤其会影响过滤器中涉及EventTask时间的查询,例如“查找在时间X和Y之间发生的所有任务”。这些任务以前可能使用过索引,但现在无法再使用了。

如果使用SQL 2008,则可以使用数据类型

如果您希望“直接”获取数据,而不需要太多麻烦,您可以使用,但是如果结果不确定,您可能无法在这些数据上创建索引(或让它们存储结果)

您的结构如下所示:

TABLE [Event] (
    EventID INT PrimaryKey, 
    Start DATETIME, 
    Finish DATETIME)

TABLE [EventTask](
    EventTaskID INT PrimaryKey, 
    EventID INT ForeignKey, 
    TaskStart DATETIMEOFFSET, 
    TaskFinish DATETIMEOFFSET,
    EventTaskStart as [getStartDateByEvent](eventId, TaskStart) <PERSISTED>,
    EventTaskStop as [getStopDateByEvent](eventId, TaskStart) <PERSISTED>,
    )

FUNCTION [getStartDateByEvent](eventId, TaskStart) as DATETIME
BEGIN
    SELECT [EVENT].start + TaskStart from [EVENT] WHERE [EVENT].EVENTID = eventID
END

FUNCTION [getStartDateByEvent](eventId, TaskStop) as DATETIME
BEGIN
    SELECT [EVENT].[finish] + TaskStop from [EVENT] WHERE [EVENT].EVENTID = eventID
END
表[事件](
EventID INT PrimaryKey,
开始日期时间,
完成日期(时间)
表[EventTask](
EventTaskID INT PrimaryKey,
EventID INT ForeignKey,
任务开始日期时间偏移量,
任务完成日期时间偏移量,
EventTaskStart为[getStartDateByEvent](eventId,TaskStart),
EventTaskStop作为[getStopDateByEvent](eventId,TaskStart),
)
函数[getStartDateByEvent](eventId,TaskStart)作为日期时间
开始
选择[EVENT].start+TaskStart from[EVENT],其中[EVENT].EVENTID=EVENTID
结束
函数[getStartDateByEvent](eventId,TaskStop)作为日期时间
开始
从[EVENT]中选择[EVENT].[finish]+TaskStop,其中[EVENT].EVENTID=EVENTID
结束

如果您使用的是SQL 2008,则可以使用数据类型

如果您希望“直接”获取数据,而不需要太多麻烦,您可以使用,但是如果结果不确定,您可能无法在这些数据上创建索引(或让它们存储结果)

您的结构如下所示:

TABLE [Event] (
    EventID INT PrimaryKey, 
    Start DATETIME, 
    Finish DATETIME)

TABLE [EventTask](
    EventTaskID INT PrimaryKey, 
    EventID INT ForeignKey, 
    TaskStart DATETIMEOFFSET, 
    TaskFinish DATETIMEOFFSET,
    EventTaskStart as [getStartDateByEvent](eventId, TaskStart) <PERSISTED>,
    EventTaskStop as [getStopDateByEvent](eventId, TaskStart) <PERSISTED>,
    )

FUNCTION [getStartDateByEvent](eventId, TaskStart) as DATETIME
BEGIN
    SELECT [EVENT].start + TaskStart from [EVENT] WHERE [EVENT].EVENTID = eventID
END

FUNCTION [getStartDateByEvent](eventId, TaskStop) as DATETIME
BEGIN
    SELECT [EVENT].[finish] + TaskStop from [EVENT] WHERE [EVENT].EVENTID = eventID
END
表[事件](
EventID INT PrimaryKey,
开始日期时间,
完成日期(时间)
表[EventTask](
EventTaskID INT PrimaryKey,
EventID INT ForeignKey,
任务开始日期时间偏移量,
任务完成日期时间偏移量,
EventTaskStart为[getStartDateByEvent](eventId,TaskStart),
EventTaskStop作为[getStopDateByEvent](eventId,TaskStart),
)
函数[getStartDateByEvent](eventId,TaskStart)作为日期时间
开始
选择[EVENT].start+TaskStart from[EVENT],其中[EVENT].EVENTID=EVENTID
结束
函数[getStartDateByEvent](eventId,TaskStop)作为日期时间
开始
从[EVENT]中选择[EVENT].[finish]+TaskStop,其中[EVENT].EVENTID=EVENTID
结束
Jon Skeet:

进行计算。那将 减慢任何返回的速度 时间,尤其是伤害 中涉及EventTask时间的查询 过滤器-例如“查找我的所有任务” 发生在X和Y之间。”

在我看来,您在编写基本数据完整性约束时已经有了这一要求,例如,事件的任务日期必须在事件本身的日期内,例如,将架构扩展到SQL DLL:

CREATE TABLE Event 
(
 EventID INTEGER NOT NULL PRIMARY KEY, 
 event_Start DATETIME NOT NULL, 
 event_Finish DATETIME NOT NULL, 
 CHECK (event_Start < event_Finish), 
 UNIQUE (event_Start, event_Finish, EventID)
)

CREATE TABLE EventTask 
(
 EventTaskID INTEGER NOT NULL PRIMARY KEY, 
 EventID INTEGER NOT NULL, 
 event_Start DATETIME NOT NULL, 
 event_Finish DATETIME NOT NULL, 
 FOREIGN KEY (event_Start, event_Finish, EventID)
    REFERENCES Event (event_Start, event_Finish, EventID)
    ON DELETE CASCADE
    ON UPDATE CASCADE, 
 event_task_START DATETIME NOT NULL, 
 event_task_Finish DATETIME NOT NULL, 
 CHECK (event_task_Start < event_task_Finish), 
 CHECK (event_Start <= event_task_Start), 
 CHECK (event_Finish <= event_task_Finish)
);
创建表事件
(
EventID INTEGER非空主键,
事件\u开始日期时间不为空,
事件\u完成日期时间不为空,
检查(事件开始<事件结束),
唯一(事件开始、事件结束、事件ID)
)
创建表事件任务
(
EventTaskID整型非空主键,
EventID整数不为空,
事件\u开始日期时间不为空,
事件\u完成日期时间不为空,
外键(事件开始、事件结束、事件ID)
引用事件(事件开始、事件结束、事件ID)
关于删除级联
在更新级联上,
事件\u任务\u开始日期时间不为空,
事件\任务\完成日期时间不为空,
检查(事件任务开始<事件任务完成),
检查(事件开始Jon Skeet:

进行计算。这将 减慢任何返回的速度 时间,尤其是伤害 中涉及EventTask时间的查询 过滤器-例如“查找我的所有任务” 发生在X和Y之间。”

在我看来,您在编写基本数据完整性约束时已经有了这一要求,例如,事件的任务日期必须在事件本身的日期内,例如,将架构扩展到SQL DLL:

CREATE TABLE Event 
(
 EventID INTEGER NOT NULL PRIMARY KEY, 
 event_Start DATETIME NOT NULL, 
 event_Finish DATETIME NOT NULL, 
 CHECK (event_Start < event_Finish), 
 UNIQUE (event_Start, event_Finish, EventID)
)

CREATE TABLE EventTask 
(
 EventTaskID INTEGER NOT NULL PRIMARY KEY, 
 EventID INTEGER NOT NULL, 
 event_Start DATETIME NOT NULL, 
 event_Finish DATETIME NOT NULL, 
 FOREIGN KEY (event_Start, event_Finish, EventID)
    REFERENCES Event (event_Start, event_Finish, EventID)
    ON DELETE CASCADE
    ON UPDATE CASCADE, 
 event_task_START DATETIME NOT NULL, 
 event_task_Finish DATETIME NOT NULL, 
 CHECK (event_task_Start < event_task_Finish), 
 CHECK (event_Start <= event_task_Start), 
 CHECK (event_Finish <= event_task_Finish)
);
创建表事件
(
EventID INTEGER非空主键,
事件\u开始日期时间不为空,
事件\u完成日期时间不为空,
检查(事件开始<事件结束),
唯一(事件开始、事件结束、事件ID)
)
创建表事件任务
(
EventTaskID整型非空主键,
EventID整数不为空,
事件\u开始日期时间不为空,
事件\u完成日期时间不为空,
外键(事件开始、事件结束、事件ID)
引用事件(事件开始、事件结束、事件ID)
关于删除级联
在更新级联上,
即使