cassandra - Cassandra CQL 中的 Where 和 Order By 条款

标签 cassandra cql cql3

我是 NoSQL 数据库的新手,刚刚开始使用 apache Cassandra。我在“empno”列上创建了一个带有主键的简单表“emp”。这是一个简单的表,因为我们总是在 Oracle 的默认 scott 模式中得到。

现在我使用 COPY 加载数据命令和发出的查询 Select * from emp order by empno但我很惊讶 CQL 不允许在 empno 上订购列(这是 PK)。也是当我使用 Where条件,它不允许对 empno 列进行任何不等运算(它说只允许 EQ 或 IN 条件)。它还不允许在任何其他列上使用 Where 和 Order by,因为它们没有在 PK 中使用,并且没有索引。

有人可以帮助我如果我想保留我该怎么办empno表中唯一并希望按 empno 的排序顺序查询结果?

(我的版本是:
cqlsh:demodb> show version [cqlsh 5.0.1 | Cassandra 2.2.0 | CQL spec 3.3.0 | Native protocol v4])

最佳答案

Cassandra 中的 PRIMARY KEY 有两个部分:

  • 分区键
  • 集群键
  • PRIMARY KEY (partitionKey1,clusteringKey1,clusteringKey2)
    要么
    PRIMARY KEY ((partitionKey1,partitionKey2),clusteringKey1,clusteringKey2)
    分区键确定您的数据存储在哪个节点上。集群键决定了分区键中数据的顺序。

    在 CQL 中,ORDER BY子句实际上仅用于反转已定义的聚类顺序的排序方向。至于列本身,您只能在 CLUSTERING ORDER BY 中指定定义的列(并按照确切的顺序...不可跳过)。创建表时的子句。因此,您不能在查询时选择任意列来对结果集进行排序。

    Cassandra 通过使用集群键对磁盘上的数据进行排序来实现性能,从而仅在单次读取(无随机读取)中返回有序行。这就是为什么您必须在 Cassandra 中采用基于查询的建模方法(通常将您的数据复制到多个查询表中)。提前了解您的查询,并构建您的表来为它们提供服务。
    Select * from emp order by empno;
    

    首先,您需要一个 WHERE条款。如果您使用的是关系数据库,则无需使用它进行查询也可以。使用 Cassandra,您应该尽量避免未绑定(bind) SELECT查询。此外,Cassandra 只能在分区内强制执行排序顺序,因此在没有 WHERE 的情况下进行查询无论如何,子句不会以您想要的顺序返回数据。

    其次,正如我上面提到的,您需要定义集群键。如果您想按 empno 对结果集进行排序,那么您必须找到另一列来定义为您的分区键。尝试这样的事情:
    CREATE TABLE emp_by_dept (
      empno text,
      dept text,
      name text,
      PRIMARY KEY (dept,empno)
    ) WITH CLUSTERING ORDER BY (empno ASC);
    

    现在,我可以按部门查询员工,他们将通过empno 订购返回给我。 :
    SELECT * FROM emp_by_dept WHERE dept='IT';
    

    但要清楚,你会不是 能够查询表中的每一行,并按单列排序。在结果集中获得有意义的顺序的唯一方法是首先以对您的业务案例有意义的方式对数据进行分区。运行未绑定(bind) SELECT将返回您的所有行(假设查询在尝试查询集群中的每个节点时不会超时),但结果集排序只能在分区内强制执行。因此,您必须按分区键进行限制才能使其有意义。

    我为自我推销道歉,但去年我为 DataStax 写了一篇文章,名为 We Shall Have Order! ,其中我讨论了如何解决这些类型的问题。读一读,看看它是否有帮助。

    编辑其他问题:

    From your answer I concluded 2 things about Cassandra:

    (1) There is no way of getting a result set which is only order by a column that has been defined as Unique.

    (2) When we define a PK (partition-key+clustering-key), then the results will always be order by Clustering columns within any fixed partition key (we must restrict to one partition-key value), that means there is no need of ORDER BY clause, since it cannot ever change the order of rows (the order in which rows are actually stored), i.e. Order By is useless.



    1) Cassandra 中的所有 PRIMARY KEY 都是唯一的。无法按分区键对结果集进行排序。在我的示例中,我按 empno 订购(按部门分区后)。 – 亚伦 1 小时前

    2)不要说 ORDER BY 没用,我会说它唯一真正的用途是在 ASC 和 DESC 之间切换排序方向。

    I created an index on "empno" column of "emp" table, it is still not allowing ORDER BY empno. So, what Indexes are for? are they only for searching records for specific value of index key?



    您不能按索引列对结果集进行排序。二级索引(与其对应的关系索引不同)实际上仅对边缘情况、基于分析的查询有用。它们不能扩展,因此一般建议不要使用二级索引。

    Ok, that simply means that one table cannot be used for getting different result sets with different conditions and different sorting order.



    正确。

    Hence for each new requirement, we need to create a new table. IT means if we have a billion rows in a table (say Sales table), and we need sum of sales (1) Product-wise, (2) Region-wise, then we will duplicate all those billion rows in 2 tables with one in clustering order of Product, the other in clustering order of Region,. and even if we need to sum sales per Salesman_id, then we build a 3rd table, again putting all those billion rows? is it sensible?



    这真的由你来决定它有多明智。但是缺乏查询灵活性是 Cassandra 的一个缺点。为了解决这个问题,您可以继续创建查询表(即,为了性能而交易磁盘)。但是,如果它变得笨拙或难以管理,那么就该考虑 Cassandra 是否真的是正确的解决方案。

    编辑 20160321

    Hi Aaron, you said above "Stopping short of saying that ORDER BY is useless, I'll say that its only real use is to switch your sort direction between ASC and DESC."

    But i found even that is not correct. Cassandra only allows ORDER by in the same direction as we define in the "CLUSTERING ORDER BY" caluse of CREATE TABLE. If in that clause we define ASC, it allows only order by ASC, and vice versa.



    如果没有看到错误消息,很难知道该告诉您什么。虽然我听说过 ORDER BY 的查询当您在分区中存储太多行时失败。
    ORDER BY如果您指定多个要排序的列,它的功能也会有点奇怪。如果我定义了两个聚类列,我可以使用 ORDER BY在第一列不分青红皂白。但是一旦我将第二列添加到 ORDER BY子句,我的查询仅在指定两个排序方向相同(如 CLUSTERING ORDER BY 定义)或两者不同时才有效。如果我混合搭配,我会得到这个:
    InvalidRequest: code=2200 [Invalid query] message="Unsupported order by relation"
    

    我认为这与数据如何存储在磁盘上有关。否则 Cassandra 在准备结果集方面会有更多工作要做。而如果它要求一切都匹配或镜像 CLUSTERING ORDER BY 中指定的方向,它只能中继从磁盘的顺序读取。所以最好在您的 ORDER BY 中只使用一列条款,以获得更可预测的结果。

    关于cassandra - Cassandra CQL 中的 Where 和 Order By 条款,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35708118/

    相关文章:

    database - Apache Ignite-Cassandra 集成,数据重复?

    cassandra - 如何在使用命令行时使用 CQL 获取当前时间戳?

    cassandra - 根据 Where 子句更新 Cassandra 中的列

    scala - 在 Spark 中读取文件时出错

    cassandra - 了解 Cassandra 复合键

    java - 如何知道 Cassandra(CQL) 中受影响的行?

    c++ - Cassandra 中的 Blob 数据类型

    cassandra - 在cassandra表中动态添加列

    java - 从 Java 应用程序将数据导入 Cassandra 2 的最快方法是什么?

    php - 是否有任何 IDE 或 GUI 可用于使用 PHP 处理 CASSANDRA DATABASE?