支持现有订阅源表的逻辑删除

Oha*_*ker 6 cassandra

我想为新闻提要记录实现逻辑删除,以支持以后的撤消.
系统正在生产中,因此任何解决方案都应支持现有数据.
向记录中插入记录是幂等的,因此插入已删除的记录(具有相同的主键)不应取消删除它.
任何解决方案都应支持查询以检索现有或已删除记录的页面.

饲料表:

CREATE TABLE my_feed (
   tenant_id int,
   item_id int,
   created_at timestamp,
   feed_data text,
PRIMARY KEY (tenant_id, created_at, feed_id) )
WITH compression = { 'sstable_compression' : 'LZ4Compressor' }
AND CLUSTERING ORDER BY (created_at DESC);
Run Code Online (Sandbox Code Playgroud)

我想到了两种方法,但两者都有严重的缺点:
1.将删除的记录移到另一个表中.查询是微不足道的,不需要迁移,但幂等插入似乎很难(只有在插入之前读取?).
2.添加is_deleted列.为该列创建辅助索引以支持查询.幂等插入似乎更容易支持(轻量级事务或更新技巧).主要缺点是旧记录具有空值,因此需要数据迁移.

还有第三种更优雅的方法吗?你支持上述建议之一吗?

Cal*_*ffe 1

如果您为已删除的记录维护一个单独的表,则可以使用 CQL 的BATCH构造来执行“移动”操作,但由于唯一的删除记录位于该表中,因此如果您想要您所描述的行为,则必须首先检查它不重新激活已删除的记录。先读后写通常是一种反模式,等等。

正如您提到的,使用is_deleted可能需要一些迁移工作,但您可能遇到的潜在更严重的问题是,在基数非常低的列上创建索引通常效率极低。对于一个boolean字段,我认为您的索引将只包含两行。如果您不经常删除,则意味着您的“假”行将非常宽,因此几乎无用

如果您避免为列创建二级索引is_deleted,并且允许nullfalse指示活动记录,而仅显式true指示已删除记录,则可能不需要迁移任何内容。(您实际上知道在迁移过程中要删除哪些现有记录吗?)然后您将过滤已删除的记录留给客户端,客户端可能已经负责您的某些分页行为。这种设计的缺点是你可能需要请求 > N 条记录才能得到 N 条未被删除的记录!

我希望这对您有所帮助并解决您所说的问题。我很想知道为什么您需要防止已删除的记录被恢复,但我可以想象这样一种情况:您有多个参与者在处理特定的 feed(以及可能出现的 CAS 问题)。

在某种程度上不相关的说明中,您可能需要考虑使用timeuuid而不是用于timestamp您的created_at领域。CQL 支持一个dateOf()函数来检索该日期(如果该日期是一个绊脚石)。(你的分区内也可能不可能发生冲突tenant_id,在这种情况下你可以放心地忽略我。)