我有这种情况,我需要将人员纳入一个团体 为此,我创建了一个像图像中所示的关系。
table diagram http://img189.imageshack.us/img189/6076/imagetkr.png
小组不断变化(每天数次,添加几个人并从组中删除) 我需要在每次更改时保存组的状态(哪些人在其中以及在哪些日期之间),以供以后分析。
为此,每次在Group中添加或删除Person时,我的应用程序都会执行以下操作:
此GroupId用于保存组中更改的日志。
一些动作后生成的数据示例:
PERSON:
PersonId Name
1 John
2 Sally
3 Pete
- 添加约翰:
GROUP:
GroupId Description StartDate EndDate
1 John added 31/7/2009 11:00:00 null
GROUPPERSON:
GroupPersonId GroupId PersonId
1 1 1
- 添加莎莉:
GROUP:
GroupId Description StartDate EndDate
1 John added 31/7/2009 11:00:00 31/7/2009 11:35:00
2 Sally added 31/7/2009 11:35:00 null
GROUPPERSON:
GroupPersonId GroupId PersonId
1 1 1
2 2 1
3 2 2
- 添加皮特:
GROUP:
GroupId Description StartDate EndDate
1 John added 31/7/2009 11:00:00 31/7/2009 11:35:00
2 Sally added 31/7/2009 11:35:00 31/7/2009 12:10:00
3 Pete added 31/7/2009 12:10:00 null
GROUPPERSON:
GroupPersonId GroupId PersonId
1 1 1
2 2 1
3 2 2
4 3 1
5 3 2
6 3 3
- 删除约翰:
GROUP:
GroupId Description StartDate EndDate
1 John added 31/7/2009 11:00:00 31/7/2009 11:35:00
2 Sally added 31/7/2009 11:35:00 31/7/2009 12:10:00
3 Pete added 31/7/2009 12:10:00 31/7/2009 12:24:00
4 John removed 31/7/2009 12:24:00 null
GROUPPERSON:
GroupPersonId GroupId PersonId
1 1 1
2 2 1
3 2 2
4 3 1
5 3 2
6 3 3
7 4 2
8 4 3
这是我提出的设计,但由于我是一名开发人员,我担心我没有清楚地看到它。
你能指出其他(更好)的方法来实现相同的功能吗?
答案 0 :(得分:1)
根据您提供的不完整信息,您似乎应该保留一个Movements表:
Date/Time Group Action Person // The Universe
17/7/2009 10:01:00 Group A Enter John // {A: John}
17/7/2009 10:02:00 Group A Enter Sally // {A: John, Sally}
17/7/2009 11:22:23 Group B Enter Pete // {A: John, Sally}, {B: Pete}
17/7/2009 11:34:45 Group A Exit John // {A: Sally}, {B: Pete}
请注意,Universe只能从移动表中计算出来。 (当然随着表格的增长,这种计算变得更加昂贵,但我只是提出了一个基本建议。)
答案 1 :(得分:1)
我不清楚你怎么知道第2组与第1组是“相同”的组 - 或者这些信息不重要?这是另一个解决方案,假设即使添加了新成员,组仍然存在(这似乎是合理的!)
create table groups (groupId integer primary key);
create table persons (personId integer primary key)
create table group_member (groupId references groups,
personId references persons,
startDate date,
endDate date);
添加约翰:
insert into group_members (groupId, personId, startDate)
values (1, 1, '1/7/2009 11:00:00');
删除约翰:
update group_members
set endDate = '31/7/2009 12:24:00'
where groupId = 1 and personId = 1;
所以在你的例子结束时你有:
PERSON:
PersonId Name
1 John
2 Sally
3 Pete
GROUP
groupId
1
GROUP_MEMBERS:
groupId personId startDate endDate
1 1 1/7/2009 11:00:00 31/7/2009 12:24:00
1 2 31/7/2009 11:35:00
1 3 31/7/2009 12:10:00
要在某个特定日期和时间找出第1组的成员资格:
select personId
from group_members
where groupId = 1
and startDate <= :given_datetime
and (endDate is null or endDate >= :given_datetime);