cassandra中的时间序列建模(包含开始和结束日期)

Avi*_*tta 3 cql cassandra cql3 datastax cassandra-2.1

我正在进行时间序列数据建模,其中我有事件的开始日期和结束日期.我需要查询该数据模型,如下所示:

Select * from tablename where startdate>'2012-08-09' and enddate<'2012-09-09'
Run Code Online (Sandbox Code Playgroud)

我在cql where子句中提到了以下链接,但我无法实现这一点.有办法吗?我也可以改变数据模型或任何cql调整.我正在使用Cassandra 2.1.

Aar*_*ron 5

我不得不在以前的一个职位上解决类似的问题.这是你可以实现这一目标的一种方式......

我需要对该数据模型进行查询,如下所示:Select * from tablename where startdate>'2012-08-09' and enddate<'2012-09-09'.

有两个建模问题阻止此查询工作.首先,要运行范围查询,首先需要使用分区键限制查询.对于时间序列数据,最好的想法是创建一个称为时间桶的东西.对于此示例,我将按月对数据进行分区,并调用分区键monthbucket.

另一个问题是,您只能对单个列/键值运行范围查询.当您想要同时查询开始日期和结束日期时,这会出现问题.一种解决方案是将表中的每一行存储两次,并创建一个额外的聚类键来保存行是开始行还是结束行的值.我会打电话给这个专栏beginend.

鉴于这些说明,我将创建一个如下所示的表:

CREATE TABLE events (
  monthBucket TEXT,
  eventDate TIMESTAMP,
  beginEnd TEXT,
  eventid UUID,
  eventName TEXT,
  PRIMARY KEY (monthBucket, eventDate, beginEnd, eventid))
WITH CLUSTERING ORDER BY (eventDate DESC, beginEnd ASC, eventid ASC);
Run Code Online (Sandbox Code Playgroud)
  • 对于大多数时间序列实现,您倾向于更关心最新的数据.为此,我正在eventDate以DESCending顺序聚集.
  • 此外,由于您可以同时启动多个事件,因此还应添加其他群集密钥以确保唯一性(eventid在本例中).

在插入一些行之后,让我们按照2015年9月的分区键进行查询:

aploetz@cqlsh:stackoverflow> SELECT * FROM events WHERE monthbucket='201509';

 monthbucket | eventdate                | beginend | eventid                              | eventname
-------------+--------------------------+----------+--------------------------------------+------------------------
      201509 | 2015-09-25 23:59:59+0000 |        E | a223ad16-2afd-4213-bee3-08a2c4dd63e6 |             Hobbit Day
      201509 | 2015-09-25 00:00:00+0000 |        B | a223ad16-2afd-4213-bee3-08a2c4dd63e6 |             Hobbit Day
      201509 | 2015-09-24 23:59:59+0000 |        E | 9cd6a265-6c60-4537-9ea9-b57e7c152db9 |       Cassandra Summit
      201509 | 2015-09-22 00:00:00+0000 |        B | 9cd6a265-6c60-4537-9ea9-b57e7c152db9 |       Cassandra Summit
      201509 | 2015-09-19 23:59:59+0000 |        E | b9fe9668-cef2-464e-beb4-d4f985ef9c47 | Talk Like a Pirate Day
      201509 | 2015-09-19 00:00:00+0000 |        B | b9fe9668-cef2-464e-beb4-d4f985ef9c47 | Talk Like a Pirate Day

(6 rows)
Run Code Online (Sandbox Code Playgroud)

与您的示例类似,假设我想在9月18日到9月24日之间查询事件:

aploetz@cqlsh:stackoverflow> SELECT * FROM events WHERE monthbucket='201509' AND eventdate > '2015-09-18' AND eventdate < '2015-09-24';

 monthbucket | eventdate                | beginend | eventid                              | eventname
-------------+--------------------------+----------+--------------------------------------+------------------------
      201509 | 2015-09-22 00:00:00+0000 |        B | 9cd6a265-6c60-4537-9ea9-b57e7c152db9 |       Cassandra Summit
      201509 | 2015-09-19 23:59:59+0000 |        E | b9fe9668-cef2-464e-beb4-d4f985ef9c47 | Talk Like a Pirate Day
      201509 | 2015-09-19 00:00:00+0000 |        B | b9fe9668-cef2-464e-beb4-d4f985ef9c47 | Talk Like a Pirate Day

(3 rows)
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,我应该得到三行:"像海盗日一样谈话"的开始和结束行以及2015年卡桑德拉峰会的开始行.

与所有数据建模方法一样,需要进行权衡.在这种情况下,为了在两个日期查询模型,权衡是你必须复制你的行.当然,为了能够进行范围查询,您必须决定monthbucket提供相关数据和所需查询灵活性的良好分区键().无论如何,试一试,看看你是否可以使它适用于你的用例.

编辑以回答问题:

  1. 如果我想查找2015年11月25日至2016年11月25日期间的所有活动.怎么可能呢?

这就是您需要为应用程序找出最佳时间段的地方.考虑一下您最常见的查询,并对其进行建模.现在您不希望在单行(存储桶)中存储太多,因为这会导致数据分发中断.因此,尝试在查询灵活性和数据分布之间找到一个愉快的媒介.

在这种特殊情况下,monthBucket您必须为每个月执行查询.我设计此解决方案的应用程序从未同时查看过一整年的事件.如果这是一个你需要支持的查询模式,那么你需要让你的时间更大一些.

  1. 有没有办法只从结果集中删除这个重复的行?

不.需要在应用程序级别处理/忽略重复项.Cassandra CQL确实有一个DISTINCT关键字,但它只在分区键上起作用.

  1. 这种类型的合并可以在Cassandra级别完成吗?

不,Cassandra没有办法将桌子连在一起.应用程序端连接是可能的,但是表现不佳并且在技术上是反模式.

处理应用程序端的数据(无论是加入还是过滤)通常不是一个好主意.但关键是适度.如果您查询20个事件并且必须忽略其中某些事件的欺骗,那么这不是太大的交易.但查询20,000,000个事件并在该卷上应用应用程序端流程根本无法很好地扩展.同样,您需要查看可用选项,并确定适用于您的应用程序的选项.