【问题标题】:How to synchronise and and update denormalised cassandra table如何同步和更新非规范化的 cassandra 表
【发布时间】:2021-10-20 00:02:26
【问题描述】:

我在使用 cassandra 开发 Spring 应用程序时偶然发现了一个问题。 通过实践,Cassandra 在设计数据模型时鼓励设计查询,而一个一直困扰我的阻止程序是当其中一个表更新它的值并且恰好发生特定值是另一个表上的主键时会发生什么?

见下图 Photo

在照片中,如果我们将用户电子邮件更新为另一个值,我通常会在 Spring cassandra 中进行保存,但是在执行批处理操作时,由于新的分区键,它会在 user_by_email 表中添加一个新条目。

您对此类问题的典型解决方案是什么?我考虑过先查询旧电子邮件,然后对 user_by_email 表进行删除,但这对我来说效率低下。

【问题讨论】:

    标签: java spring cassandra nosql


    【解决方案1】:

    要使非规范化表保持同步,您需要使用 CQL BATCH 语句。它将插入、更新和删除分组到一个原子事务中。看看这篇文章,我已经更详细地解释了它——https://community.datastax.com/articles/2744/

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

    • 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。干杯!

    【讨论】:

    • 我对批处理操作有一些很好的想法,但是我目前的问题是尝试更新 User 表电子邮件,并且由于我的表已去规范化,因此我也有 user_by_email 表。如果我要更新用户表上的电子邮件,那么在对 user_by_email 进行批处理操作时,它将插入一个新条目而不是更新 user_by_email 中的旧条目,因为电子邮件是一个新值
    • 思路是一样的。但是,除了 2 个表只有 2 个 INSERTs 之外,批处理中还包含 user_by_email 表的 DELETE。干杯!
    • 我明白了。这听起来很沉重,因为我必须在每次保存操作之前进行读取以检索旧电子邮件值以进行删除。
    猜你喜欢
    • 2014-10-03
    • 2016-10-22
    • 1970-01-01
    • 2017-10-23
    • 2016-05-13
    • 2018-07-31
    • 2018-05-31
    • 1970-01-01
    • 2017-07-09
    相关资源
    最近更新 更多