Cassandra DB 将数据插入多个表

问题描述

我一直在阅读有关 datastax 的 Cassandra Db 文档以及 Apache 文档。到目前为止,我已经了解到我们不能在一张表上创建多个索引(一个主索引,一个二级索引)。每个查询都应该有一个单独的表。 将此与 sql 表进行比较,例如我们要查询 4 ​​个字段的表,对于此表,在 Cassandra 的情况下,我们应该将此表拆分为 4 个表,对吗? (如果我错了,请纠正我)。 在这 4 个表上,我可以拥有索引并进行查询, 我的问题是如何将数据插入到这4张表中,我应该连续发出4次插入请求吗?

我的首要任务是避免二级索引

解决方法

要在非规范化表之间保持数据同步,您需要使用 CQL BATCH 语句。

例如,如果您要维护这些表:

  • movies
  • movies_by_actor
  • movies_by_genre

然后您可以像这样在 CQL BATCH 中对更新进行分组:

BEGIN BATCH
  INSERT INTO movies (...) VALUES (...);
  INSERT INTO movies_by_actor (...) VALUES (...);
  INSERT INTO movies_by_genre (...) VALUES (...);
APPLY BATCH;

请注意,也可以批量执行 UPDATEDELETE 语句以及条件写入。

上面的例子在cqlsh中只是为了说明,实际中并未使用。以下是使用 Java 驱动程序的示例 BatchStatement

SimpleStatement insertMovies =
  SimpleStatement.newInstance(
    "INSERT INTO movies (...) VALUES (?,...)",<some_values>);

SimpleStatement insertMoviesByActor =
  SimpleStatement.newInstance(
    "INSERT INTO movies_by_actor (...) VALUES (?,<some_values>);

SimpleStatement insertMoviesByGenre =
  SimpleStatement.newInstance(
    "INSERT INTO movies_by_genre (...) VALUES (?,<some_values>);

BatchStatement batch =
  BatchStatement.builder(DefaultBatchType.LOGGED)
    .addStatement(insertMovies)
    .addStatement(insertMoviesByActor)
    .addStatement(insertMoviesByGenre)
    .build();

有关详细信息,请参阅 Java driver Batch statements。干杯!

,

Cassandra 支持二级索引,SSTable Attached Secondary Index(SASI)。存储附加索引 (SAI) 已捐赠给该项目,但尚未被接受。

您需要创建您的表,以便您可以使用类似这样的单个查询从表中获取所有需要的数据

SELECT * from keyspace.table_name where key = 'ABC';

那么对于设计师来说,这意味着什么。您需要识别所有查询,并根据这些查询定义数据模型(表)。因此,如果您认为需要 4 个表来满足您的查询,那么您是对的。

由于您定义的所有 4 个表如果表示相同的数据,则必须保持同步,因此最好的方法是使用批处理

BEGIN BATCH 
  DML_statement1 ;
  DML_statement2 ;
  DML_statement3 ;
  DML_statement4 ;
APPLY BATCH ;

Batch 不保证所有语句都会成功回滚。它通知客户端语句组失败。所以客户应该重新尝试应用它们。

如果可以,最好避免使用二级索引,因为它们存在性能问题。一般的经验法则是索引具有少量值的低基数的列。