Cassandra不是按主键排序

时间:2017-01-09 18:57:15

标签: cassandra cql cql3

我正在尝试在卡桑德拉模拟一张桌子,我很新,偶然发现了一个问题。我有以下内容:

CREATE TABLE content_registry (
    service text,
    file text,
    type_id tinyint,
    container text,
    status_id tinyint,
    source_location text,
    expiry_date timestamp,
    modify_date timestamp,
    create_date timestamp,
    to_overwrite boolean,
    PRIMARY KEY ((service), file, type_id)
);

据我所知:

  • service是我的分区键,基于此值将生成哈希值,并且值将在群集中分割
  • file是群集密钥
  • type_id是群集密钥
  • 这三个实体组合了一个复合(复合)主键

我已经想到的是,每当我插入新数据时,Cassandra都会upsert(如果存在该复合主键的值,则插入或更新)

现在我正在努力的是,我希望我的数据按create_date按降序排序,但create_date不是主键的一部分。

如果我将create_date添加到我的主键,我将无法插入数据,因为create_date表示插入记录时的时间戳,所以如果我每次都将它添加到主键插入,我最终会有多个记录。

还有哪些其他选择?申请中的订单?这看起来效率不高。

3 个答案:

答案 0 :(得分:2)

  

我发现的是每当我要插入新数据时,Cassandra   将upsert(如果使用该化合物的值,则插入或更新   主键存在)

完全正确。

  

现在我正在努力的是,我希望我的数据按照排序方式返回   create_date按降序排列,但create_date不是其中的一部分   首要的关键。   如果我将create_date添加到我的主键,我就无法进行upsert   数据,因为create_date表示插入记录时的时间戳,所以   如果我每次插入时都将它添加到主键,我就会结束   有多个记录。

这些句子实际上是矛盾的。

如果create_date不是您的密钥的一部分,而是属性并且数据已插入,则表示记录始终相同。因此,当通过密钥查询并获取create_date时,您总是拥有最新的。如果你真的想要记录创建的日期,你应该在第一次插入该记录后不再覆盖数据。

如果您希望表示一系列数据,则确实需要避免插入,这可以通过使用create_date作为附加分区键来完成。我宁愿使用time_uuid来使用非常方便的功能。

最后但同样重要的是,最有趣的问题是,您想反映的实际用途是什么。在cassandra中建模数据时,您应始终知道需要提前运行的查询。

答案 1 :(得分:2)

Cassandra的关键概念是你必须决定你的PRIMARY KEY是什么,这就是你的行中查询时唯一已知的内容。这是一个非常基本的要求,因为没有认识到这将导致一个糟糕的模型。

从我所看到的,您将service标识为您的PARTITION KEY,因此我认为此字段是“规则”您的数据。这是你必须真正知道甚至执行单个查询的事情(忽略低效的表扫描SELECT * FROM content_registry;)。在每个service中,您当前的行按file排序,然后按type_id排序。我不知道后一个字段的确切含义,但您现在可以通过('service1', 'a.jpg', 1)('service1', 'a.jpg', 2)标识两行。因此,如果type_id以某种方式与file相关,则模型有点不正确。

现在,假设您想要以另一个顺序为每个service获取相同的记录,您真正需要做的是创建另一个表,其中包含create_date作为第一个聚类列,例如(service, create_date, file, type_id)。这将允许您获取按创建日期排序的记录,并且当在同一日期创建两个记录时,它们将由file进一步排序,然后由type_id进行排序。

第二种方法是将辅助索引附加到原始表的create_date字段。这将允许按创建日期进行查询。

第三种方法,可能比第二种方法更好,就是使用物化视图。它会为你隐藏很多负担,并且可能比二级索引更好地扩展。

请注意,二级索引或物化视图通常无法很好地扩展。检查这些方法是否足以满足您的使用需求。

答案 2 :(得分:0)

  

如果我将create_date添加到主键,我将无法插入数据。

为什么不呢?假设您的密钥是PRIMAY KEY (service, create_date, file, type_id)?这样,您就可以按create_date 为每项服务排序,但不能全局排序。

如果你想全局地做(也就是说,你希望所有服务和所有文件按创建日期排序),那么如果你仍然希望能够对数据进行分片,那么事情可能会更复杂。一种选择是制作主键PRIMARY KEY (create_date, service, file, type_id)并使用其中一个order preserving partitioners

此外,还有更多信息:http://www.datastax.com/dev/blog/we-shall-have-order

相关问题