【问题标题】:How to design NoSQL Database to select data order by timestamp如何设计 NoSQL 数据库按时间戳选择数据顺序
【发布时间】:2019-04-29 15:06:29
【问题描述】:

总结一下,我想创建一个 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);

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

【问题讨论】:

  • 您希望有多少 fireman 行?
  • @ChrisLohfink 这是一个尽可能多的 POC,目前我派出了 100 万消防员

标签: cassandra nosql cassandra-3.0


【解决方案1】:

由于 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!

阅读一下,看看是否有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-08
    • 1970-01-01
    • 1970-01-01
    • 2020-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多