Cassandra:DELETE不起作用

时间:2015-04-02 02:26:59

标签: cassandra row cql

我有一张这样的表:

CREATE TABLE ab(group int,timestamp varchar,ab_id uuid, PRIMARY KEY (group,timestamp,ab_id)) WITH CLUSTERING ORDER BY (timestamp DESC);

布局:

1 | 2015-04-01 08:48:46 | 07d2a30d-79f3-5619-bbdd-6e5140a68ec3
1 | 2015-04-01 08:47:24 | 08d3a40c-85c7-5823-ddcc-7e6174d78dg4
1 | 2015-04-01 08:46:33 | c35dedeb-3144-5818-c282-53cd7ee1e8e8

我可以使用插入和选择查询,但我无法删除一行。 我必须使用所有主键,因为DELETE是保留的,所以我尝试了:

 DELETE FROM ab WHERE ab_id=2d1ddf9a-2e80-41ea-b891-e322edfb905e  AND "timestamp"='2015-04-02 03:29:54' AND group = 1;

但什么都没发生,没有消息错误,也没有删除行...... ??

2 个答案:

答案 0 :(得分:1)

  

当我像select语句那样执行select语句时,它给了我(0行)。

其中(如LordKain所示)意味着如果你没有SELECT,那么你也不会对DELETE产生任何影响。

  

如果我在列上创建索引并使用允许过滤从此列中选择*,我可以使用select语句

请勿这样做。在我最近回答的几个与查询相关的问题中,似乎有很多人认为使用ALLOW FILTERING的查询是个好主意。这些相同的用户通常会在一周左右的时间内回来,想知道为什么他们的ALLOW FILTERING查询会突然超时,数据更多。询问ALLOW FILTERING是Cassandra告诉你的事情,你正在尝试一些你可能不应该做的事情。

此外,二级索引您的朋友。它们是为了方便而创建的,而不是为了表现。有些人甚至将其用作反模式。

Cassandra旨在按特定顺序通过特定键进行查询。如果您的表不适合您的查询,那么您需要构建一个额外的表。这将允许您在没有ALLOW FILTERING或二级索引的情况下执行查询。

  

当我尝试这个时(选择*来自ab,其中ab_id = xxxx),它表示我必须输入主键时间戳,当我这样做时,它表示与主键组相同,当我这样做时他一无所获,一无所获。

那是因为DELETE操作需要特定的,完整的PRIMARY KEY。在你的情况下,这应该工作:

DELETE FROM ab WHERE group=1 AND timestamp='2015-04-01 08:48:46' 
    AND ab_id=07d2a30d-79f3-5619-bbdd-6e5140a68ec3;

如果缺少一个或多个PRIMARY KEY组件,则DELETE将无效。这里存在的缺点是将表中的每一列指定为PRIMARY KEY的一部分。删除行时,您需要全部指定。

该规则的例外是您可以通过指定完整的分区键来删除。所以在你的情况下,这应该有效:

DELETE FROM ab WHERE group=1;

当然,这将删除group分区键1下的所有行,这可能不是您想要的。

最重要的是,Cassandra PRIMARY KEYs的行为与RDBMs PRIMARY KEYs不同。因此,您无法使用RDBMS思维模式构建Cassandra数据模型。

答案 1 :(得分:0)

我之前发现自己处于类似的境地。我们做的时候,

SELECT * FROM ab;

您可能会看到类似的内容,

group |      timestamp      |              ab_id
   1  | 2015-04-01 08:48:46 | 07d2a30d-79f3-5619-bbdd-6e5140a68ec3
   1  | 2015-04-01 08:47:24 | 08d3a40c-85c7-5823-ddcc-7e6174d78dg4
   1  | 2015-04-01 08:46:33 | c35dedeb-3144-5818-c282-53cd7ee1e8e8
   1  | 2015-04-02 03:29:54 | 2d1ddf9a-2e80-41ea-b891-e322edfb905e  <- Pay attention on this one

当我们查询类似的内容时,

 SELECT * FROM ab WHERE group = 1 AND "timestamp"='2015-04-02 03:29:54' AND ab_id=2d1ddf9a-2e80-41ea-b891-e322edfb905e;

您可能会看到类似的内容,

group |      timestamp      |              ab_id
      |                     |                                       <- Cannot see it!

但是当我们这样查询时,

SELECT * FROM ab WHERE group = 1 AND timestamp >'2015-04-02 03:29:54';

你会得到,

group |      timestamp      |              ab_id
   1  | 2015-04-02 03:29:54 | 2d1ddf9a-2e80-41ea-b891-e322edfb905e  <- Pay attention on this one

这是因为,即使CQLSH显示时间戳为2015-04-02 03:29:54,已存储的实际数据也会显示为2015-04-02 03:29:54.156

有两种方法可以找到(可能更多?)。

  1. 如果您使用的是旧版本的Apache Cassandra / DSE,则可以使用cassandra-cli
  2. 如果您使用的是上述工具已弃用的较新版本,则可以使用Apache Spark和spark-cassandra-connector
  3. 我正在使用DSE,因此我很快创建了一个SparkDF,然后查询以查找。