数据模型:用于多个主键的Cassandra表

时间:2018-08-09 21:08:23

标签: cassandra datastax cassandra-3.0 composite-primary-key

请为以下要求提供有关Cassandra表数据模型的建议/想法。 不确定这是否可以实现。如果可以实现,我们就不需要编写外部程序

注意:这对于加入两个kafka主题很有帮助,并且任何一个kafka都在进行任何更新,两者都会以非规范化的格式反映在Cassandra表上

create table stackoverflow_composite (
      key_part_one text,
      key_part_two int,
      data text,
      PRIMARY KEY(key_part_one, key_part_two)      
  );

insert into stackoverflow_composite (key_part_one, key_part_two, data) 
  VALUES ('ronaldo', 9, 'football player');
insert into stackoverflow_composite (key_part_one, key_part_two, data) 
  VALUES ('ronaldo', 10, 'ex-football player');
insert into stackoverflow_composite (key_part_one, key_part_two, data) 
  VALUES ('ronaldo', 11, 'ex-football player');

select * from stackoverflow_composite where key_part_one = 'ronaldo';

 key_part_one | key_part_two | data
--------------+--------------+--------------------
      ronaldo |            9 |    football player
      ronaldo |           10 | ex-football player

根据我们的要求,主键的任何一个值都应该相同。没有插入。

insert into stackoverflow_composite (key_part_one, key_part_two, data) 
  VALUES ('Messi', 10, 'ex-football player');

基于第二个主键

cqlsh:key1> select * from stackoverflow_composite ;

 key_part_one | key_part_two | data
--------------+--------------+--------------------
      ronaldo |            9 |    football player
      Messi   |           10 | ex-football player

基于第二个第一主键

insert into stackoverflow_composite (key_part_one, key_part_two, data) 
  VALUES ('Messi', 12, 'ex-football player');

 cqlsh:key1> select * from stackoverflow_composite ;

 key_part_one | key_part_two | data
--------------+--------------+--------------------
      ronaldo |            9 |    football player
      Messi   |           12 | ex-football player

致谢

Karthikeyan Rasipalyam

1 个答案:

答案 0 :(得分:1)

这是一个有点复杂的解决方案(因为您的要求也很复杂)。

首先,您需要使主键只能是一列key_part_one

create table stackoverflow_composite ( key_part_one text, key_part_two int, data text, PRIMARY KEY(key_part_one) );

在插入之前,请执行一个尝试首先查找key_part_two的查询,以便能够直接查询此列而不限制partition key(key_part_one),您必须创建一个secondary index在此列上:

CREATE INDEX key_part_two_index ON stackoverflow_composite (key_part_two);

然后在插入之前进行如下查询:

select * from stackoverflow_composite where key_part_two = 10;

如果找到返回的任何行,则应执行更新而不是插入操作,例如,如果要插入行:

insert into stackoverflow_composite (key_part_one, key_part_two, data) VALUES ('Messi', 10, 'ex-football player');

相反,您应该更新除key_part_two之外的其余列:

update stackoverflow_composite set key_part_one='Messi', data='ex-football player' where key_part_two=10;

否则,如果找不到该key_part_two值的行,则应该执行常规插入操作:

insert into stackoverflow_composite (key_part_one, key_part_two, data) VALUES ('Messi', 10, 'ex-football player');

请注意,即使在所有行之前该key_part_one的值已经存在,新的插入操作仍会覆盖它,因为仅此列就构成了整个行的主键。

此解决方案的缺点是您必须执行两个查询才能插入,而不是一个查询,并且使用二级索引会使查询变慢。为了提高二级索引的性能,请尝试选择基数不高(不同值太多)的列,因此必须在key_part_one和key_part_two之间进行选择,哪一个将是新的主键,而哪一个将成为新主键。是用于创建二级索引的列。