如何在 Cassandra 中删除带有计数器列的记录后重置记录?
How to reset record with counter column after delete it in Cassandra?
我在使用 com.datastax.driver.core 包时创建了一个 table 和计数器列 ,在 class:
中创建了一个函数
public void doStartingJob(){
session.execute("CREATE KEYSPACE myks WITH replication "
+ "= {'class':'SimpleStrategy', 'replication_factor':1};");
session.execute("CREATE TABLE myks.clients_count(ip_address text PRIMARY KEY,"
+ "request_count counter);");
}
之后我从 CQLSH 中删除了 table 条目,例如:
jay@jayesh-380:~$ cqlsh
Connected to Test Cluster at 127.0.0.1:9042.
[cqlsh 5.0.1 | Cassandra 3.9 | CQL spec 3.4.2 | Native protocol v4]
Use HELP for help.
cqlsh:myks> DELETE FROM clients_count WHERE ip_address='127.0.0.1';
然后插入具有相同主键的行我使用了以下语句(通过cqlsh):
UPDATE myks.clients_count SET request_count = 1 WHERE ip_address ='127.0.0.1';
并且不允许因为:
InvalidRequest: Error from server: code=2200 [Invalid query] message="Cannot set the value of counter column request_count (counters can only be incremented/decremented, not set)"
但是,我希望记录的 counter 列的值应该设置为 1,并且具有相同的主键。 (功能需求)
如何做同样的事情??
计数器的用法有点奇怪,但你会习惯的。然而,最主要的是计数器不能 重复使用 。删除特定主键的计数器值后,该计数器将永远丢失 。这是设计使然,我认为不会改变。
回到你的问题,你的第一个问题是初始DELETE
。不要。
其次,如果主键的计数器值不存在,C* 默认将视为零。按照 the documentation,第一次在计数器中加载数据你必须发出:
UPDATE mysecurity.clients_count SET request_count = request_count + 1 WHERE ip_address ='127.0.0.1';
而 SELECT
将 return 正确答案:1
再次提醒,谨防删除!不!如果您这样做,任何后续查询:
UPDATE mysecurity.clients_count SET request_count = request_count + 1 WHERE ip_address ='127.0.0.1';
将 NOT 失败,但计数器将 NOT 更新。
另一件需要注意的事情是 C* 不支持原子 read 和 update(或 update 和 read 计数器列。也就是说,您无法发出更新并在同一查询中获取计数器的新(或旧)值。您需要执行两个不同的查询,一个使用 SELECT
,一个使用 UPDATE
,但在多客户端环境中,您获得的 SELECT
值无法反映 UPDATE
期间的计数器值。
如果你低估了这一点,你的应用肯定会失败。
我在使用 com.datastax.driver.core 包时创建了一个 table 和计数器列 ,在 class:
中创建了一个函数public void doStartingJob(){
session.execute("CREATE KEYSPACE myks WITH replication "
+ "= {'class':'SimpleStrategy', 'replication_factor':1};");
session.execute("CREATE TABLE myks.clients_count(ip_address text PRIMARY KEY,"
+ "request_count counter);");
}
之后我从 CQLSH 中删除了 table 条目,例如:
jay@jayesh-380:~$ cqlsh
Connected to Test Cluster at 127.0.0.1:9042.
[cqlsh 5.0.1 | Cassandra 3.9 | CQL spec 3.4.2 | Native protocol v4]
Use HELP for help.
cqlsh:myks> DELETE FROM clients_count WHERE ip_address='127.0.0.1';
然后插入具有相同主键的行我使用了以下语句(通过cqlsh):
UPDATE myks.clients_count SET request_count = 1 WHERE ip_address ='127.0.0.1';
并且不允许因为:
InvalidRequest: Error from server: code=2200 [Invalid query] message="Cannot set the value of counter column request_count (counters can only be incremented/decremented, not set)"
但是,我希望记录的 counter 列的值应该设置为 1,并且具有相同的主键。 (功能需求)
如何做同样的事情??
计数器的用法有点奇怪,但你会习惯的。然而,最主要的是计数器不能 重复使用 。删除特定主键的计数器值后,该计数器将永远丢失 。这是设计使然,我认为不会改变。
回到你的问题,你的第一个问题是初始DELETE
。不要。
其次,如果主键的计数器值不存在,C* 默认将视为零。按照 the documentation,第一次在计数器中加载数据你必须发出:
UPDATE mysecurity.clients_count SET request_count = request_count + 1 WHERE ip_address ='127.0.0.1';
而 SELECT
将 return 正确答案:1
再次提醒,谨防删除!不!如果您这样做,任何后续查询:
UPDATE mysecurity.clients_count SET request_count = request_count + 1 WHERE ip_address ='127.0.0.1';
将 NOT 失败,但计数器将 NOT 更新。
另一件需要注意的事情是 C* 不支持原子 read 和 update(或 update 和 read 计数器列。也就是说,您无法发出更新并在同一查询中获取计数器的新(或旧)值。您需要执行两个不同的查询,一个使用 SELECT
,一个使用 UPDATE
,但在多客户端环境中,您获得的 SELECT
值无法反映 UPDATE
期间的计数器值。
如果你低估了这一点,你的应用肯定会失败。