当我尝试使用以下cql语句时出现上述错误,不确定它是否有错误。
CREATE TABLE Stocks(
id uuid,
market text,
symbol text,
value text,
time timestamp,
PRIMARY KEY(id)
) WITH CLUSTERING ORDER BY (time DESC);
Bad Request: Only clustering key columns can be defined in CLUSTERING ORDER directive
但这样可以正常使用,我是否可以使用一些不属于主键的列来排列我的行?
CREATE TABLE timeseries (
... event_type text,
... insertion_time timestamp,
... event blob,
... PRIMARY KEY (event_type, insertion_time)
... )
... WITH CLUSTERING ORDER BY (insertion_time DESC);
答案 0 :(得分:8)
“我不能使用一些不属于主键的列来排列我的行吗?”
不,你不能。从SELECT命令的DataStax文档:ORDER BY子句只能选择一个列。该列必须是复合PRIMARY KEY中的第二列。这也适用于主键中包含两个以上列组件的表。
因此,对于您的第一个CREATE
工作,您需要调整您的PRIMARY KEY:
PRIMARY KEY(id,time)
复合主键中的第二列称为“群集列”。这是确定分区键 中数据 的磁盘排序顺序的列。注意最后一部分用斜体字表示,因为它很重要。当您按id
查询Stocks列系列(表格)时,将返回id
的所有“行”列值,按time
排序。在Cassandra中,您只能在分区键(而不是整个表)中指定顺序,并且您的分区键是复合主键中列出的第一个键。
当然,问题在于,您可能希望id
是唯一的(这意味着CQL只会为每个分区键返回一列“行”)。要求time
成为主键的一部分否定了这一点,并且可以为同一个id存储多个值。这是通过唯一ID对数据进行分区的问题。在RDBMS世界中它可能是一个好主意,但它可以使Cassandra中的查询更加困难。
基本上,您需要在此处重新访问您的数据模型。例如,如果您想查询一段时间内的价格,可以将表格命名为“StockPriceEvents”,主键为(id,time)
或(symbol,time)
。查询该表将为您提供按时间排序的每个id或符号的记录价格。现在,这可能对您的用例有任何价值,也可能没有任何价值。试着解释一下Cassandra中的主键和排序顺序是如何工作的。
注意:您应该使用具有更多含义的列名。诸如“id”,“time”和“timeseries”之类的东西非常模糊,并没有真正描述它们被使用的上下文。
答案 1 :(得分:1)
使用“ CLUSTERING ORDER BY ”选项在Cassandra中创建表格时,请确保群集列为“主要”列。
使用群集列创建的表下方,但群集列“Datetime”不是主键列。因此低于错误。
<强> ERROR_SCRIPT 强>
cqlsh> CREATE TABLE IF NOT EXISTS cpdl3_spark_cassandra.log_data (
... IP text,
... URL text,
... Status text,
... UserAgent text,
... Datetime timestamp,
... PRIMARY KEY (IP)
... ) WITH CLUSTERING ORDER BY (Datetime DESC);
错误:强> InvalidRequest:来自服务器的错误:code = 2200 [无效查询] message =“只能在CLUSTERING ORDER指令中定义聚类键列”
CORRECTED_SCRIPT (将“日期时间”添加到“主键”列中)
cqlsh> CREATE TABLE IF NOT EXISTS cpdl3_spark_cassandra.log_data (
... IP text,
... URL text,
... Status text,
... UserAgent text,
... Datetime timestamp,
... PRIMARY KEY (IP,Datetime)
... ) WITH CLUSTERING ORDER BY (Datetime DESC);