拯救一群人及其中的每一个变化

时间:2009-07-31 10:25:08

标签: database-design

我有这种情况,我需要将人员纳入一个团体 为此,我创建了一个像图像中所示的关系。

table diagram http://img189.imageshack.us/img189/6076/imagetkr.png

小组不断变化(每天数次,添加几个人并从组中删除) 我需要在每次更改时保存组的状态(哪些人在其中以及在哪些日期之间),以供以后分析。

为此,每次在Group中添加或删除Person时,我的应用程序都会执行以下操作:

  1. 获取当前组(以及其中的人员)
  2. 在组中创建人员列表(在内存中),排除或添加要删除或添加的人员
  3. 更新当前组的EndDate
  4. 创建一个新组
  5. 在群组中插入人员(来自第2点的列表)
  6. 返回新的GroupId
  7. 此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
    

    这是我提出的设计,但由于我是一名开发人员,我担心我没有清楚地看到它。
    你能指出其他(更好)的方法来实现相同的功能吗?

2 个答案:

答案 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);