【问题标题】:Cassandra: Error: code=2200 [Invalid query] message="PRIMARY KEY column cannot be restricted as preceding columnCassandra: 错误: code=2200 [Invalid query] message="PRIMARY KEY 列不能被限制为前列
【发布时间】:2023-03-16 07:09:01
【问题描述】:

表架构:

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:来自服务器的错误:code=2200 [无效查询] message="PRIMARY KEY 列“comdate”不能被限制为 前列“comtype”不受限制”

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

【问题讨论】:

    标签: cassandra cassandra-3.0 spring-data-cassandra


    【解决方案1】:

    在 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,我们知道要访问哪个索引来获取数据。

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 2015-01-30
        • 2023-03-15
        • 2017-10-18
        • 2021-10-04
        • 2015-04-18
        • 2015-06-12
        • 2021-09-16
        • 1970-01-01
        • 2016-03-29
        相关资源
        最近更新 更多