cassandra主键列不能被限制

时间:2015-02-17 15:52:23

标签: cassandra cql cqlsh

我第一次在网络应用中使用Cassandra而且我遇到了查询问题。 这是我的标签:

CREATE TABLE vote (
    doodle_id uuid,
    user_id uuid,
    schedule_id uuid,
    vote int,
    PRIMARY KEY ((doodle_id), user_id, schedule_id)
);

在每个请求中,我都指示我的分区键doodle_id。 例如,我可以毫无问题地制作:

select * from vote where doodle_id = c4778a27-f2ca-4c96-8669-15dcbd5d34a7 and user_id = 97a7378a-e1bb-4586-ada1-177016405142;

但是在我提出的最后一个请求中:

select * from vote where doodle_id = c4778a27-f2ca-4c96-8669-15dcbd5d34a7 and schedule_id = c37df0ad-f61d-463e-bdcc-a97586bea633;

我收到以下错误:

Bad Request: PRIMARY KEY column "schedule_id" cannot be restricted (preceding column "user_id" is either not restricted or by a non-EQ relation)

我是Cassandra的新手,但如果我错了,请更正我,在复合主键中,第一部分是PARTITION KEY,必须允许Cassandra知道在哪里查找数据。 然后其他部分是CLUSTERING KEY来对数据进行排序。

但我仍然不知道为什么我的第一个请求正在运行而不是第二个请求?

如果有人能提供帮助,那将是一件非常愉快的事。

2 个答案:

答案 0 :(得分:13)

在Cassandra中,您应该设计适合您查询的数据模型。因此,支持第二个查询的正确方法(doodle_idschedule_id进行查询,但不必使用user_id),是创建一个新表来处理该特定查询。这个表几乎是一样的,除了PRIMARY KEY会略有不同:

CREATE TABLE votebydoodleandschedule (
    doodle_id uuid,
    user_id uuid,
    schedule_id uuid,
    vote int,
    PRIMARY KEY ((doodle_id), schedule_id, user_id)
);

现在这个查询将起作用:

SELECT * FROM votebydoodleandschedule 
WHERE doodle_id = c4778a27-f2ca-4c96-8669-15dcbd5d34a7 
AND schedule_id = c37df0ad-f61d-463e-bdcc-a97586bea633;

这使您无需指定ALLOW FILTERING。依赖ALLOW FILTERING永远不是一个好主意,当然不是你应该在生产集群中做的事情。

答案 1 :(得分:3)

群集密钥还用于查找给定分区中的列。使用您的模型,您将能够通过以下方式进行查询:

  • doodle_id
  • doodle_id / USER_ID
  • doodle_id / USER_ID / schedule_id
  • user_id使用ALLOW FILTERING
  • user_id / schedule_id使用ALLOW FILTERING

您可以将主键视为文件路径doodle_id#123 / user_id#456 / schedule_id#789,其中所有数据都存储在最深的文件夹中(即schedule_id#789)。当您查询时,您必须从开始搜索的位置指出子文件夹/子树。

您的第二个查询不起作用,因为列在分区中的组织方式。 Cassandra无法在分区中获得连续的 slice 列,因为它们是交错的。

您应该反转主键顺序(doodle_id,schedule_id,user_id)才能运行查询。