Cassandra 防止重复

标签 cassandra cql cql3

我有一个由 userId 分发的简单表:

create table test (
  userId uuid,
  placeId uuid,
  visitTime timestamp,
  primary key(userId, placeId, visitTime)
) with clustering order by (placeId asc, visitTime desc);

每对(userId, placeId)可以有 1 次访问或没有访问。 visitTime只是一些与之相关的数据,用于在查询中排序,如 select * from test where userId = ? order by visitTime desc .

我怎样才能要求 (userId, placeId)是独一无二的?我需要确保
insert into test (userId, placeId, timeVisit) values (?, ?, ?)

不会插入对 (userId, placeId) 的第二次访问随着不同的时间。在插入之前检查是否存在不是原子的,有没有更好的方法?

最佳答案

让我明白——如果这对夫妇(userId, placeId)应该是唯一的,(意思是你不必用这对数据放两行)什么是timeVisit在主键中有用吗?为什么要使用 order by visitTime desc 执行查询如果这将只有一行?

如果您需要的是防止重复,您有两种方法。

1 - 轻量级交易——这个,使用 IF NOT EXISTS会做你想做的。但正如我所解释的 here由于 cassandra 的特殊处理,轻量级事务真的很慢

2 - USING TIMESTAMP写入时间强制执行 -(小心!***)“技巧”是强制减少 TIMESTAMP
让我举个例子吧:

INSERT INTO users (uid, placeid , visittime , otherstuffs ) VALUES ( 1, 2, 1000, 'PLEASE DO NOT OVERWRITE ME') using TIMESTAMP 100;

这会产生这个输出
select * from users;

 uid | placeid | otherstuffs                | visittime
-----+---------+----------------------------+-----------
   1 |       2 | PLEASE DO NOT OVERWRITE ME |      1000

现在让我们减少 timestamp
INSERT INTO users (uid, placeid , visittime , otherstuffs ) VALUES ( 1, 2, 2000, 'I WANT OVERWRITE YOU') using TIMESTAMP 90;

现在表中的数据没有更新 ,因为这对夫妇 (uid, placeid) 有更高的 TS 操作 (100) -- 实际上这里的输出没有改变
select * from users;

 uid | placeid | otherstuffs                | visittime
-----+---------+----------------------------+-----------
   1 |       2 | PLEASE DO NOT OVERWRITE ME |      1000

如果性能很重要,则使用解决方案 2,如果性能无关紧要,则使用解决方案 1。对于解决方案 2,您可以使用固定数字减去系统时间毫秒来计算每次写入的递减时间戳

例如:
Long decreasingTimestamp = 2_000_000_000_000L - System.currentTimeMillis();

*** 例如,如果您想删除然后重新插入数据,此解决方案可能会导致意外行为。重要的是要知道,一旦删除数据,只有在写入操作将具有更高的删除时间戳时,您才能再次写入它们(如果未指定,则使用的时间戳是机器的时间戳)

哈,
卡罗

关于Cassandra 防止重复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28856303/

相关文章:

cassandra - 当节点重新同步其数据时,cassandra 能否保证复制因子?

replication - R + W > N 对 Cassandra 集群有什么影响?

具有多种条件的 Cassandra 数据模型

cassandra - CQL 表中的空列

java - 为一个或多个 @Params 创建 Cassandra @Query

cassandra - CQL3 中一组列的 TTL 字段 - Cassandra

cassandra - 是否有可能有一个不复制的 Cassandra 表?

cassandra - 如何使用 auto_bootstrap 属性高效启动/重启 Cassandra 节点

java - 使用 DataStax Java 驱动程序 1.0.4 通过 CQL 连接到 Cassandra 时出现异常

cassandra - 在 Cassandra 中有大量写入和一些读取的表。主键搜索需要 30 秒。 (队列)