如何在cassandra中选择合适的表结构?
假设我有一个具有以下结构的表如何在cassandra中选择合适的表结构?,cassandra,cql,cql3,Cassandra,Cql,Cql3,假设我有一个具有以下结构的表 创建表任务( 用户id uuid, 名称文本, 任务id uuid, 说明文字, 主键((用户id)、名称、任务id) ); 它允许我按name升序获取用户的所有任务。我还在主键中添加了task\u id,以避免出现错误。以下查询适用 从任务中选择*,其中user_id=? 以及 从任务中选择*,其中user_id=?和名字>? 但是,我无法使用特定的任务id获取任务。例如,以下查询崩溃 从任务中选择*,其中user_id=?任务_id=? 由于这个
创建表任务(
用户id uuid,
名称文本,
任务id uuid,
说明文字,
主键((用户id)、名称、任务id)
);
它允许我按name
升序获取用户的所有任务。我还在主键中添加了task\u id
,以避免出现错误。以下查询适用
从任务中选择*,其中user_id=?
以及
从任务中选择*,其中user_id=?和名字>?
但是,我无法使用特定的任务id
获取任务。例如,以下查询崩溃
从任务中选择*,其中user_id=?任务_id=?
由于这个错误
无法限制主键列“任务id”,因为前面的列“名称”未受限制
它需要指定name
列,但目前我只有task\u id
(例如,来自url)和user\u id
(来自会话)
如何创建此表以执行这两个查询?或者我需要为第二种情况创建单独的表?这种情况下的常见模式是什么?您可以简单地添加一个与task_id值相同的冗余列taskId,并在taskId上创建一个辅助索引。 然后您可以查询
user\u id=?和tsakId=?
PRIMARY KEY column "task_id" cannot be restricted as preceding
column "name" is not restricted
您看到此错误是因为CQL不允许查询跳过主键组件
如何创建此表以执行这两个查询?或者我需要为第二种情况创建单独的表?这种情况下的常见模式是什么
正如您所怀疑的,使用Cassandra解决此类问题的典型方法是为每个查询创建一个附加表。在这种情况下,使用设计用于匹配附加查询模式的主键重新创建表的方式如下所示:
create table tasks_by_user_and_task (
user_id uuid,
name text,
task_id uuid,
description text,
primary key ((user_id), task_id)
);
您只需再添加一个与task_id值相同的冗余列taskId,并在taskId上创建一个二级索引 虽然我通常不喜欢使用二级索引,但在这种情况下,它的性能可能还不错。原因是,您仍将通过分区键限制查询,这将消除检查其他节点的需要。缺点(正如Undefined_variable指出的)是无法在主键组件上创建辅助索引,因此需要复制该列(并将索引应用于非主键列)才能使该解决方案起作用
对这两种解决方案的性能进行建模和测试可能是个好主意。如果您有额外的磁盘空间,最好的方法是在第二个表中复制数据。您应该避免在生产中使用二级索引。当然,您的应用程序需要写入这两个表。但是卡桑德拉非常擅长使这一点更有效率
create table tasks_by_name (
user_id uuid,
name text,
task_id uuid,
description text,
primary key ((user_id), name, task_id)
);
create table tasks_by_id (
user_id uuid,
name text,
task_id uuid,
description text,
primary key ((user_id), task_id)
);
我考虑过这个变体,实际上它是有效的。但我认为对于基数较高的列,这可能是不合适的。在本例中,我们通过用户id缩小查询范围,似乎用户的任务量并不巨大。所以索引可以起到帮助作用。但是,如果我有数十万行,我需要找到一个具体的。索引可能是低效的?