2

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

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  

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

我是否要更改我的 userproducts 以便我的分区键现在是 groupid 并将 userid 作为我的集群键,以便我在一个查询中获得所有结果。

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

谢谢。

4

1 回答 1

5

甚至在回答您的问题之前,您提出的数据建模就有一个问题:您说您要存储“用户拥有的产品列表”。但这不是您提供的表格所具有的 - 您的表格对于每个用户 ID 都有一个产品。“userid”是您的表的键,表中的每个条目,即每个唯一的用户ID,都具有其他字段的一种组合。

如果你真的希望每个用户都有一个产品列表,你需要主键是(userid, productid). 这意味着每条记录都由 userid 和 productid 索引或者换句话说 - userid 有一个记录列表,每个记录都有自己的 productid。Cassandra 允许您有效地获取单个用户 ID 的所有 productid 记录,因为它将键的第一部分实现为“分区键”,而第二部分是“集群键”。

关于您的实际问题,您确实有两个选择:要么对原始表执行多个查询,要么执行所谓的反规范化,即创建第二个表,其中包含您想要立即搜索的内容。对于第二个选项,您可以手动执行(每次有新数据时更新两个表),或者让 Cassandra 使用名为Materialized Views的功能自动为您更新第二个表。

使用两个选项中的哪一个 - 多个查询或多个更新 - 真正取决于您的工作量。如果它有很多更新和很少的查询,最好让更新快一点,让查询慢一点。另一方面,如果它的更新很少但查询很多,最好让更新更慢(当每次更新都需要更新两个表时)但让查询更快。另一个重要问题是查询延迟对您来说有多重要 - 多个查询选项不仅会增加集群上的负载(您可以通过在问题上投入更多硬件来解决)而且还会增加延迟 - 这个问题不会发生没有更多的硬件,对于某些用例可能会成为一个问题。

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

于 2019-01-08T08:34:21.987 回答