Cassandra更改主键与引发多个选择查询

时间:2019-01-08 07:11:28

标签: cassandra nosql cassandra-3.0 database-partitioning scylla

我有一个表,用于存储用户拥有的列表产品。桌子看起来像这样。

create table my_keyspace.userproducts{
  userid,
  username,
  productid,
  productname,
  producttype,
Primary Key(userid)
}

所有用户都属于一个组,一个组中的最小用户数为1至最大100个用户

userid|groupid|groupname|
1     |g1     | grp1  
2     |g2     | grp2  
3     |g3     | grp3  

我们有一个新的要求,即在一个组中为所有用户展示所有产品。

我也要更改用户产品,以便我的分区密钥现在是groupid,并把userid作为我的集群密钥,这样我就可以在一个查询中获得所有结果。

还是我保持表设计不变,并通过从第二个表中选择一个组中的所有用户来触发多个选择查询,然后为每个用户触发一个选择查询,将数据合并到我的代码中,然后将其返回给用户

谢谢。

1 个答案:

答案 0 :(得分:5)

即使在提出问题之前,所呈现的数据建模也存在问题:您说要存储“用户拥有的产品清单”。但这不是您提供的表所具有的-您的表为每个用户ID具有一个产品。 “用户ID”是表的关键字,表中的每个条目(即每个唯一的用户ID)都具有其他字段的组合。

如果您确实希望每个用户都有一个产品列表,则需要将主键设置为(userid, productid)。这意味着每个记录都由两者以及用户ID和产品ID索引,换句话说,用户ID包含一个记录列表,每个记录都有自己的产品ID。 Cassandra允许您有效地获取单个用户ID的所有产品ID记录,因为它将密钥的第一部分实现为“分区密钥”,而第二部分则实现为“集群密钥”。

关于您的实际问题,您确实有两个选择:对原始表进行多个查询,或者进行所谓的 denormalization ,即创建一个具有您想要立即可搜索内容的表。 。对于第二个选项,您可以手动进行(每次有新数据时都更新两个表),或者让Cassandra使用名为材料化视图的功能自动为您更新第二个表。

要使用的两个选项中的哪个(多个查询或多个更新)实际上取决于您的工作量。如果更新很多且查询很少,则最好保持快速更新并使查询变慢。另一方面,如果更新很少但查询很多,则最好使更新速度变慢(当每个更新都需要更新两个表时),但使查询速度加快。另一个重要的问题是多少查询延迟对您很重要-多个查询选项不仅增加了群集上的负载(您可以通过在该问题上投入更多的硬件来解决),而且还增加了延迟-这个问题不会解决没有更多的硬件,在某些情况下可能会成为问题。

您还可以使用二级索引功能在Cassandra中实现类似的目标,该功能具有其自身的性能特征(在某些方面类似于“多个查询”解决方案)。