如何设计NoSQL数据库按时间戳选择数据顺序

问题描述 投票:4回答:1

总结一下,我想创建一个SMACK架构(Spark,Mesos,Akka,Cassandra和Kafka)。我想做一个入口点,我可以在我的数据库中返回50个最后一个元素添加。这是我的数据库:

create table fireman
(
    uuid uuid primary key,
    date text,
    heartrate int,
    id text,
    location text,
    ratecommunication int,
    temperature int,
    time timestamp
);

我试着查询一下:

SELECT * FROM scala_fireman.fireman WHERE temperature > 0 ORDER BY date LIMIT 5 ALLOW FILTERING ;

但我得到了这个错误:

ORDER BY is only supported when the partition key is restricted by an EQ or an IN.

所以我的问题是SELECT如何获得我添加的最后一个元素?

我看到我可以通过这样做来订购表:

) WITH CLUSTERING ORDER BY (time DESC);

但要做到这一点,我需要将时间更改为主键,但有些数据会同时添加,因此我无法将其设置为主键。

cassandra nosql cassandra-3.0
1个回答
3
投票

由于Cassandra需要基于查询的建模方法,我们需要专门构建一个表来处理这个查询:

SELECT * FROM scala_fireman.fireman 
WHERE temperature > 0 ORDER BY date LIMIT 5 ALLOW FILTERING;

你有没有问过uuid?如果是这样,那么我们可以构建一个新表。如果没有,您将需要更改主键才能使其正常工作。在ID列上构建单个PRIMARY KEY会严重限制您的查询灵活性(正如您所发现的那样)。

这是一个尽可能多的POC,目前我已派出100万名消防员

这将是你的第一个障碍。 Cassandra每个分区只能支持20亿个单元,而且在此之前很久就会变慢。因此,我们希望通过“时间分组”来限制每个分区的消防员事件数量。例如,我将使用month_bucket,但您应该确定这是否真的适合您的业务需求。

接下来,你想要ORDER BY日期,所以我们将它用作聚类键。实际上,由于date是一个文本字段,我们将使用time,因为我确定你不希望以ASCII-betical顺序返回结果。关于ORDER BY条款的快速教育,就是它完全是多余的。您只能按照群集密钥的预定顺序强制执行该操作。它不应该在查询中。

注意:您收到错误的原因是,排序顺序只能在数据分区中强制执行。它不能在结果集上强制执行。

另外,我看到你在temperature上做了一个开放式的范围查询。通常,这是一个坏主意(以及您在原始查询中需要ALLOW FILTERING的原因)。但在一个分区内,它应该不会太糟糕。只要那个分区不是太大。我们也将集中于此。

当然,有可能多个消防员可以在相同的温度下参与相同温度的事件,因此我们将在最后添加uuid以强制执行唯一性。您的新主键应如下所示:

    PRIMARY KEY ((month_bucket),time,temperature,uuid))

所以如果尝试这个表定义:

create table fireman_events_by_date_and_temp (
    uuid uuid,
    month_bucket int,
    date text,
    heartrate int,
    id text,
    location text,
    ratecommunication int,
    temperature int,
    time timestamp,
    PRIMARY KEY ((month_bucket),time,temperature,uuid))
    WITH CLUSTERING ORDER BY (time DESC, temperature ASC, uuid ASC);

现在,如果我加载一些数据并运行您的查询:

> SELECT time,temperature,heartrate,location
  FROM fireman_events_by_date_and_temp
  WHERE month_bucket=201904
  AND temperature > 0
  LIMIT 5
  ALLOW FILTERING;

 time                            | temperature | heartrate | location
---------------------------------+-------------+-----------+----------
 2019-04-30 13:40:03.253000+0000 |         644 |       144 |       SF
 2019-04-30 13:39:51.944000+0000 |         644 |       144 |       SF
 2019-04-30 13:39:39.859000+0000 |         644 |       144 |       SF
 2019-04-30 13:39:30.331000+0000 |         644 |       144 |       SF
 2019-04-30 13:39:15.945000+0000 |         644 |       144 |       NY

(5 rows)

通常,我不建议使用ALLOW FILTERING。但只要您查询分区键(month_bucket),所有数据仍应由同一节点提供服务。

另外,我在2015年写了关于Cassandra中结果集排序的这篇文章,并在其中演示了这些建模技术的使用。四年后它仍然非常相关(特别是对于这样的问题):

We Shall Have Order!

给它一个阅读,看看它是否有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.