简单的用例。最多3M项目的清单。 用户可以重新排列列表中的项目(移至顶部,底部,上部,下部)。 列表以分页方式提供。
到目前为止,我们提出了以下解决方案。 第一个CF是将项目ID映射到小数位(大十进制)。
create table positions (
list_id UUID,
item_id UUID,
position text,
PRIMARY KEY(list_id, item_id)
);
按分数位置我的意思如下:
假设我们有列名定义的项目的初始位置:
1 2 3 4 5
---------
a b c d e
当我们想要在2和3之间插入一个项目时,我们只需创建一个小数部分,它将为我们提供正确的排序顺序,而不必重新移动其余的项目:
1 2 2.5 3 4 5
-------------
a b X c d e
第二个cf是按位置对项目进行排序:
create table items (
list_id UUID,
item_id UUID,
position text,
PRIMARY KEY(list_id, position)
);
显然,分页将使用N + 1限制选择'items'表和item_id从前一页获取。
要在另一个项目(before_id)之前插入项目(insert_id),我们可以使用以下伪代码:
BigDecimal before_position = (select position from positions where list_id = '...' and item_id = 'before_id')
List<item_id> list = (select item_id from items where list_id = '...' and position = 'before_position' order by desc limit 2)
BigDecimal before_before_id = list[2]
before_before_position = (select position from positions where list_id = '...' and item_id = 'before_before_id')
BigDecimal insert_position = (before_position + before_before_position) / 2;
insert into positions (list_id, item_id, position) values ('...', 'insert_id', insert_position.toPlainString());
insert into items (list_id, item_id, position) values ('...', 'insert_id', insert_position.toPlainString());
我们做得对吗?
我们在这个解决方案中不喜欢的是,在大量项目重新安排之后,分数位置可能会变得非常大(特别是如果插入恰好位于“移到顶部”用例中的相同位置) 。我们应该通过预定的后台工作将分数归一化为真正的整数位置来“维持”这一点。
另一个问题是,似乎不可能有效地将项目插入随机顺序位置。我们必须扫描整个色谱柱系列才能实现这一目标。