我有以下具有特定名称的组,具体取决于日期:
Group 1: 3/30/2017 to present: status 'on'
Group 2: 3/30/2017 to present: status 'on'
Group 3: 3/30/2017 to present: status 'on'
Group 4: 3/30/2017 to 6/1/2017: status 'off'; 6/2/2017 to present: status: 'on'
Group 5: 3/30/2017 to present: status 'off'
Group 6: 3/30/2017 to 7/10/2017: status 'off'; 7/11/2017 to present: status 'on'
我试图将此信息转换为有效的数据库表,以便我可以指定特定日期的状态更改。
我有一个近乎实时运行的流程,它会检查每个群组的状态,并根据状态执行各种流程。
我想出了以下内容,但我认为这还不够:
Group Effective Date Termination Date Status
Group 1 '2017-03-30' NULL On
Group 2 '2017-03-30' NULL On
Group 3 '2017-03-30' NULL On
Group 4 '2017-03-30' '2017-06-01' On
Group 4 '2017-06-02' NULL Off
Group 5 '2017-03-30' NULL Off
Group 6 '2017-03-30' '2017-07-10' Off
Group 6 '2017-07-11' NULL On
因此,如果我历史地运行我的日常流程,我希望它能够查阅该表并确定该组的状态。如果我实时运行我的流程,我希望能够查阅表并确定状态。如果我想在特定时间点更改状态,请输入组和状态的终止日期并开始换行。
我无法想象这是一个很好的方法。
寻找见解。
提前致谢。
答案 0 :(得分:1)
这是一种使用我称之为Version Normal Form(vnf)的方法。它适用于具有平滑,不间断的状态变化链的实体。也就是说,没有间隙(一个状态仅在另一个状态生效时结束)或重叠(任何时候只有一个状态有效)。
使用除状态之外的所有组信息设计Group
表。
create table Group(
ID int auto generated primary key,
... ... -- all other Group data
);
现在创建一个Status
表,其中包含一个State字段和一个日期字段 - 状态生效的日期。
create table GroupStatus(
ID int references Group( ID ),
EffDate date not null default Now(),
State char( 1 ) check (State in ('Y', 'N')),
constraint PK_GroupStatus primary key( ID, EffDate )
);
有关GroupStatus表的两个要点需要考虑:
我使用单个字符'Y'(表示开启)和'N'(表示关闭),但您可以按照您想要的任何方式定义状态。这只是为了说明。
EffDate
字段可能必须是Date
,Datetime
或Timestamp
类型,具体取决于您的特定DBMS。 Now()
仅表示使用DBMS中可用的任何方法的“当前日期和时间”。
GroupStatus数据如下所示:
ID EffDate State
1 '2017-03-30' Y
2 '2017-03-30' Y
3 '2017-03-30' Y
4 '2017-03-30' Y
4 '2017-06-02' N
5 '2017-03-30' N
6 '2017-03-30' N
6 '2017-07-11' Y
对于强制执行的数据完整性级别,设计非常简单。查询会有点复杂。
要查看第1组的当前状态:
select g.ID as 'Group', s.EffDate as 'Effective Date',
case s.State when 'Y' then 'On' else 'Off' end as Status
from Group g
join GroupStatus s
on s.ID = g.ID
and s.EffDate =(
select Max( s1.EffDate )
from GroupStatus s1
where s1.ID = g.ID
and s1.EffDate <= Now()
)
where g.ID = 1;
要查看所有组的当前状态,请忽略where
子句。要查看在特定日期生效的第1组的状态,只需将子查询中的Now()
更改为加载了感兴趣的日期和时间的变量。
实际上,将所有组的当前状态查询设置为视图。然后您的日常流程可以简单地查询:
select ID, Status from CurrentGroupStatus;
由于您知道不存在间隙或重叠,因此您知道每个组只有一行。
假设在3月30日插入第6组条目后,您已经知道它将被打开的日期。您可以继续插入具有未来日期(7月11日)的GroupStatus条目,并且“当前”查询和视图将继续显示正确的状态(关闭),直到该日期到来,此时ON状态将开始出现。
在视图上创建“而不是”触发器以正确使用基础表,您的应用甚至不必知道数据存储方式的详细信息。
这为您提供了坚实的数据完整性,并且在查看和操作数据方面具有很大的灵活性。