Cassandra cqlsh-如何显示时间戳列的微秒/毫秒?
我正在插入一个带有时间戳列的Cassandra表。我得到的数据精度为微秒,因此时间数据字符串如下所示:Cassandra cqlsh-如何显示时间戳列的微秒/毫秒?,cassandra,timestamp,cql,cqlsh,Cassandra,Timestamp,Cql,Cqlsh,我正在插入一个带有时间戳列的Cassandra表。我得到的数据精度为微秒,因此时间数据字符串如下所示: aploetz@cqlsh:stackoverflow> SELECT id, type, blobAsBigint(timestampAsBlob(datetime)), data FROM data; id | type | blobAsBigint(timestampAsBlob(datetime)) | data --------+---------
aploetz@cqlsh:stackoverflow> SELECT id, type, blobAsBigint(timestampAsBlob(datetime)),
data FROM data;
id | type | blobAsBigint(timestampAsBlob(datetime)) | data
--------+--------------+-----------------------------------------+-------------------------------
B26354 | Blade Runner | 1424109603234 | Deckard- Filed and monitored.
(1 rows)
2015-02-16T18:00:03.234+00:00
然而,在cqlsh中,当我运行select查询时,微秒级的数据没有显示,我只能看到低至秒级的时间。234微秒数据未显示
我想我有两个问题:
1) Cassandra是否使用时间戳数据类型捕获微秒?我猜是的
2) 我怎样才能用cqlsh来验证呢
表定义:
create table data (
datetime timestamp,
id text,
type text,
data text,
primary key (id, type, datetime)
)
with compaction = {'class' : 'DateTieredCompactionStrategy'};
使用Java PreparedStation运行的插入查询:
insert into data (datetime, id, type, data) values(?, ?, ?, ?);
Select查询只是:
select * from data;
为了回答你们的问题,我在这个问题上做了一些挖掘
aploetz@cqlsh:stackoverflow> INSERT INTO data (datetime, id, type, data)
VALUES ('2015-02-16T18:00:03.234+00:00','B26354','Blade Runner','Deckard- Filed and monitored.');
aploetz@cqlsh:stackoverflow> SELECT * FROM data
WHERE id='B26354' AND type='Blade Runner' AND datetime='2015-02-16 12:00:03-0600';
id | type | datetime | data
----+------+----------+------
(0 rows)
但当我在指定毫秒的同时查询相同的id
和类型
值时:
aploetz@cqlsh:stackoverflow> SELECT * FROM data
WHERE id='B26354' AND type='Blade Runner' AND datetime='2015-02-16 12:00:03.234-0600';
id | type | datetime | data
--------+--------------+--------------------------+-------------------------------
B26354 | Blade Runner | 2015-02-16 12:00:03-0600 | Deckard- Filed and monitored.
(1 rows)
aploetz@cqlsh:stackoverflow> INSERT INTO data (id, type, datetime, data)
VALUES ('B25881','Blade Runner','2015-02-16T18:00:03+00:00','Holden- Fine as long as nobody unplugs him.');
aploetz@cqlsh:stackoverflow> SELECT id, type, blobAsBigint(timestampAsBlob(datetime)),
... data FROM data;
id | type | blobAsBigint(timestampAsBlob(datetime)) | data
--------+--------------+-----------------------------------------+---------------------------------------------
B25881 | Blade Runner | 1424109603000 | Holden- Fine as long as nobody unplugs him.
B26354 | Blade Runner | 1424109603234 | Deckard- Filed and monitored.
(2 rows)
所以毫秒肯定在那里。为此问题()创建了一个JIRA票证,但它被解决为“无法修复”
timestasBlob()
函数嵌套在blobAsBigint()
中,如下所示:
aploetz@cqlsh:stackoverflow> SELECT id, type, blobAsBigint(timestampAsBlob(datetime)),
data FROM data;
id | type | blobAsBigint(timestampAsBlob(datetime)) | data
--------+--------------+-----------------------------------------+-------------------------------
B26354 | Blade Runner | 1424109603234 | Deckard- Filed and monitored.
(1 rows)
虽然不是最优的,但在这里您可以清楚地看到最末端的毫秒值“234”。如果我为相同的时间戳添加一行,但没有毫秒,这一点会变得更加明显:
aploetz@cqlsh:stackoverflow> SELECT * FROM data
WHERE id='B26354' AND type='Blade Runner' AND datetime='2015-02-16 12:00:03.234-0600';
id | type | datetime | data
--------+--------------+--------------------------+-------------------------------
B26354 | Blade Runner | 2015-02-16 12:00:03-0600 | Deckard- Filed and monitored.
(1 rows)
aploetz@cqlsh:stackoverflow> INSERT INTO data (id, type, datetime, data)
VALUES ('B25881','Blade Runner','2015-02-16T18:00:03+00:00','Holden- Fine as long as nobody unplugs him.');
aploetz@cqlsh:stackoverflow> SELECT id, type, blobAsBigint(timestampAsBlob(datetime)),
... data FROM data;
id | type | blobAsBigint(timestampAsBlob(datetime)) | data
--------+--------------+-----------------------------------------+---------------------------------------------
B25881 | Blade Runner | 1424109603000 | Holden- Fine as long as nobody unplugs him.
B26354 | Blade Runner | 1424109603234 | Deckard- Filed and monitored.
(2 rows)
您可以使用python的“strftime”语法在.cassandra/cqlshrc
文件中创建一组datetime对象
不幸的是,对于较旧的python版本,
%f
指令表示微秒(似乎没有毫秒的指令),这意味着您必须回到blobAsBigint(timestasAsblob(date))
解决方案。不可能显示微秒(百万分之一秒)使用Cassandra数据类型“timestamp”,因为该数据类型可用的最大精度为毫秒(千分之一秒)
时间戳类型的值编码为64位有符号整数
表示自标准基准时间起的毫秒数
被称为大纪元
我认为“微秒”(例如03.234567)的意思是“毫秒”(例如03.234)
这里的问题是一个cqlsh
错误,在处理时间戳时无法支持小数秒
因此,当毫秒值保留在实际的持久层(cassandra)中时,shell(cqlsh)无法显示它们
即使将.cqlshrc
中的time\u格式更改为显示带有%f
指令的小数秒(例如%Y-%m-%d%H:%m:%S.%f%z
),这也是正确的。在此配置中,cqlsh将为我们的3.234值呈现3.000000
,因为问题在于cqlsh如何在不加载部分秒的情况下加载datetime对象
话虽如此,该问题已于年修复,并于年发布。一些相关代码:
cqlsh> CREATE KEYSPACE udf
WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 3};
cqlsh> USE udf;
cqlsh:udf> CREATE OR REPLACE FUNCTION udf.timeuuid_as_us ( t timeuuid )
RETURNS NULL ON NULL INPUT
RETURNS bigint LANGUAGE JAVA AS '
long msb = t.getMostSignificantBits();
return
( ((msb >> 32) & 0x00000000FFFFFFFFL)
| ((msb & 0x00000000FFFF0000L) << 16)
| ((msb & 0x0000000000000FFFL) << 48)
) / 10
- 12219292800000000L;
';
cqlsh:udf> SELECT
toUnixTimestamp(now()) AS now_ms
, udf.timeuuid_as_us(now()) AS now_us
FROM system.local;
now_ms | now_us
---------------+------------------
1525995892841 | 1525995892841000
cqlsh>创建键空间udf
使用replication={'class':'SimpleStrategy','replication\u factor':3};
cqlsh>使用udf;
cqlsh:udf>创建或替换函数udf.timeuuid\u as\u us(t timeuuid)
在NULL输入时返回NULL
返回bigint语言JAVA作为'
long msb=t.getMostSignificantBits();
返回
((msb>>32)和0x00000000ffffffffffffl)
|((msb&0x00000000FF0000L)你能用你的表格定义、INSERT
和SELECT
查询来编辑你的帖子吗?在我看到这些信息之前我不知道,但你的问题可能与此有关:只是按照你的要求更新了我的帖子。如果不够清楚,请告诉我。谢谢。谢谢你的详细回复,这非常有帮助。我可以用用你的解决方案。我想在实践中,我会以编程的方式拿回时间戳,只要它能正常工作就可以了。在这种情况下,是否有偏好将时间戳存储为bigint格式?这将取决于你的用例。如果你关心时间精度,那么将其存储为timeuuid就是一种方式但如果毫秒更多的是一个有效载荷字段或结果排序,那么我可以看到一个bigint为您工作。是的,对我来说,排序确实很重要。我会考虑一下。谢谢!@不会有问题,很高兴我能帮上忙!有没有办法通过在节点cassandra cql中使用类似TimestasAsBlob的函数来获取时间戳?