Cassandra中的数据建模冲突

时间:2018-03-27 08:32:42

标签: cassandra cql

我正在使用的架构如下:

CREATE TABLE mytable(
id varchar,
date date,
name varchar,
PRIMARY KEY ((date),name, id)
) WITH CLUSTERING ORDER BY (name desc);

我的用例有2个查询:

  1. 获取给定name
  2. 的所有记录
  3. 删除给定date的所有记录。
  4. 由于我们无法删除未指定分区键的记录,因此我的分区键仅固定为date,并且没有其他列可以添加到分区键,因为除了{{1}之外我没有任何其他内容在删除时。

    但是要使用date获取记录,我需要使用name,因为我需要扫描上面架构的整个表格,这会导致性能问题。

    你能否提出一个更好的方法,以便我可以跳过ALLOW FILTERING同时删除ALLOW FILTERING兼容。

2 个答案:

答案 0 :(得分:1)

您可以使用索引: https://docs.datastax.com/en/cql/3.3/cql/cql_using/useSecondaryIndex.html

但是你必须要小心,根据表的大小可能存在问题。你应该阅读这篇文章了解更多信息: https://pantheon.io/blog/cassandra-scale-problem-secondary-indexes

答案 1 :(得分:1)

您需要一张额外的表来支持您的要求。 您的主要查询是检索给定名称的记录。为此,您应该使用mytable如下(注意主键):

CREATE TABLE mytable(
id varchar,
date date,
name varchar,
PRIMARY KEY ((name),date, id)
) WITH CLUSTERING ORDER BY (date desc);

此表将允许您使用(查询1)检索给定名称的数据:

 SELECT * FROM mytable WHERE name='bob';

现在,您希望能够按日期删除。为此,您需要以下附加表:

CREATE TABLE mytable_by_date(
id varchar,
date date,
name varchar,
PRIMARY KEY ((date), name, id)
) WITH CLUSTERING ORDER BY (name);

此表格可让您找到给定日期的名称(和ID):

SELECT * from mytable_by_date WHERE date='your-date';

我不了解您的业务需求,因此您的此查询可能会返回0,1或更多结果。一旦你有了,你可以对第一个和第二个表发出删除(可能使用已记录的批处理原子性?)

DELETE * from mytable_by_date WHERE date='your-date' and name='the-name' and id='the-id'
DELETE * from mytable WHERE name='the-name' and ...

总的来说,您可能需要根据您的业务需求进行调整(名称是唯一的,是ID等强制执行的唯一性)。

希望它有所帮助!