我在Cassandra有一个下表结构:
CREATE TABLE ssession (
sessionid text PRIMARY KEY,
session_start_time timestamp,
updated_time timestamp
);
session_start_time
是特定会话变为活动状态的时间,update_time
是用户进行某些活动的时间。这里,sessionid
和session_start_time
将被插入一次并且updated_time
会在用户处于活动状态时不断更新。
I want to include only sessionid as the primary key
。
正常更新声明将是:
UPDATE ssession SET session_start_time = '2015-07-31 10:43:13+0530',
updated_time = '2015-07-31 10:43:13+0530' WHERE sessionid = '22_865624098';
在这里,我第一次插入相同的session_start_time
和updated_time
。但是从下次开始我只需要更新updated_time
。
我需要一个查询才能这样做。因为,我将持续获取数据(使用storm来处理数据)。
有没有办法实现这个目标?
答案 0 :(得分:2)
当您插入或更新数据(cassandra中的更新和插入相同)时,您不需要提供所有列。如果您只想更新updated_time,则查询应为:
UPDATE ssession SET updated_time = '2015-07-31 10:43:13+0530' WHERE sessionid = '22_865624098';
但听起来你想确保session_start_time是第一次创建sessionid时设置的,而且只是第一次,对吗?
您可以利用lightweight transactions和if not exists
使用session_start_time创建数据。如果已存在具有该session_id的行,则不会应用插入:
INSERT INTO ssession (sessionid, session_start_time, updated_time) values ('22_865624098', '2015-07-31 10:43:13+0530', '2015-07-31 10:43:13+0530') if not exists;
如果应用了插入内容,Cassandra会在这种情况下返回一列[applied]
,其值为true
或false
。如果返回false
,则可以只运行仅更新updated_time
的更新查询:
UPDATE ssession set updated_time = '2015-07-31 10:43:14+0531' where sessionid = '22_865624098';
请注意,轻量级事务会引入一些性能成本,这在上面链接的文章中有详细介绍。它使用' SERIAL'一致性水平,这是一个多阶段的QUORUM。这也是一个“随后写入”。模式,这不会像盲目写入数据一样快。您应该测试此解决方案的性能,看看它是否适合您。