将订购清单存储在数据库中(间隙方法)

| 我想在Google App Engine数据存储区中保留一个大的有序列表(数百万个元素)。需要快速插入。 最简单的方法是添加一个表示订单的索引属性(或列)\“ order_num \”。例如,列表[A,B,C]将像这样存储:
content   order_num
--------------------
   A         1
   B         2
   C         3  
但是,这不能让您快速插入。例如,如果我想在A后面插入X,则必须将B和C重编号为X的“腾出空间”,即,让B变成3,C变成4,X变成2。这将是一场灾难如果我有数百万个元素。 我找到了一种可行的解决方案,称为“缺口方法”,此处介绍。这种方法在相邻元素之间保持间隔。像这样:
content   order_num
--------------------
   A         1000
   B         2000
   C         3000
当我想在A后面插入X时,我可以简单地将X的order_num设置为(1000 + 2000)/ 2 = 1500,而无需重新编号。 但是随着这些间隙变小,可能需要重新编号。我的问题是,是否有任何已知的重编号策略?并决定差距的大小? 谢谢! 更新 这里更详细。假设我在数据库中有一个元素列表,每个元素都有一个名为my_num的整数属性。 my_num的值是任意正整数。假设我有一个列表[A,B,C,D],它们的my_num为
 element    my_num   
---------------------
   A          5        
   B          2
   C         10
   D          7
现在,让我们定义一个accum()运算符:
accum(n) = element[0].my_num + element[1].my_num + ... + element[n-1].my_num
所以每个元素的累加值是
 element    my_num   accum 
----------------------------
   A          5        5
   B          2        7
   C         10       17
   D          7       24
但是,由于列表会不断更新,因此可能不应该将累加值存储在数据库中。最好保持快速插入。 我想设计一个输入为整数x的查询:
query(x) = element[i] if accum(i-1) < x <= accum(i)
例如,query(11)是C,query(3)是A。 是否可以设计一个数据存储架构以使此查询快速进行?还是唯一的方法是我计划在查询时一个一个地累积它?     
已邀请:
或者,您可以使用小数还是字符串?
content     order
-------------------- 
   A         \'a\' 
   B         \'b\' 
   C         \'c\'
然后在a和b之间插入D,给它取值''aa \' 最好为二进制字符串显示用于生成字符串的算法:如果要在\“ 1011 \”和\“ 1100 \”之间插入内容,请执行以下操作: 值= 1 + 0 *(1/2)+ 1 *(1/4)+ 1 *(1/8) 值= 1 + 1 *(1/2)+ 0 *(1/4)+ 0 *(1/8) 平均,新值= 1 + 0 *(1/2)+ 1 *(1/4)+ 1 *(1/8)+ 1 *(1/16)          新字符串= \“ 10111 \”
content     order
-------------------- 
   A         \'1011\' 
   new!      \'10111\' 
   B         \'1100\' 
   C         \'1101\'
由于您总是将2个值取平均值,因此平均值将始终具有有限的二进制展开和有限的字符串。它有效地定义了一个二叉树。 如您所知,二叉树并不总是平衡良好,换句话说,插入足够多后,某些字符串会比另一些字符串长得多。为了使它们简短,可以使用任何偶数基数-必须是偶数,因为这样两个值的任何平均值的展开都是有限的。 但是无论您做什么,字符串都可能变长,并且您将不得不在某些时候做一些内务处理,清理值,以便有效地使用字符串空间。该算法为您提供的确定性是在清理之间,系统将一直运转。     
您可能要考虑使用app-engine-ranklist,该引擎使用基于树的结构来维护数据存储区中的排名。 或者,如果您可以更详细地描述您的需求,也许我们可以建议一种开销较小的替代方案。     
您可以创建一个巨大的链接列表...。每个实体都指向列表中的下一个实体。 稍后遍历该列表将非常慢,但这可能是可以接受的,具体取决于您使用数据的方式,并且插入到列表中只会两次写入数据存储区(一次用于更新插入点,一次用于新实体) )。 在数据库中,可以像这样完成链接列表:
value (PK)   predecessor
------------------------
  A              null
  B               A
  C               B
然后,当您插入新数据时,请更改前身:
value (PK)   predecessor
------------------------
  A              null
  B               A
  C               D
  D               B
插入很快,但是遍历确实很慢!     

要回复问题请先登录注册