群组成员资格的高效时间点查询

时间:2014-02-18 09:21:53

标签: algorithm data-structures point-in-time

我们有这样的场景:

  • 数百万条记录(记录1,记录2,记录3 ......)
  • 分成数百万个小型非交叉群体(A组,B组,C组......)
  • 会员资格会逐渐变化,即记录可能会重新分配给另一个团体。

我们正在重新设计数据模式,我们需要支持的一个用例被赋予特定记录,找到在给定时间点属于同一组的所有其他记录。或者,这可以被认为是两个单独的查询,例如:

  1. 三年前,Record 15544属于哪个组? (将此组称为 g )。
  2. 三年前哪些记录属于 g 群组?
  3. 假设我们使用关系数据库,记录和组之间的关联可以使用记录ID和组ID的两列表轻松建模。允许历史查询的常用方法是添加时间戳列。这使我们能够回答以下问题:

    1. 找到记录15544的行,其中包含给定日期之前的最新时间戳。这告诉我们Group g
    2. 查找属于 g 的所有
    3. 的所有记录。
    4. 对于这些记录中的每一个,找到在给定日期之前具有最新时间戳的行。如果这表示该记录当时在 g 组中,则将其添加到结果集中。
    5. 这不是太糟糕(假设表是由记录ID和组ID单独索引的),甚至可能是刚刚描述的朴素表结构的最佳算法,但它确实需要为找到的每个记录进行索引查找在第2步中。是否有替代数据结构可以更有效地回答查询?


      ETA:这只是系统的几个用例中的一个,因此我们不希望加快此查询,代价是对当前分组的查询速度较慢,我们也不想要在太空消费等方面付出巨大代价。

1 个答案:

答案 0 :(得分:1)

如何创建两个表:

  1. (recordID,time-> groupID) - 键是recordID,时间 - 排序依据 recordID,次要的时间(让它为map1
  2. (groupID,time-> List) - 键是groupID,时间 - 排序依据 recordID,次要的时间(让它为map2
  3. 每次更改记录:

    • 检索要更改的记录的当前groupID
    • 设置t <- current time
    • 为旧组map1创建一个新条目:(oldGroupID,t,list') - 其中list'是相同的列表,但没有您刚从那里移出的条目。
    • 为新组添加新条目map1(newGroupId,t,list'') - 其中list''是新组的旧列表,并添加了更改后的记录。
    • 向map1
    • 添加新条目(recordId,t,newGroupId)

    在查询期间:

    • 您需要在map2中找到“最接近”且小于的条目 (recordId,desired_time) - 这是经典的O(logN)操作 排序数据结构。
    • 这将为您提供所需时间所属的组g
    • 现在,请查看map1,类似于条目最近但小于(g,desired_time)的条目。该值是在所需时间在该组中的所有记录的列表。

    这需要相当多的空间(尽管是常数因素......),但每个操作都是O(logN) - 其中N是记录更改的数量。

    主要存储在磁盘上的条目的有效排序DS是B+ tree,它也是由许多关系DS实现实现的。