【问题标题】:Cassandra does not support DELETE on indexed columnsCassandra 不支持在索引列上删除
【发布时间】:2016-07-07 15:37:20
【问题描述】:

假设我有一个具有以下架构的 cassandra 表 xyz:

create table xyz(
xyzid uuid,
name text,
fileid int, 
sid    int,
PRIMARY KEY(xyzid));

我在列 fileid , sid 上创建索引:

CREATE INDEX file_index ON xyz (fileid);
CREATE INDEX sid_index ON xyz (sid);

我插入数据:

INSERT INTO xyz (xyzid, name , fileid , sid ) VALUES ( now(), 'p120' , 1, 100);
INSERT INTO xyz (xyzid, name , fileid , ssid ) VALUES ( now(), 'p120' , 1, 101);
INSERT INTO xyz (xyzid, name , fileid , sid ) VALUES ( now(), 'p122' , 2, 101);

我想使用索引列删除数据:

 DELETE from xyz WHERE fileid=1 and sid=101;

为什么会出现这个错误?

InvalidRequest: code=2200 [Invalid query] message="Non PRIMARY KEY fileid found in where clause"
  1. 删除查询需要在where子句中指定主键吗?

  2. Cassandra 是否支持使用二级索引 s 进行删除?

  3. 使用二级索引s删除数据需要做什么?

  4. 任何可能有帮助的建议。

我正在使用 Data Stax Community Cassandra 2.1.8,但我也想知道 Data Stax Community Cassandra 3.2.1 是否支持使用索引列进行删除

谢谢

【问题讨论】:

  • 您真正只通过 PRIMARY KEY 查询的频率是多少?如果这些索引对您来说非常重要,为什么不创建一个使用这些索引列作为 PRIMARY KEY 组件的查询表?

标签: cassandra datastax cqlsh cassandra-3.0


【解决方案1】:

让我试着按顺序回答你的问题:

1) 是的,如果您要在 CQL 语句中使用 where 子句,那么 PARTITION KEY 必须是 where 子句中的相等运算符。除此之外,您只能过滤主键中指定的集群列。 (除非你有二级索引)

2) 不,它没有。有关更多信息,请参阅这篇文章,因为它本质上是相同的问题。 Why can cassandra "select" on secondary key, but not update using secondary key? (1.2.8+)

3) 为什么不在主键中添加sid 作为集群列。这将允许您按照所示使用两者进行删除或查询。

create table xyz( xyzid uuid, name text, fileid int, sid int, PRIMARY KEY(xyzid, sid));

4) 通常,使用二级索引被认为是一种反模式(C* 3.4 中的 SASI 索引稍微少一点)所以我的问题是您可以将这些字段作为集群列添加到您的主键中吗?您如何查询这些二级索引?

【讨论】:

  • 我加 1。我喜欢你对#4 的回答……怎么强调都不过分。太多人将 Cassandra 视为关系数据库,然后想知道为什么它不能像他们想象的那样工作。
  • @bechbd :即使我将“sid”字段保留为聚类列。并从 sid = 101 的 xyz 触发查询 DELETE。最终会出现此错误:“缺少某些分区键部分:xyzid”。一个 Sid 将在表中定义一组特定的数据。我基本上想触发一个查询,该查询将删除所有具有我在 where 子句中提到的 sid 的数据。如果我必须指定“xyzid”和“sid”来删除属于“sid”的特定数据集,我该怎么做?对我来说 xyzid 只是它使每一行都独一无二。你有什么建议?
  • 在 CQL 中,您始终必须在 where 子句中包含整个 PARTITION KEY,包括在删除时。因此,根据您在此处的说明``` One Sid 将在表中定义一组特定的数据``` 这将导致我说您应该使用sid 字段作为表中的PARTITION KEY 而不是xyzid。
  • 但是如果我有 sid 作为 PARTITION KEY ,每一行将如何是唯一的?假设我有 10 行 sid 100 ?如果我将 sid 保留为 PARTITION KEY,它将被覆盖吗?
  • 您会使用主键 (sid, xyzid) 之类的东西。这将使您能够通过WHERE sid=A AND xyzid=B 找到更新等的单独行,还允许您通过WHERE sid=A 删除整个 sid。
【解决方案2】:

我想你可以分两步执行删除:

  1. 通过二级索引选择数据并获取主索引列值 (xyzid) 来自查询结果
  2. 按主索引值执行删除。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-27
    • 1970-01-01
    • 2016-04-26
    • 2019-08-18
    相关资源
    最近更新 更多