Cassandra:错误:代码=2200 [无效查询]消息=“主键列不能限制为前一列”

标签 cassandra cassandra-3.0 spring-data-cassandra

表架构:

CREATE TABLE com (
    receiverid text,
    senderid text,
    commatriid text,
    comtype tinyint,
    comid text,
    displaystatus tinyint,
    comdate timestamp,
    cominfoid bigint,
    comstatus tinyint,
    dateactioned timestamp,
    datedeleted timestamp,
    dateread timestamp,
    dateupdated timestamp,
    disclosedmatriid tinyint,
    filteredmsg tinyint,
    message text,
    recentstatus tinyint,
    regionallang tinyint,
    transmsg text,
    PRIMARY KEY (receiverid, senderid, commatriid, comtype, comid, displaystatus, comdate)
) WITH CLUSTERING ORDER BY (senderid ASC, commatriid ASC, comtype ASC, comid ASC, displaystatus ASC, comdate ASC);

使用 where 子句选择查询:

SELECT ComInfoId,ComId,ComType,SenderId,ReceiverId,ComMatriId,ComDate,ComStatus FROM com WHERE ComMatriId='M1'AND SenderId='M79984222' and ReceiverId='M2' and ComDate <= '2017-11-14 09:20:05+0000';

错误:

InvalidRequest: Error from server: code=2200 [Invalid query] message="PRIMARY KEY column "comdate" cannot be restricted as preceding column "comtype" is not restricted"

什么是主键列被限制为处理列? 如果删除 where 子句中的 comDate 日期,我可以检索数据

最佳答案

在 C* 中,主键列的顺序很重要,数据存储在磁盘中的方式是,只有在指定了之前的键的情况下才允许选择数据。

PRIMARY KEY (receiverid, senderid, commatriid,
             comtype, comid, displaystatus, comdate)

您收到的错误意味着,如果您想按 comdate 查询,那么您还需要按之前的所有键进行查询:receiverid、senderid、commatriid、comtype、comid、displaystatus .

如果要按comtype查询,则需要指定``receiverid, senderid, commatriid, comtype`。

为什么我必须指定其他键?

这取决于 Cassandra 的设计方式以及性能。所有内容都存储在分区中,并按顺序存储在磁盘上,以便数据库只需执行最少的工作。缺点是您需要知道在设计架构时要运行哪些查询。

将磁盘上的数据可视化为数组(请原谅所有等于整数的列):

data =
receiverid(1)
    senderid(1)
        commatriid(1)
            comtype(1)
                comid(1)
                    displaystatus(1)
                        comdate(1)
                        comdate(2)
                        comdate(3)
    senderid(2)
        commatriid(1)
            comtype(1)
                comid(1)
                    displaystatus(1)
                        comdate(1)
                        comdate(2)
                        comdate(3)

采用以下查询和我的像 Cassandra 一样访问数据的示例。

  1. WHERE receiveid IN (1, 2)

    结果 = (数据[1], 数据[2])

  2. 其中 receiveid IN (1) AND senderid = 1

    结果=数据[1][1]

  3. 其中 receiveid IN (1) AND senderid = 1 AND comtype = 1

    结果 = 数据[1][1][??????][1]

    这就是有趣的地方。我故意错过了 where 子句中的 commatriid 字段。现在,C* 可以将结果范围缩小到 data[1][1],但是它应该查找哪个 commatriid 索引来返回数据?它不知道,因为我没有指定它。

  4. 其中 receiveid IN (1) AND senderid = 1 AND comtype = 1 AND commatriid = 1

    结果 = 数据[1][1][1][1]

    现在我们已经包含了 commatriid,我们知道要访问数据的索引。

关于Cassandra:错误:代码=2200 [无效查询]消息=“主键列不能限制为前一列”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47283460/

相关文章:

cassandra - 如何降级 Cassandra 3.0.0 -> 2.x?

Cassandra 浮点精度

spring - bootstrap.yml 未加载 Spring Boot 2

Spring-Data-Cassandra SchemaAction 不工作

java - 自驱动程序 3.0 起,Cassandra 的 DDL 查询速度较慢

mysql - Cassandra 还是 MySQL/PostgreSQL?

hadoop - 使用列表数据类型将数据从Pig插入Cassandra失败

cassandra - Cassandra 的墓碑

java - cassandra的cqlsh控制台操作超时错误

Spring Boot 数据嵌入式 Cassandra