【问题标题】:Spring Data Cassandra Insert creating cell tombstonesSpring Data Cassandra Insert 创建单元格墓碑
【发布时间】:2017-08-16 18:59:56
【问题描述】:

我正在使用 Spring Boot 1.5.1.RELEASE 和 spring-boot-starter-data-cassandra。

我遇到了一个问题,我正在使用 CassandraOperations.insert,它会导致一堆单元墓碑。这似乎是由:https://jira.spring.io/browse/DATACASS-182 引起的。由于 Spring Data 现在为空值插入一个实际的空值,这会导致单元格墓碑。我还没有找到任何方法告诉 Spring Data 不要这样做。有没有配置或者我可以说“对于这个插入,不要插入实际的空值”?

【问题讨论】:

  • 这是不可能的。您是否愿意提出投诉,以便我们讨论如何改进?
  • 当然,我会提交一张票。如果您可以在 WriteOptions 中包含类似的内容,那就太好了,这样就可以在查询级别完成。
  • AFAIU 在插入时写入 null 会创建不需要的墓碑。从查询的角度来看,写null 或单元格根本没有写应该无关紧要。在任何情况下您都想在插入时创建单元墓碑?
  • 我们也遇到过这个问题。任何对 Cassandra 的空插入都会创建一个墓碑。在某些情况下,我们有一个包含 1k+ 墓碑的单元格会导致性能问题。
  • @mp911de 好吧,根据jira.spring.io/browse/DATACASS-182,有些人希望在写入时创建墓碑,以防他们将先前设置的单元格中的值清空。因此,我认为在查询级别选择是否要写入文字空值会很有用。这样,您就不会在不想要文字空值的插入中遇到性能问题,但您仍然可以进行“更新”,您可以用空值覆盖先前设置的值。我今天会处理申请票。谢谢!

标签: cassandra spring-data spring-data-cassandra


【解决方案1】:

最简单且非侵入性的解决方案之一是使用

CassandraTemplate.insert()/CassandraBatchOperations.insert()

基本上,当生成的 CQL 具有显式空值时,会创建墓碑。例如,以下查询将插入一个墓碑。

Insert into KeyspaceName.TableName(ColumnName1, ColumnName2, ColumnName3)
values (Column1Value, Column2Value, null)

Cassandra 将插入视为 upsert,并且对于每个空值,它会尝试删除现有的列值,而不检查列值是否存在。因此,对于每个空值,它都会创建一个墓碑,这意味着该值已被删除。

但是下面的查询不会创建墓碑。

Insert into KeyspaceName.TableName(ColumnName1, ColumnName2)
values (Column1Value, Column2Value)

CassandraTemplate.insert()/CassandraBatchOperations.insert() 生成的查询忽略具有空值的列,并生成具有非空值的列的 CQL。因此不会创建墓碑。

【讨论】:

  • CassandraRepository.saveAll() 是否也能正确处理空值?
【解决方案2】:

目前这是 Spring Data Cassandra 的一个限制。我创建了https://jira.spring.io/browse/DATACASS-420 来跟踪它。我暂时解决它的方法是创建一个扩展 MappingCassandraConverter 的自定义类,并且我重写了 writeInsertFromWrapper 方法以不插入空值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-17
    • 1970-01-01
    • 2023-03-08
    • 2023-03-18
    • 2016-05-31
    • 2019-05-02
    • 2018-08-20
    • 2014-10-16
    相关资源
    最近更新 更多