Cassandra:错误:代码= 2200 [无效查询]消息=" PRIMARY KEY列不能被限制为前一列

时间:2017-11-14 10:34:01

标签: 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';

ERROR:

  

InvalidRequest:服务器出错:code = 2200 [查询无效]   message =&#34; PRIMARY KEY列&#34; comdate&#34;不能被限制为   前一栏&#34; comtype&#34;不受限制&#34;

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

2 个答案:

答案 0 :(得分:3)

在C *中,主键列的顺序很重要,并且数据以只允许在指定键之前选择数据的方式存储在磁盘中。

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

您收到的错误意味着,如果您想按comdate进行查询,则还需要按以上所有键进行查询:receiverid, senderid, commatriid, comtype, comid, displaystatus

如果你想通过comtype查询,那么你需要指定``receiverid,senderid,commatriid,comtype`。

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

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

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

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 receiverid IN (1, 2)

    result = (data[1], data[2])

  2. WHERE receiverid IN (1) AND senderid = 1

    result = data[1][1]

  3. WHERE receiverid IN (1) AND senderid = 1 AND comtype = 1

    result = data[1][1][????][1]

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

  4. WHERE receiverid IN (1) AND senderid = 1 AND comtype = 1 AND commatriid = 1

    result = data[1][1][1][1]

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

答案 1 :(得分:0)

从select查询中的where子句中删除commatriid,然后检查输出一次.. 我想,查询搜索键中的多个聚类键不应发生这样的查询。如果我错了,请纠正我。

这可能会对您有所帮助:https://www.datastax.com/dev/blog/a-deep-look-to-the-cql-where-clause