【问题标题】:Cassandra: Update multiple rows with different valuesCassandra:使用不同的值更新多行
【发布时间】:2017-05-08 09:50:07
【问题描述】:

您好,我在 Cassandra 中有类似的表:

CREATE TABLE TestTable( id text, 
        group text,
        date text,
        user text,
        dept text,
        orderby int,
        files list<text>,
        users list<text>, 
        family_memebrs list<frozen <member>>,
        PRIMARY KEY ((id)));'
CREATE INDEX on TestTable (user);
CREATE INDEX on TestTable (dept);
CREATE INDEX on TestTable (group);
CREATE INDEX on TestTable (date);

 Id    | OrderBy
:----  | :----
101    |  1
102    |  2
105    |  3

我想以相同的顺序更改现有的订单,以跟踪 105,102,103 的 ID。即 (105, 1) (102, 2) (103, 3)。我是Cassandra的新手,请帮助我。我认为在 sql 中使用 rownum 和 join 是可能的。

【问题讨论】:

  • 您能否编辑您的问题以包含您的CREATE TABLE 声明?唯一可以真正按照您从 SQL 世界中思考的方式工作的方法是,如果它们都共享相同的分区键。即便如此,这也取决于您的集群键是什么。
  • 我添加了表创建
  • 另外,使用高基数二级索引是一种反模式。根据它们的取值范围,dept 和 group 可能没问题,但 user 和 date 太独特而无法很好地发挥作用。

标签: sql cassandra cql nosql


【解决方案1】:

我是 Cassandra 的新手

我知道。第一个线索,是你的结果的顺序。使用id 作为您唯一的主键(使其成为您的分区键),您的结果将永远不会像那样排序。 这是它们的排序方式:

aploetz@cqlsh:stackoverflow> SELECT id,orderby,token(id) FROM testtable  ;

 id  | orderby | system.token(id)
-----+---------+---------------------
 102 |       2 | -963541259029995480
 105 |       3 | 2376737131193407616
 101 |       1 | 4965004472028601333

(3 rows)

未绑定查询始终返回按分区键的哈希标记值排序的结果。我已经在你的分区键 (id) 上运行了 token() 函数来显示这一点。

我想以相同的顺序更改现有的订单,以遵循 105,102,103 的 ID。即 (105, 1) (102, 2) (103, 3)。

如果您只需更改 orderby 列中的值,这很容易:

aploetz@cqlsh:stackoverflow> INSERT INTO testtable(id,orderby) VALUES ('101',3);
aploetz@cqlsh:stackoverflow> INSERT INTO testtable(id,orderby) VALUES ('102',2);
aploetz@cqlsh:stackoverflow> INSERT INTO testtable(id,orderby) VALUES ('105',1);
aploetz@cqlsh:stackoverflow> SELECT id,orderby,token(id) FROM testtable  ;

 id  | orderby | system.token(id)
-----+---------+---------------------
 102 |       2 | -963541259029995480
 105 |       1 | 2376737131193407616
 101 |       3 | 4965004472028601333

(3 rows)

由于 Cassandra 主键是唯一的,因此只需为该键插入一个新的非键列值即可更改 orderby。

现在,如果您实际上希望能够按 orderby 列对结果进行排序,那完全是另一个问题,并且无法用您当前的模型解决。

如果这是您真正想要做的,那么您将需要一个具有不同 PRIMARY KEY 定义的新表。因此,我将创建具有两个更改的同一个表:我将其命名为testtable_by_group,我将使用PRIMARY KEY (group,orderby,id)) 的复合主键。现在我可以查询特定组“group1”并查看已排序的结果。

aploetz@cqlsh:stackoverflow> CREATE TABLE testtable_by_group (group text,id text,orderby int,PRIMARY KEY (group,orderby,id));
aploetz@cqlsh:stackoverflow> INSERT INTO testtable_by_group(group,id,orderby) VALUES ('group1','101',3);
aploetz@cqlsh:stackoverflow> INSERT INTO testtable_by_group(group,id,orderby) VALUES ('group1','102',2);
aploetz@cqlsh:stackoverflow> INSERT INTO testtable_by_group(group,id,orderby) VALUES ('group1','105',1);
aploetz@cqlsh:stackoverflow> SELECT group,id,orderby,token(group) FROM testtable_by_group WHERE group='group1';

 group  | id  | orderby | system.token(group)
--------+-----+---------+----------------------
 group1 | 105 |       1 | -2413872665919611707
 group1 | 102 |       2 | -2413872665919611707
 group1 | 101 |       3 | -2413872665919611707

(3 rows)

这样group就是新的分区键。 orderby 是第一个聚类键,因此 group 中的行会自动按它排序。 id 位于末尾以确保唯一性,如果任何两行具有相同的orderby。

请注意,我将 token() 函数留在了结果集中,但我在新的分区键 (group) 上运行了它。如您所见,group1 的键被散列到所有 3 行的相同令牌,这意味着在多节点环境中,所有 3 行将存储在一起。这可以在您的集群中创建一个“热点”,其中一些节点比其他节点拥有更多的数据。这就是为什么良好的 PRIMARY KEY 定义可以确保查询满意度和数据分布。

不久前,我为 DataStax 写了一篇关于这个主题的文章。阅读它,它应该可以帮助你:http://www.datastax.com/dev/blog/we-shall-have-order

【讨论】:

  • 非常感谢。需求已更改并切换到 Postgres
猜你喜欢
  • 2011-04-22
  • 1970-01-01
  • 1970-01-01
  • 2012-11-01
  • 1970-01-01
  • 2016-11-17
  • 2017-06-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多