如何通过 ScalarDB 实现应用程序级分页
How to implement application level pagination over ScalarDB
这个问题部分是 Cassandra,部分是 ScalarDB。我正在使用 ScalarDB,它在 Cassandra
之上提供 ACID 支持。图书馆似乎运作良好!不幸的是,ScalarDB 不支持分页,所以我必须在应用程序中实现它。
考虑以下场景,其中 P
是主键,C
是聚类键,E
是分区中的其他数据
Partition => { P,C1,E1
P,C2,E1
P,C2,E2
P,C2,E3
P,C2,E4
P,C3,E1
...
P,Cm,En
}
在 ScalarDB 中,我可以指定键的起始值和结束值,因此我想 ScalarDB 只会从指定的行中获取数据。我也可以限制没有。获取的条目数。
https://scalar-labs.github.io/scalardb/javadoc/com/scalar/db/api/Scan.html
假设我想从 P,C2
获取条目 E3
和 E4
。对于较小的值,我可以将开始和结束聚类键指定为 C2,并将获取限制设置为 4 并忽略 E1
和 E2
。但是,如果有几百条记录,则此方法将无法扩展。
例如说 P,C1
有 10 条记录,P,C2
有 100 条记录,我想对每个查询实现 20 条记录的分页。然后要实现这个,我必须
Query 1 – Scan – 主键为P,聚类开始为C1,聚类结束为Cn,因为我不知道有多少条记录。
- 获得
P,C1
。这将给出 10 条记录
- 获得
P,C2
。这将给我 20 条记录。我将忽略最后 10 个并将 P,C1
的 10 与 P,C2
的前 10 个和 return 结果结合起来。
我还必须维护查询的最后一个簇键是 C2
并且从中提取了 10 条记录。
查询 2(用于下一个分页请求)- 扫描 - 主键将是 P,聚类开始将是 C2,聚类结束将是 Cn,因为我不知道有多少条记录。
现在我将获取 P,C2
并获取 20,忽略第一个 10(因为它们是上次发送的),获取剩余的 10,使用相同的 Scan 进行另一次获取并从中获取前 10。
这是应该怎么做还是有更好的方法?我对上述实现的担忧是,每次我都必须获取大量记录并转储它们。例如,假设我想从 P,C2
中获取记录 70-90,那么我仍然会查询到记录 60 并转储结果!
主键和集群键组成一个主键,所以你上面的例子看起来不对。
假设以下数据结构。
P, C1, ...
P, C2, ...
P, C3, ...
...
无论如何,我认为其中一种方法可能如下。假设页面大小为 2.
- 从开始 (P, C1) 开始扫描,从上到下,限制为 2。结果存储在 R1 中
- 获取R1的最后一条记录->(P,C2)。
- 从前一个最后记录(P,C2)开始扫描,不包括在内,升序限制为 2。
...
这个问题部分是 Cassandra,部分是 ScalarDB。我正在使用 ScalarDB,它在 Cassandra
之上提供 ACID 支持。图书馆似乎运作良好!不幸的是,ScalarDB 不支持分页,所以我必须在应用程序中实现它。
考虑以下场景,其中 P
是主键,C
是聚类键,E
是分区中的其他数据
Partition => { P,C1,E1
P,C2,E1
P,C2,E2
P,C2,E3
P,C2,E4
P,C3,E1
...
P,Cm,En
}
在 ScalarDB 中,我可以指定键的起始值和结束值,因此我想 ScalarDB 只会从指定的行中获取数据。我也可以限制没有。获取的条目数。
https://scalar-labs.github.io/scalardb/javadoc/com/scalar/db/api/Scan.html
假设我想从 P,C2
获取条目 E3
和 E4
。对于较小的值,我可以将开始和结束聚类键指定为 C2,并将获取限制设置为 4 并忽略 E1
和 E2
。但是,如果有几百条记录,则此方法将无法扩展。
例如说 P,C1
有 10 条记录,P,C2
有 100 条记录,我想对每个查询实现 20 条记录的分页。然后要实现这个,我必须
Query 1 – Scan – 主键为P,聚类开始为C1,聚类结束为Cn,因为我不知道有多少条记录。
- 获得
P,C1
。这将给出 10 条记录 - 获得
P,C2
。这将给我 20 条记录。我将忽略最后 10 个并将P,C1
的 10 与P,C2
的前 10 个和 return 结果结合起来。
我还必须维护查询的最后一个簇键是 C2
并且从中提取了 10 条记录。
查询 2(用于下一个分页请求)- 扫描 - 主键将是 P,聚类开始将是 C2,聚类结束将是 Cn,因为我不知道有多少条记录。
现在我将获取 P,C2
并获取 20,忽略第一个 10(因为它们是上次发送的),获取剩余的 10,使用相同的 Scan 进行另一次获取并从中获取前 10。
这是应该怎么做还是有更好的方法?我对上述实现的担忧是,每次我都必须获取大量记录并转储它们。例如,假设我想从 P,C2
中获取记录 70-90,那么我仍然会查询到记录 60 并转储结果!
主键和集群键组成一个主键,所以你上面的例子看起来不对。 假设以下数据结构。
P, C1, ...
P, C2, ...
P, C3, ...
...
无论如何,我认为其中一种方法可能如下。假设页面大小为 2.
- 从开始 (P, C1) 开始扫描,从上到下,限制为 2。结果存储在 R1 中
- 获取R1的最后一条记录->(P,C2)。
- 从前一个最后记录(P,C2)开始扫描,不包括在内,升序限制为 2。 ...