使用部分分区键

时间:2017-07-03 15:40:04

标签: cassandra cassandra-3.0

让我们说我在Cassandra中有下表:

customer_bought_product (
    store_id uuid,
    product_id text,
    order_time timestamp,
    email text,
    first_name text,
    last_name text,
    PRIMARY KEY ((store_id, product_id), order_time, email)

分区键为store_idorder_id,用于存储时间序列数据。

数据没有TTL,因为它应该始终可以访问。

在某些情况下,我们可能会要求删除给定store_id的所有数据。 这样做的最佳做法是什么?

到目前为止,我已经考虑过以下解决方案:

  1. 编写一个程序,该程序将从表中选择所有数据并删除具有给定store_id的记录。 - 缺点是,随着我们在表格中插入更多数据,这将花费越来越多的时间。
  2. 将数据保留在表格中。 - 这样做的唯一问题是我们将拥有无用的数据。
  3. 将表名与可用的分区键存储在另一个表中,可以由store_id查询,从中获取密钥并为每个或那些密钥创建一个删除语句。 - 我不喜欢这个概念,因为我必须保留记录。
  4. 有没有人遇到过这个问题?从Cassandra中清除未使用的记录的最佳做法是什么(不包括TTL)?

2 个答案:

答案 0 :(得分:3)

创建实体化视图以存储属于相应store_ids的product_id。这样,您可以查询给定store_id的MV,然后从主表中删除相应的行。这样可以避免额外的应用程序代码来维护两个不同的表。

create materialized view mv_customer_bought_product 
as select product_id, store_id, order_time, email 
from customer_bought_product 
where order_time is not null 
and email is not null 
and product_id is not null 
and store_id is not null 
primary key (store_id, product_id, order_time, email) ;

答案 1 :(得分:1)

无法通过部分分区键删除。

这是一种方法:

创建一个单独的表,其中包含给定商店的所有product_id。

CREATE TABLE product_by_store(
store_id uuid,
product_id set<text>,
PRIMARY KEY(store_id)
);

现在写信给customer_bought_product,同时更新为product_by_store,类似

UPDATE product_by_store SET product_id=product_id + 'someValue' WHERE store_id=GIVEN_STORE_ID

您可以在写作时使用BATCH语句,这样您就可以获得原子性。

现在,在删除时,您可以获取给定store_id的所有product_id,然后使用

DELETE FROM customer_bought_product WHERE store_id=GIVEN_STORE_ID and product_id in (PRODUCT_ID YOU GET from product_by_store table)

同时从customer_bought_product

删除相应的记录