订购Cassandra的任何领域

时间:2015-05-23 22:27:25

标签: sorting cassandra cql

我正在研究cassandra作为我即将到来的项目的可能解决方案。我研究的越多,我就会越多地听到在创建表时对未设置排序的字段进行排序是个坏主意。

是否可以对任何领域进行排序?如果对不在群集中的字段进行排序会对性能产生什么影响?我需要在表格中排序或约200万条记录。

1 个答案:

答案 0 :(得分:9)

  

我一直听说在创建表格时对未设置排序的字段进行排序是个坏主意。

这不是一个坏主意。实际上不可能让Cassandra按任意列对数据进行排序。 Cassandra需要一种基于查询的建模方法,这也适用于排序顺序。您必须提前决定您希望Cassandra支持的查询类型,以及这些查询返回其数据的顺序。

  

是否可以对任何字段进行排序?

以下是Cassandra如何对结果集进行排序的事情:事实并非如此。 Cassandra查询对应于分区位置,数据从磁盘读取并返回给您。如果数据的读取顺序与在磁盘上排序的顺序相同,则将对结果集进行排序。另一方面,如果您尝试多键查询或基于索引的查询,它必须跳转到不同的分区,很可能不会以任何有意义的顺序返回。

但是,如果您提前计划,您实际上可以影响数据的磁盘排序顺序,然后在查询中利用该顺序。这可以通过称为“聚类列”的建模机制来完成。 Cassandra允许您指定多个聚类列,但它们仅在单个分区中有效。

那是什么意思?拿this example from the DataStax documentation

CREATE TABLE playlists (
  id uuid,
  artist text,
  album text,
  title text,
  song_order int,
  song_id uuid,
  PRIMARY KEY ((id),song_order))
WITH CLUSTERING ORDER BY (song_order ASC);

通过此表定义,我可以通过playlist(分区键)查询特定id。在每个id内,数据将按song_order排序:

SELECT id, song_order, album, artist, title 
FROM playlists WHERE id = 62c36092-82a1-3a00-93d1-46196ee77204
ORDER BY song_order DESC;

id                                   | song_order | album                 | artist         | title
------------------------------------------------------------------------------------------------------------------
62c36092-82a1-3a00-93d1-46196ee77204 | 4          | No One Rides For Free |      Fu Manchu |             Ojo Rojo    
62c36092-82a1-3a00-93d1-46196ee77204 | 3          |             Roll Away | Back Door Slam |  Outside Woman Blues
62c36092-82a1-3a00-93d1-46196ee77204 | 2          |          We Must Obey |      Fu Manchu |     Moving in Stereo
62c36092-82a1-3a00-93d1-46196ee77204 | 1          |          Tres Hombres |         ZZ Top |            La Grange

在此示例中,如果我只想指定ORDER BY,则需要切换排序方向。由于行以ASC结束顺序存储,因此我需要指定DESCDESC结尾顺序查看它们。如果我以ASC结尾顺序返回行,那么我根本不需要指定ORDER BY

但如果我想通过艺术家订购怎么办?还是专辑?或两者?由于一位艺术家可以拥有多张专辑(对于此示例),我们将修改PRIMARY KEY定义,如下所示:

PRIMARY KEY ((id),artist,album,song_order)

运行上面的相同查询(减去ORDER BY)会产生此输出:

SELECT id, song_order, album, artist, title 
FROM playlists WHERE id = 62c36092-82a1-3a00-93d1-46196ee77204;

id                                   | song_order | album                 | artist         | title
------------------------------------------------------------------------------------------------------------------
62c36092-82a1-3a00-93d1-46196ee77204 | 3          |             Roll Away | Back Door Slam |  Outside Woman Blues
62c36092-82a1-3a00-93d1-46196ee77204 | 4          | No One Rides For Free |      Fu Manchu |             Ojo Rojo    
62c36092-82a1-3a00-93d1-46196ee77204 | 2          |          We Must Obey |      Fu Manchu |     Moving in Stereo
62c36092-82a1-3a00-93d1-46196ee77204 | 1          |          Tres Hombres |         ZZ Top |            La Grange

请注意,行现在按artist排序,然后按album排序。如果我们有两首来自同一专辑的歌曲,那么song_order就是下一首。

所以现在你可能会问“如果我只想按album排序,而不是artist?”您只能按album排序,但不能使用此表排序。您不能跳过ORDER BY子句中的群集键。要仅按album(而不是artist)进行排序,您需要设计不同的查询表。有时,Cassandra数据建模会让您复制几次数据,以便能够提供不同的查询... ,这没关系

有关如何在利用群集顺序的同时构建数据模型的更多详细信息,请查看PlanetCassandra上的这两篇文章: