4

我们目前正在开发一个应用程序,其中多个实体具有关联的营业时间。开放时间可能跨越多天,也可能包含在一天之内。

前任。周一 6:00 开放,周五 18:00 关闭。

或者

周一 06:00 开放,周一 15:00 关闭。

此外,一个实体每天可能有多组营业时间。到目前为止,我发现的最好的设计是定义一个开放时间,包括以下内容:

开始日、开始时间、结束日和结束时间。

这种设计允许所有需要的灵活性。但是,数据完整性成为一个问题。我似乎找不到一个不允许重叠跨度的解决方案(在数据库中)。

请分享你的想法。

编辑:数据库是 Microsoft SQL Server 2008 R2

4

7 回答 7

2

考虑存储您的 StartDay 和 StartTime,然后为其打开的小时数设置一个值。这将确保您的结束日期时间在开幕之后。

OpenDate -- day of week? e.g. 1 for Monday
OpenTime -- time of day. e.g. 08:00
DurationInHours -- in hours or mins. e.g.   15.5
于 2011-01-25T17:58:34.160 回答
1

必须在应用程序级别检测和防止重叠时间段。当然,您可以尝试在数据库中使用触发器,但我认为这不是数据库问题。您提出的结构很好,但您的应用程序逻辑必须处理重叠。

于 2011-01-25T17:59:54.150 回答
1

假设一个健壮的触发器框架

在插入/更新时,您将检查新的开始日期或结束日期是否在任何现有范围内。如果是这样,那么您将回滚更改。

CREATE TRIGGER [dbo].[mytable_iutrig] on [mytable] FOR INSERT, UPDATE AS

IF (SELECT COUNT(*)
FROM inserted, mytable
WHERE (inserted.startdate < mytable.enddate 
          AND inserted.startdate > mytable.startdate)
      OR (inserted.enddate < mytable.enddate 
          AND inserted.enddate > mytable.startdate)) > 0 
BEGIN
    RAISERROR --error number
    ROLLBACK TRANSACTION
END
于 2011-01-25T18:15:07.743 回答
1

在 SimpleTalk 网站上,Joe Celko 有一篇文章在这里讨论了类似的问题,并提出了一个优雅但复杂的解决方案。这可能适用于您的情况。

于 2011-01-25T18:52:10.680 回答
0

具有单列 TimeOfChangeBetweenOpeningAndClosing 的表?

更严重的是,我可能不会太担心提出一个单一的数据库结构来表示所有内容,最终你可能想要一个涉及重复、计划关闭等的系统。持久化表示这些的对象,然后评估它们以找到关闭/打开时间。

于 2011-01-25T17:59:39.960 回答
0

这看起来是一个很好的解决方案,但您必须编写一个自定义验证函数。内置的数据库验证(即唯一的、小于 x 等)不会在这里解决问题。为确保您没有重叠跨度,每次将记录插入数据库时​​,您都必须选择现有记录并比较...

于 2011-01-25T18:00:15.880 回答
0

首先是逻辑,如果一个的起始值落在另一个的开始/结束之间,则两个跨度将重叠。如果我们将日期时间结合起来,而不是 date1,time1 和 date2,time2,这会容易得多。因此,查找重叠的查询如下所示。

select openingId
  from opening o1
  join opening o2 on o1.startDateTime 
             between o2.startDateTime
                 AND o2.endDateTime

如果找到匹配项,您可以将其放入触发器中并引发错误。

于 2011-01-25T18:12:39.397 回答