19

这是我要解决的问题:

我需要能够显示存储在多个数据库分片中的分页、排序数据表。

分页和排序是众所周知的问题,当数据来自单一来源时,我们大多数人都可以通过多种方式解决这些问题。但是,如果您要跨分片拆分数据或使用 DHT 或分布式文档数据库或任何您喜欢的 NoSQL 风格,事情就会变得更加复杂。

这是一个非常小的数据集的简单图片:

碎片 | 数据
1 | 1
| 1
| G
2 | 乙
2 | E
2 | H
3 | C
3 | F
3 | 一世

分页(页面大小 = 3):

页 | 数据
1 | 1
| 1
| C
2 | 2
| E
2 | F
3 | G
3 | H
3 | 一世

如果我们想向用户显示第 2 页,我们会返回:

D
E
F

如果有问题的表的大小大约是 1000 万行或 1 亿行,您不能只是将所有数据拉到 Web/应用程序服务器上对其进行排序并返回正确的页面。而且您显然不能让每个单独的分片对自己的数据片段进行排序和分页,因为分片彼此不知道。

更复杂的是,我需要呈现的数据不能过时,因此提前预先计算一组有用的排序并存储结果以供以后检索是不切实际的。

4

1 回答 1

15

有几种解决方案,其中一些可能对您不可行,但也许其中一种会坚持下去:

  1. 按此值的输入范围进行分片(例如,分片 1 包含 AC,分片 2 DF 等)。或者,使用另一个具有该表的外键的表作为索引,并使用该系统对索引表进行分片。这样您就可以轻松定位和获取指定的范围。如果可以的话,这个解决方案在性能方面可能是最好的(它假设分片的数量是静态的并且分片是可靠的)。
  2. 通过二分搜索识别页面项目。例如,假设您想要项目 100 到 110。对于每个分片,按字典顺序计算低于“M”的值的数量。如果数字总和大于 100,则减少枢轴点,否则增加它(使用二分查找)。在确定第 100 个项目(页面上的第一个项目)后,从每个分片中取出比该项目大的前 9 (10 - 1) 个项目,获取它们,对整个列表进行排序,从列表中取出前 9 个,前置第一项就是你的页面!这种方法更难实现,并且需要O(log(n))查询,因此它比(1)慢,但如果负载不是很重,仍然可能相当快。
  3. 存储每个值的页码。这将使您的读取速度非常快,但写入速度却非常慢,因此它仅适用于写入很少(或仅根据有序变量附加)的情况。
于 2010-10-13T21:03:04.860 回答