2

我一直在查看 CQL 3.0数据建模文档,该文档描述了带有标签的歌曲列族,创建如下:

CREATE TABLE songs (
    id uuid PRIMARY KEY,
    title text,
    tags set<text>
);

我想获取所有具有特定标签的歌曲的列表,所以我需要添加一个适当的索引。

我可以很容易地在列上创建索引title,但是如果我尝试索引tags作为集合的列,如下所示:

CREATE INDEX ON songs ( tags );

我从 DataStax Java 驱动程序 1.0.4 收到以下错误:

Exception in thread "main" com.datastax.driver.core.exceptions.InvalidQueryException: Indexes on collections are no yet supported
at com.datastax.driver.core.exceptions.InvalidQueryException.copy(InvalidQueryException.java:35)
at com.datastax.driver.core.ResultSetFuture.extractCauseFromExecutionException(ResultSetFuture.java:269)

根据 JIRA 问题CASSANDRA-4511,这看起来可能会在更高版本的 Cassandra (2.1) 中得到修复。但是,我目前正在使用 Apache Cassandra 1.2.11,并且还不想升级。不过根据问题CASSANDRA-5615,在 Cassandra 1.2.6 中,支持集合上的自定义索引

问题是,唯一可用的文档指出:

Cassandra 支持创建自定义索引,仅供内部使用,超出本文档的范围。

但是,它确实建议使用以下语法:

CREATE CUSTOM INDEX ON songs ( tags ) USING 'class_name';

class_name此 CQL 语句中指定的内容是什么?

有没有更好的方法来索引标签,以便我可以在歌曲表中查询具有特定标签的歌曲列表?

4

1 回答 1

5

在我看来,您尝试执行此操作的方式并不是在 Cassandra 中建模的最佳方式。您根据查询而不是数据构建模型。如果您需要按标签查找歌曲,则为此创建另一个表并复制数据。就像是 ...

CREATE TABLE tagged_songs (
  tag varchar,
  song_id uuid,
  song_title varchar,
  ... anything else you might need with your songs here ...
  PRIMARY KEY ((tag), song_id)
);

Cassandra 的前提是存储成本低廉。复制您的数据以满足您的查询。写入速度很快,写入相同的数据 3、4、10 次通常没问题。

您还希望将您的歌曲名称和您需要的任何其他信息存储到此表中。您不想在阅读时获取大量 ID 并尝试加入它。这不是关系数据库。

当有人标记一首歌曲时,您可能希望将标签插入到集合中,因为您拥有它,并将其添加到 tagged_songs 表中。查询所有带有标签 X 的歌曲基本上是 O(1)。

于 2013-12-06T21:52:53.370 回答