我想为新闻Feed记录实施逻辑删除,以支持以后的撤消
系统正在生产中,因此任何解决方案都应支持现有数据
将记录插入到Feed中是幂等的,因此插入已删除的记录(具有相同的主键)不应取消删除它。
任何解决方案都应支持查询以检索现有或已删除记录的页面。
Feed表:
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);
我想到了两种方法但两者都有严重的缺点:
1.将删除的记录移动到其他表。查询是微不足道的,不需要迁移,但幂等插入似乎很困难(只能在插入之前读取?)。
2.添加is_deleted列。为该列创建辅助索引以支持查询。幂等插入似乎更容易支持(轻量级事务或更新技巧)。
主要缺点是旧记录具有空值,因此需要数据迁移。
还有第三种更优雅的方法吗?你支持上述建议之一吗?
答案 0 :(得分:1)
如果为已删除的记录维护一个单独的表,则可以使用CQL的BATCH
构造来执行“移动”操作,但由于唯一的删除记录位于该表中,因此如果您是希望您所描述的行为不会重新设置已删除记录的动画。在写作之前阅读通常是反模式等。
使用is_deleted
列可能需要一些迁移工作,正如您所提到的,但您可能遇到的更严重的问题是在非常低基数的列上创建索引是通常效率极低。对于boolean
字段,我认为您的索引只包含两行。如果你不太频繁地删除,那就意味着你的“假”行会很宽,因此almost useless。
如果您避免为is_deleted
列创建辅助索引,并且同时允许null
和false
指示活动记录,而只显式true
表示已删除的索引,你可能不需要迁移任何东西。 (您实际上是否知道在迁移期间要删除哪些现有记录?)然后,您将过滤已删除的记录留给客户端,客户端可能已经负责您的某些分页行为。这种设计的缺点是你可能不得不要求>获取N的N条记录未被删除!
我希望这有助于解决问题并解决问题。我很想知道为什么你需要防止已经删除的记录恢复生命,但我可以想象你有多个参与者处理某个特定的饲料(以及可能出现的CAS问题)。
在某种程度上不相关的说明中,您可能需要考虑在timeuuid
字段中使用timestamp
代替created_at
。 CQL支持dateOf()
函数来检索该日期,如果这是一个绊脚石。 (也可能无法在tenant_id
分区内发生冲突,在这种情况下,您可以安全地忽略我。)