Database design 拯救一组人和其中的每一个变化

Database design 拯救一组人和其中的每一个变化,database-design,Database Design,我遇到的这种情况是,我需要将人员包括在一个组中。 为此,我创建了一个如图所示的关系 组在不断变化(一天几次,一个组中添加和删除几个人)。 每次组发生变化时,我都需要保存组的状态(哪些人在组中,以及在哪些日期之间),以便以后进行分析 为此,每次在组中添加或删除人员时,我的应用程序都会执行以下操作: 获取当前组(以及其中的人员) 创建组中人员的列表(在内存中),排除或添加要删除或添加的人员 更新当前组的结束日期 创建一个新组 在小组中插入人员(第2点列表中的人员) 返回新的GroupId 此Gro

我遇到的这种情况是,我需要将人员包括在一个组中。
为此,我创建了一个如图所示的关系

组在不断变化(一天几次,一个组中添加和删除几个人)。
每次组发生变化时,我都需要保存组的状态(哪些人在组中,以及在哪些日期之间),以便以后进行分析

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

  • 获取当前组(以及其中的人员)
  • 创建组中人员的列表(在内存中),排除或添加要删除或添加的人员
  • 更新当前组的结束日期
  • 创建一个新组
  • 在小组中插入人员(第2点列表中的人员)
  • 返回新的GroupId
  • 此GroupId用于保存组中更改的日志

    一些移动后生成的数据示例:

    PERSON:
    PersonId   Name
     1         John
     2         Sally
     3         Pete
    
    -添加John:

    GROUP:
    GroupId   Description   StartDate            EndDate
     1        John added    31/7/2009 11:00:00   null
    
    GROUPPERSON:
    GroupPersonId   GroupId   PersonId
     1               1         1
    
    insert into group_members (groupId, personId, startDate)
    values (1, 1, '1/7/2009 11:00:00');
    
    -添加Sally:

    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
    
    这是我提出的设计,但由于我是一名开发人员,恐怕我看不清楚。

    你能告诉我实现相同功能的其他(更好的)方法吗?

    从你提供的不完整信息来看,你应该保留一个移动表:

    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}
    

    注意,宇宙可以从运动表中计算出来。(当然,随着表格的增长,这种计算会变得更加昂贵,但我只是提出一个基本的建议。)

    我不清楚您是如何知道第2组与第1组是“同一”组的,还是这些信息并不重要?这里是另一个解决方案,假设即使添加了新成员,组仍然存在(这似乎是合理的!)

    添加John:

    GROUP:
    GroupId   Description   StartDate            EndDate
     1        John added    31/7/2009 11:00:00   null
    
    GROUPPERSON:
    GroupPersonId   GroupId   PersonId
     1               1         1
    
    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);
    
    选择personId
    来自集团成员
    其中groupId=1
    和startDate=:给定的_datetime);
    
    谢谢您的回答。我添加了更多信息来解释我的实现。为了知道我想要的是哪个组,我将当前组Id保存到另一个位置,因此在创建新组之前,我检查当前组是什么,并替换它。谢谢你的回答。