如何仅存储 Cassandra 中的最新条目?
How to store only most recent entry in Cassandra?
我有一个 Cassandra table 喜欢 :-
create table test(imei text,dt_time timestamp, primary key(imei, dt_time)) WITH CLUSTERING ORDER BY (dt_time DESC);
Partition Key is: imei
Clustering Key is: dt_time
现在我只想为每个分区键在此 table(基于时间)中存储最近的条目。
假设我在 table 中插入条目,其中每个 imei
都有一个条目
现在假设 imei 98838377272 dt_time 是 2017-12-23 16.20.12 现在对于相同的 imei 如果 dt_time 像 2017-12-23 15.20.00
那么这个条目不应该插入那个Cassandra table.
但是如果时间到了 2017-12-23 17.20.00 那么它应该被插入并且前一行应该被替换为这个 dt_time.
首先,要仅存储 table 中的最后一个条目,您需要从主键中删除 dt_time
- 否则您会为每个时间戳将条目插入到数据库中。
Cassandra 支持所谓的 lightweight transactions 允许在插入数据之前检查数据。
所以如果你只想在 dt_time
小于新时间时更新条目,那么你可以使用类似的东西:
首先插入数据:
> insert into test(imei, dt_time) values('98838377272', '2017-12-23 15:20:12');
尝试同时更新数据,否则可以更小
> update test SET dt_time = '2017-12-23 15:20:12' WHERE imei = '98838377272'
IF dt_time < '2017-12-23 15:20:12';
[applied] | dt_time
-----------+---------------------------------
False | 2017-12-23 15:20:12.000000+0000
这将失败,因为从 applied
等于 False
可以看出。我可以用更大的时间戳更新它,它会更新:
> update test SET dt_time = '2017-12-23 15:20:12' WHERE imei = '98838377272'
IF dt_time < '2017-12-23 16:21:12';
[applied]
-----------
True
这有几个问题:
如果条目尚不存在,它将不起作用 - 在这种情况下,您可以尝试在尝试更新之前使用 INSERT ... IF NOT EXISTS
,或者使用 [= 预填充数据库18=] 数字
轻量级事务会给集群带来开销,因为数据应该在写入之前读取,这可能会给服务器带来很大的负载,并降低吞吐量。
实际上你不能 "update" 集群键,因为它是主键的一部分,所以你应该删除 dt_time 上的集群键。
然后您可以使用轻量级事务更新行,该事务检查新值是否在现有值之后。
cqlsh:test> CREATE TABLE test1(imei text, dt_time timestamp) PRIMARY KEY (imei);
cqlsh:test> INSERT INTO test1 (imei, dt_time) VALUES ('98838377272', '2017-12-23 16:20:12');
cqlsh:test> SELECT * FROM test1;
imei | dt_time
-------------+---------------------------------
98838377272 | 2017-12-23 08:20:12.000000+0000
(1 rows)
cqlsh:test> UPDATE test1 SET dt_time='2017-12-23 15:20:00' WHERE imei='98838377272' IF dt_time < '2017-12-23 15:20:00';
[applied] | dt_time
-----------+---------------------------------
False | 2017-12-23 08:20:12.000000+0000
cqlsh:test> UPDATE test1 SET dt_time='2017-12-23 17:20:00' WHERE imei='98838377272' IF dt_time < '2017-12-23 17:20:00';
[applied]
-----------
True
“15:20:00”的更新将 return 'false' 并告诉您当前值。
“17:20:00”的更新将 return 'true'
参考:https://docs.datastax.com/en/cql/3.3/cql/cql_using/useInsertLWT.html
您可以在插入语句中使用 TIMESTAMP 子句将数据标记为最新:
Marks inserted data (write time) with TIMESTAMP. Enter the time since epoch (January 1, 1970) in microseconds. By default, Cassandra uses the actual time of write.
从主键中删除 dt_time
以仅存储 imei
和
的一个条目
- 插入数据并指定时间戳为 2017-12-23 16.20.12
- 插入数据并指定时间戳为 2017-12-23 15.20.00
在这种情况下,select by imei
将 return 记录最近的时间戳(从点 1 开始)。
请注意,如果您的 dt_time
(将指定为时间戳)小于当前时间,则此方法有效。换句话说,select 查询将 return 具有最近时间戳但在当前时间之前的记录。如果您插入的数据的时间戳大于当前时间,您将在该时间戳到来之前看不到该数据。
我有一个 Cassandra table 喜欢 :-
create table test(imei text,dt_time timestamp, primary key(imei, dt_time)) WITH CLUSTERING ORDER BY (dt_time DESC);
Partition Key is: imei
Clustering Key is: dt_time
现在我只想为每个分区键在此 table(基于时间)中存储最近的条目。 假设我在 table 中插入条目,其中每个 imei
都有一个条目现在假设 imei 98838377272 dt_time 是 2017-12-23 16.20.12 现在对于相同的 imei 如果 dt_time 像 2017-12-23 15.20.00 那么这个条目不应该插入那个Cassandra table.
但是如果时间到了 2017-12-23 17.20.00 那么它应该被插入并且前一行应该被替换为这个 dt_time.
首先,要仅存储 table 中的最后一个条目,您需要从主键中删除 dt_time
- 否则您会为每个时间戳将条目插入到数据库中。
Cassandra 支持所谓的 lightweight transactions 允许在插入数据之前检查数据。
所以如果你只想在 dt_time
小于新时间时更新条目,那么你可以使用类似的东西:
首先插入数据:
> insert into test(imei, dt_time) values('98838377272', '2017-12-23 15:20:12');
尝试同时更新数据,否则可以更小
> update test SET dt_time = '2017-12-23 15:20:12' WHERE imei = '98838377272'
IF dt_time < '2017-12-23 15:20:12';
[applied] | dt_time
-----------+---------------------------------
False | 2017-12-23 15:20:12.000000+0000
这将失败,因为从 applied
等于 False
可以看出。我可以用更大的时间戳更新它,它会更新:
> update test SET dt_time = '2017-12-23 15:20:12' WHERE imei = '98838377272'
IF dt_time < '2017-12-23 16:21:12';
[applied]
-----------
True
这有几个问题:
如果条目尚不存在,它将不起作用 - 在这种情况下,您可以尝试在尝试更新之前使用
INSERT ... IF NOT EXISTS
,或者使用 [= 预填充数据库18=] 数字轻量级事务会给集群带来开销,因为数据应该在写入之前读取,这可能会给服务器带来很大的负载,并降低吞吐量。
实际上你不能 "update" 集群键,因为它是主键的一部分,所以你应该删除 dt_time 上的集群键。
然后您可以使用轻量级事务更新行,该事务检查新值是否在现有值之后。
cqlsh:test> CREATE TABLE test1(imei text, dt_time timestamp) PRIMARY KEY (imei);
cqlsh:test> INSERT INTO test1 (imei, dt_time) VALUES ('98838377272', '2017-12-23 16:20:12');
cqlsh:test> SELECT * FROM test1;
imei | dt_time
-------------+---------------------------------
98838377272 | 2017-12-23 08:20:12.000000+0000
(1 rows)
cqlsh:test> UPDATE test1 SET dt_time='2017-12-23 15:20:00' WHERE imei='98838377272' IF dt_time < '2017-12-23 15:20:00';
[applied] | dt_time
-----------+---------------------------------
False | 2017-12-23 08:20:12.000000+0000
cqlsh:test> UPDATE test1 SET dt_time='2017-12-23 17:20:00' WHERE imei='98838377272' IF dt_time < '2017-12-23 17:20:00';
[applied]
-----------
True
“15:20:00”的更新将 return 'false' 并告诉您当前值。
“17:20:00”的更新将 return 'true'
参考:https://docs.datastax.com/en/cql/3.3/cql/cql_using/useInsertLWT.html
您可以在插入语句中使用 TIMESTAMP 子句将数据标记为最新:
Marks inserted data (write time) with TIMESTAMP. Enter the time since epoch (January 1, 1970) in microseconds. By default, Cassandra uses the actual time of write.
从主键中删除 dt_time
以仅存储 imei
和
- 插入数据并指定时间戳为 2017-12-23 16.20.12
- 插入数据并指定时间戳为 2017-12-23 15.20.00
在这种情况下,select by imei
将 return 记录最近的时间戳(从点 1 开始)。
请注意,如果您的 dt_time
(将指定为时间戳)小于当前时间,则此方法有效。换句话说,select 查询将 return 具有最近时间戳但在当前时间之前的记录。如果您插入的数据的时间戳大于当前时间,您将在该时间戳到来之前看不到该数据。