我在使用com.datastax.driver.core包和类中的函数时创建了一个带有计数器列的表:
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中删除了表条目,如:
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)"
但是,我希望记录的计数器列的值应设置为1 ,并使用相同的主键。 (功能要求)
如何做同样的事情?
答案 0 :(得分:3)
计数器的使用有点奇怪,但你会习惯的。但最重要的是,计数器不能重用。删除特定主键的计数器值后,此计数器将永久丢失 。这是设计,我认为不会改变。
回到你的问题,你的第一个问题是最初的DELETE
。不。
其次,如果主键的计数器值不存在,则默认情况下C *会将处理为零。在the documentation之后,要首次在计数器中加载数据,您必须发出:
UPDATE mysecurity.clients_count SET request_count = request_count + 1 WHERE ip_address ='127.0.0.1';
SELECT
将返回正确答案:1
再次提防删除!别!如果你这样做,任何后续查询:
UPDATE mysecurity.clients_count SET request_count = request_count + 1 WHERE ip_address ='127.0.0.1';
NOT 会失败,但计数器会 NOT 更新。
需要注意的另一件事是C *不支持原子读取和更新(或更新并读取计数器列。这是你不能发布更新和在同一查询中获取计数器的新(或旧)值。您需要执行两个不同的查询,一个使用SELECT
,另一个使用UPDATE
,但是在多客户端环境中您获得的SELECT
值无法反映UPDATE
期间的计数器值。
如果你低估了这个,你的应用肯定会失败。