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,您应该尽最大努力避免未绑定的 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';
但需要明确的是,您将不能够查询表中的每一行,并使其按单列排序。在结果集中获得有意义的顺序的唯一方法是首先以对您的业务案例有意义的方式对数据进行分区。运行未绑定的SELECT 将返回所有行(假设查询在尝试查询集群中的每个节点时不会超时),但结果集排序只能在分区内强制执行。因此,您必须通过分区键进行限制才能使其有意义。
对于自我推销,我深表歉意,但去年我为 DataStax 写了一篇名为 We Shall Have Order! 的文章,其中讨论了如何解决这些类型的问题。读一读,看看是否有帮助。
编辑其他问题:
从你的回答中我总结出关于 Cassandra 的两件事:
(1) 没有
获取仅按具有的列排序的结果集的方法
被定义为唯一。
(2) 当我们定义一个 PK
(partition-key+clustering-key),那么结果总是有序的
通过在任何固定分区键中聚类列(我们必须限制
到一个分区键值),这意味着不需要 ORDER BY
子句,因为它永远不能改变行的顺序(在
实际存储了哪些行),即 Order By 没用。
1) Cassandra 中的所有主键都是唯一的。无法按分区键对结果集进行排序。在我的示例中,我按empno 订购(按部门分区后)。 – 亚伦 1 小时前
2) 不要说 ORDER BY 没用,我会说它唯一真正的用途是在 ASC 和 DESC 之间切换排序方向。
我在“emp”表的“empno”列上创建了一个索引,它仍然没有
允许 ORDER BY empno。那么,索引是干什么用的?他们只是为了
搜索记录以查找索引键的特定值?
您不能按索引列对结果集进行排序。二级索引(与其对应的关系索引不同)实际上只对边缘情况、基于分析的查询有用。它们无法扩展,因此一般建议不要使用二级索引。
好的,这只是意味着一张表不能用于获取
不同的结果集不同的条件和不同的排序
顺序。
正确。
因此,对于每个新需求,我们都需要创建一个新表。
IT 意味着如果我们在一个表中有十亿行(比如 Sales 表),并且
我们需要销售额总和(1)产品方面,(2)地区方面,然后我们将
将所有这些十亿行复制到 2 个表中,其中一个在集群中
Product 的顺序,另一个在 Region 的聚类顺序中。乃至
如果我们需要对每个 Salesman_id 的销售额求和,那么我们构建第三个表,
再次放置所有这些十亿行?合理吗?
这真的是由你来决定它是多么明智。但缺乏查询灵活性是 Cassandra 的一个缺点。为了解决这个问题,您可以继续创建查询表(即,交易磁盘以获得性能)。但是,如果它变得笨拙或难以管理,那么是时候考虑一下 Cassandra 是否真的是正确的解决方案。
编辑 20160321
嗨 Aaron,您在上面说过“不要说 ORDER BY 没用,我会说它唯一真正的用途是在 ASC 和 DESC 之间切换您的排序方向。”
但我发现即使这样也不正确。 Cassandra 只允许按照我们在 CREATE TABLE 的“CLUSTERING ORDER BY”中定义的方向进行排序。如果在该子句中我们定义 ASC,则它只允许按 ASC 排序,反之亦然。
没有看到错误消息,很难知道该告诉您什么。虽然我听说过使用 ORDER BY 的查询在分区中存储的行过多时会失败。
ORDER BY 如果您指定多个列作为排序依据,其功能也会有些奇怪。如果我定义了两个聚类列,我可以在第一列上不加选择地使用ORDER BY。但是,一旦我将第二列添加到 ORDER BY 子句,我的查询只有在我指定 both 排序方向相同(与 CLUSTERING ORDER BY 定义一样)或 both 时才有效em> 不同。如果我混合搭配,我会得到这个:
InvalidRequest: code=2200 [Invalid query] message="Unsupported order by relation"
我认为这与数据在磁盘上的存储方式有关。否则,Cassandra 在准备结果集方面需要做更多的工作。而如果它要求一切都匹配或镜像CLUSTERING ORDER BY 中指定的方向,它可以只中继从磁盘中的顺序读取。因此,最好只在 ORDER BY 子句中使用单列,以获得更可预测的结果。