我有一个表存储用户拥有的产品列表。这张table看起来像这样。
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作为集群键,以便在一个查询中获得所有结果。
还是保持表的设计不变,从第二个表中选择组中的所有用户,然后为每个用户启动一个select查询,在代码中合并数据,然后将其返回给用户,从而启动多个select查询
谢谢。
1条答案
按热度按时间tvokkenx1#
甚至在开始讨论你的问题之前,你的数据建模就有一个问题:你说你想存储“一个用户拥有的产品列表”。但这并不是您所展示的表所具有的内容—您的表中的每个userid都有一个产品。“userid”是表的键,表中的每个条目,即每个唯一的userid,都有一个其他字段的组合。
如果您真的希望每个用户都有一个产品列表,那么需要将主键设置为
(userid, productid)
. 这意味着每个记录都由userid和productid索引,或者换句话说,userid有一个记录列表,每个记录都有自己的productid。cassandra允许您高效地获取单个userid的所有productid记录,因为它将键的第一部分实现为“分区键”,而第二部分实现为“集群键”。关于您的实际问题,您确实有两种选择:要么对原始表执行多个查询,要么执行所谓的反规范化,即创建第二个表,其中包含您希望立即搜索的内容。对于第二个选项,您可以手动执行(每次有新数据时都更新这两个表),或者让cassandra使用称为物化视图的功能自动更新第二个表。
这两个选项中的哪一个-多个查询或多个更新-取决于您的工作负载。如果它有许多更新和罕见的查询,最好保持更新速度快,使查询速度慢。另一方面,如果更新很少但查询较多,则最好使更新速度减慢(当每个更新都需要更新两个表时),但使查询速度加快。另一个重要的问题是查询延迟对您来说有多重要—多个查询选项不仅增加了集群上的负载(您可以通过向问题中扔更多硬件来解决这个问题),而且还增加了延迟—这个问题不会随着更多硬件而消失,对于某些用例来说可能会成为一个问题。
您也可以在cassandra中通过使用二级索引特性来实现类似的目标,二级索引特性有其自身的性能特征(在某些方面类似于“多查询”解决方案)。