如何解决将订购清单存储在数据库中间隙方法
| 我想在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
插入很快,但是遍历确实很慢!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。