Sql 在关系数据模型中表示时间表/时间表

Sql 在关系数据模型中表示时间表/时间表,sql,oracle,Sql,Oracle,我们有一个外汇定价系统,其中我们需要表示在给定的一周中的某一天+某一天的某个时间处于活动状态的一组ECN/交易所。So可以表示开始时间、结束时间和作为行活动的ECN名称。复合主键将是开始时间+结束时间+ECN。例如,伦敦时间8:00,纽约时间14:30,EBS。现在不能有重叠或重复。人们可以编辑记录,并且约束应该保持不变 如何在数据库级别最好地表示这一点?如果它有助于我们使用Oracle,但Oracle不可知解决方案是首选 现在忽略时区和夏令时,这是不可能避免重叠的。 < P>我会给出两个答案,

我们有一个外汇定价系统,其中我们需要表示在给定的一周中的某一天+某一天的某个时间处于活动状态的一组ECN/交易所。So可以表示开始时间、结束时间和作为行活动的ECN名称。复合主键将是开始时间+结束时间+ECN。例如,伦敦时间8:00,纽约时间14:30,EBS。现在不能有重叠或重复。人们可以编辑记录,并且约束应该保持不变

如何在数据库级别最好地表示这一点?如果它有助于我们使用Oracle,但Oracle不可知解决方案是首选


现在忽略时区和夏令时,这是不可能避免重叠的。

< P>我会给出两个答案,首先,考虑RFC 5545的重复规则格式,并在应用层验证。p> 因为这可能不是你想要的答案,我也建议你把这周的任何一点都看作是从本周开始的一个补偿

然后,您可以构建一个转换列表,该列表定义了exchange打开或关闭一周的偏移量。所需的唯一约束是验证偏移是否有效(少于7天),以及从开放到关闭的转换之后是否只跟随从关闭到开放的转换(反之亦然)

我没有打开一个oracle盒子来玩,但下面是T-SQL中的一个示例:

create table #sched (exchangeID int, weekOffset int, isOpen bit)
insert into #sched 
values (1, 400, 1),
    (1, 800, 0),
    (1, 1200, 1),
    (1, 1700, 0);

-- constraints are that isOpen cannot be repeated.  1->0->1 is valid, 1->1->0 is not

declare @coffset int,
    @weekStart datetime;

set @weekstart = dateadd(week, datediff(week, 0, getdate()), 0);
set @coffset = datediff(minute, @weekStart, getdate());

with trans (uniqid, exch, offset, isopen)
as 
(
    select ROW_NUMBER() OVER (ORDER BY weekoffset), *
    from (
        SELECT exchangeID, weekoffset - 7*24*60 as weekoffset, isopen from #sched
        UNION 
        select exchangeID, weekoffset, isopen from #sched
        UNION
        select exchangeID, weekoffset + 7*24*60, isopen from #sched
    ) as inr
)
select *,
    CASE pt.IsOpen 
        WHEN 1 THEN 'Exchange is now open and will close at ' + CAST(DATEADD(minute, nt.offset, @weekstart) as varchar(20)) 
        ELSE 'Exchange is now closed and will open at ' + CAST(DATEADD(minute, nt.offset, @weekstart) as varchar(20)) END
from (
    SELECT MIN(uniqid) as nextTransition
    FROM trans
    WHERE offset > @coffset
) as n
cross join (
    SELECT MAX(uniqid) as prevTransition
    FROM trans
    WHERE offset <= @coffset
) as p
inner join trans as nt on nt.uniqid = nextTransition
inner join trans as pt on pt.uniqid = prevTransition

drop table #sched
| NEXTTRANSITION | PREVTRANSITION | UNIQID | EXCH | OFFSET | ISOPEN |                                                   COLUMN_10 |
|----------------|----------------|--------|------|--------|--------|-------------------------------------------------------------|
|              9 |              8 |      9 |    1 |  10480 |      1 | Exchange is now closed and will open at Feb 24 2014  6:40AM |