我们目前正在开发一个应用程序,其中多个实体具有相关的营业时间。开放时间可能跨越多天,或者可能在一天内被包含。
实施例。周一开放时间为6:00,周五18:00关闭。
或者
周一06:00开放,周一15:00关闭。
此外,实体每天可能有多套营业时间。 到目前为止,我发现的最佳设计是定义一个开放时间,包括以下内容:
StartDay,StartTime,EndDay和EndTime。
此设计可实现所有必需的灵活性。但是,数据完整性成为一个问题。我似乎找不到一个不允许重叠跨度的解决方案(在数据库中)。
请分享您的想法。
编辑:数据库是Microsoft SQL Server 2008 R2
答案 0 :(得分: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
答案 1 :(得分: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
答案 2 :(得分:1)
Joe Celko在SimpleTalk网站上发表了一篇关于here的文章,该文章讨论了类似的问题,如果是复杂的解决方案,我会提出优雅。这可能适用于您的情况。
答案 3 :(得分:0)
一个包含单列TimeOfChangeBetweenOpeningAndClosing的表?
更严重的是,我可能不会过多担心单个数据库结构来表示所有内容,最终你可能想要一个涉及重现,计划闭包等的系统。坚持代表那些的对象,然后评估他们找出关闭/开放时间。
答案 4 :(得分:0)
检测和防止重叠时间段必须在应用程序级别完成。当然,您可以尝试在数据库中使用触发器,但在我看来,这不是数据库问题。您提出的结构很好,但您的应用程序逻辑必须处理重叠。
答案 5 :(得分:0)
这看起来是一个很好的解决方案,但您必须编写自定义验证功能。内置的数据库验证(即唯一的,小于x等)不会在这里削减它。为了确保您没有重叠的跨度,每次将记录插入数据库时,您将不得不选择现有记录并进行比较......
答案 6 :(得分:0)
首先,如果一个的起始值落在另一个的开始/结束之间,则两个跨度将重叠。如果我们将日期时间组合起来,而不是date1,time1和date2,time2,这会容易得多。因此,查找重叠的查询如下所示。
select openingId
from opening o1
join opening o2 on o1.startDateTime
between o2.startDateTime
AND o2.endDateTime
如果找到匹配项,您可以将其置于触发器中并抛出错误。