Cassandra 更改主键与触发多个 select 查询
Cassandra changing Primary Key vs Firing multiple select queries
我有一个 table 存储用户拥有的列表产品。 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 作为我的集群键,这样我就可以在一个查询中获得所有结果。
或者我是否保持我的 table 设计不变,并通过 select 从第二个 table 组中的所有用户触发多个 select 查询,然后触发每个用户一个 select 查询,在我的代码中合并数据,然后 return 给用户
谢谢。
甚至在回答您的问题之前,您提出的数据建模就存在问题:您说您想要存储 "a list products that a user has"。但这不是您提供的 table 所具有的 - 您的 table 每个用户 ID 都有一个产品。 "userid" 是您的 table 的键,table 中的每个条目,即每个唯一的用户 ID,都有一个其他字段的组合。
如果你真的想让每个用户都有一个产品列表,你需要主键是(userid, productid)
。这意味着每条记录都由 用户 ID 和产品 ID 索引,或者换句话说 - 用户 ID 有一个记录列表,每个记录都有自己的产品 ID。 Cassandra 允许您有效地获取单个用户 ID 的所有产品 ID 记录,因为它将密钥的第一部分实现为 "partition key",但第二部分是 "clustering key".
关于您的实际问题,您确实有两个选择:要么对原始 table 进行多次查询,要么进行所谓的 非规范化 ,即创建第二个 table 正是您想要立即搜索的内容。对于第二个选项,您可以手动执行(每次有新数据时都更新 table),或者让 Cassandra 使用名为 [=22= 的功能自动为您更新第二个 table ]物化视图.
使用多个选项(多个查询或多个更新)中的哪一个实际上取决于您的工作量。如果它有很多更新和罕见的查询,最好让更新保持快速,让查询变慢。另一方面,如果更新很少但查询很多,那么最好让更新变慢(当每个更新需要更新两个 tables 时)但让查询更快。另一个重要的问题是多少查询延迟对你来说很重要——多个查询选项不仅增加了集群的负载(你可以通过在问题上投入更多的硬件来解决这个问题),而且还增加了延迟——一个没有解决的问题远离更多硬件,对于某些用例可能会成为问题。
您也可以在 Cassandra 中使用 Secondary Index 功能实现类似的目标,该功能具有自己的性能特征(在某些方面类似于 "multiple queries"解决方案)。
我有一个 table 存储用户拥有的列表产品。 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 作为我的集群键,这样我就可以在一个查询中获得所有结果。
或者我是否保持我的 table 设计不变,并通过 select 从第二个 table 组中的所有用户触发多个 select 查询,然后触发每个用户一个 select 查询,在我的代码中合并数据,然后 return 给用户
谢谢。
甚至在回答您的问题之前,您提出的数据建模就存在问题:您说您想要存储 "a list products that a user has"。但这不是您提供的 table 所具有的 - 您的 table 每个用户 ID 都有一个产品。 "userid" 是您的 table 的键,table 中的每个条目,即每个唯一的用户 ID,都有一个其他字段的组合。
如果你真的想让每个用户都有一个产品列表,你需要主键是(userid, productid)
。这意味着每条记录都由 用户 ID 和产品 ID 索引,或者换句话说 - 用户 ID 有一个记录列表,每个记录都有自己的产品 ID。 Cassandra 允许您有效地获取单个用户 ID 的所有产品 ID 记录,因为它将密钥的第一部分实现为 "partition key",但第二部分是 "clustering key".
关于您的实际问题,您确实有两个选择:要么对原始 table 进行多次查询,要么进行所谓的 非规范化 ,即创建第二个 table 正是您想要立即搜索的内容。对于第二个选项,您可以手动执行(每次有新数据时都更新 table),或者让 Cassandra 使用名为 [=22= 的功能自动为您更新第二个 table ]物化视图.
使用多个选项(多个查询或多个更新)中的哪一个实际上取决于您的工作量。如果它有很多更新和罕见的查询,最好让更新保持快速,让查询变慢。另一方面,如果更新很少但查询很多,那么最好让更新变慢(当每个更新需要更新两个 tables 时)但让查询更快。另一个重要的问题是多少查询延迟对你来说很重要——多个查询选项不仅增加了集群的负载(你可以通过在问题上投入更多的硬件来解决这个问题),而且还增加了延迟——一个没有解决的问题远离更多硬件,对于某些用例可能会成为问题。
您也可以在 Cassandra 中使用 Secondary Index 功能实现类似的目标,该功能具有自己的性能特征(在某些方面类似于 "multiple queries"解决方案)。