Cassandra:使用用户定义的顺序建模大型项目列表

时间:2015-02-20 01:27:28

标签: cassandra nosql

简单的用例。最多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());

我们做得对吗?

我们在这个解决方案中不喜欢的是,在大量项目重新安排之后,分数位置可能会变得非常大(特别是如果插入恰好位于“移到顶部”用例中的相同位置) 。我们应该通过预定的后台工作将分数归一化为真正的整数位置来“维持”这一点。

另一个问题是,似乎不可能有效地将项目插入随机顺序位置。我们必须扫描整个色谱柱系列才能实现这一目标。

0 个答案:

没有答案