【发布时间】:2015-08-05 17:52:31
【问题描述】:
我正在研究 cassandra 作为我即将开展的项目的可能解决方案。我研究得越多,我听到的消息越多,在创建表时对未设置排序的字段进行排序是个坏主意。
是否可以对任何字段进行排序?如果对不在集群中的字段进行排序会影响性能,那么性能影响是什么?我需要对表中大约 200 万条记录进行排序。
【问题讨论】:
我正在研究 cassandra 作为我即将开展的项目的可能解决方案。我研究得越多,我听到的消息越多,在创建表时对未设置排序的字段进行排序是个坏主意。
是否可以对任何字段进行排序?如果对不在集群中的字段进行排序会影响性能,那么性能影响是什么?我需要对表中大约 200 万条记录进行排序。
【问题讨论】:
我一直听说,在创建表时对未设置排序的字段进行排序是个坏主意。
这并不是一个坏主意。真的不可能让 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);
使用这个表定义,我可以通过id(分区键)查询特定的playlist。在每个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。由于这些行以ASCending 顺序存储,因此我需要指定DESC 才能以DESCending 顺序查看它们。如果我可以按ASCending 顺序恢复行,我根本不需要指定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 上的这两篇文章:
【讨论】: