如何在cassandra中选择合适的表格结构?

时间:2016-02-01 07:27:30

标签: cassandra cql cql3

假设我有一个具有以下结构的表 create table tasks ( user_id uuid, name text, task_id uuid, description text, primary key ((user_id), name, task_id) );

它允许我为用户按name升序排序所有任务。我还将task_id添加到主键以避免upserts。以下查询成立 select * from tasks where user_id = ? 以及 select * from tasks where user_id = ? and name > ?

但是,我无法完成特定task_id的任务。例如,以下查询崩溃 select * from tasks where user_id = ? and task_id = ? 有这个错误 PRIMARY KEY column "task_id" cannot be restricted as preceding column "name" is not restricted 它需要指定name列,但目前我只有task_id(例如来自网址)和user_id(来自会话)。

我应该如何创建此表来执行这两个查询?或者我需要为第二种情况创建单独的表?这种情况下的常见模式是什么?

3 个答案:

答案 0 :(得分:1)

您只需添加一个与task_id具有相同值的冗余列taskId,并在taskId上创建二级索引。 然后,您可以查询user_id=? and tsakId=?

答案 1 :(得分:0)

PRIMARY KEY column "task_id" cannot be restricted as preceding 
  column "name" is not restricted

您看到此错误,因为CQL不允许查询跳过主键组件。

  

我应该如何创建此表来执行这两个查询?或者我需要为第二种情况创建单独的表?这种情况下的常见模式是什么?

正如您所怀疑的那样,使用Cassandra解决此类问题的典型方法是为每个查询创建一个附加表。在这种情况下,使用PRIMARY KEY重新创建表以匹配您的其他查询模式将只是这样:

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所指出的)是您无法在主键组件上创建辅助索引,因此您需要复制该列(并将索引应用于非主键列)以使该解决方案起作用。

对两种性能解决方案进行建模和测试可能是一个好主意。

答案 2 :(得分:0)

如果您有额外的磁盘空间,最好的方法是在第二个表中复制数据。您应该避免在生产中使用二级索引。当然,您的应用程序需要写入这两个表。但是卡桑德拉很擅长提高效率。

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)
);