繁体   English   中英

Cassandra中的多列相等性限制

[英]Multi Column equality Restrictions in Cassandra

请考虑下表:

CREATE TABLE routes (
start text,
end text,
validFrom timestamp,
validTo timestamp,
PRIMARY KEY (start, end, validFrom, validTo)
);

如何编写一个cql查询以查找从日期A到日期B并在日期x和日期y之间有效的所有路由。 本质上等效于以下SQL语句:

SELECT * from routes where start = 'A' and end = 'B' and validFrom <= x and validTo >= y.

我一直在阅读Cassandra文档 ,我的印象是,使用给定的表无法进行此类查询。 如果是这种情况,那么如何对数据建模才能启用这种查询。

SELECT * from routes where start = 'A' and end = 'B' and validFrom <= x and validTo >= y

由于Cassandra在磁盘上存储数据的方式,因此无法为这样的查询提取连续的行范围。 因此,您需要做的是稍微调整模型。

CREATE TABLE routes (
  start text,
  end text,
  valid timestamp,
  toFrom text,
  name text,
  PRIMARY KEY (start, end, valid, toFrom)
);

通过将valid时间到/从valid时间合并到单个列中,现在可以在其上执行范围查询,检查起点和终点。 每行将需要存储两次。 一次使用“有效至”时间,一次使用“有效自”时间。 toFrom列有助于对此进行区分。

现在,我可以运行以下查询:

> SELECT * FROM routes 
    WHERE start='A' AND end='B' 
    AND valid>='2016-02-01'AND valid<='2016-02-20';

 start | end | valid                    | tofrom | name
-------+-----+--------------------------+--------+---------
     A |   B | 2016-02-01 06:00:00+0000 |      F | combo 1
     A |   B | 2016-02-14 06:00:00+0000 |      T | combo 1
     A |   B | 2016-02-15 06:00:00+0000 |      F | combo 2

(3 rows)

只是想一想,但是使用复合分区键(例如PRIMARY KEY ((start, end), valid, toFrom) )可能会更好PRIMARY KEY ((start, end), valid, toFrom)实现更好的数据分发。 尽管这实际上取决于您的查询模式...。因此,如果您需要查询以“ A”开头的所有行,则此方法将无效(例如)。

编辑20160221

我接受了您的回答,但现在我想了一下,我认为这不会起作用。 例如,我认为查询:SELECT * FROM route where where start ='A'and end ='B'AND valid> ='2016-02-01'AND valid <='2016-02-13'; 即使“组合1”路线有效,也不会产生任何结果。

实际上,这确实有效:

> SELECT * FROM routes 
    WHERE start='A' AND end='B' 
    AND valid>='2016-02-01'AND valid<='2016-02-13';

 start | end | valid                    | tofrom | name
-------+-----+--------------------------+--------+---------
     A |   B | 2016-02-01 06:00:00+0000 |      F | combo 1

(1 rows)

话虽如此,我了解您的意思。 如果您应该选择一个有效的往返之间的时间段(不包括在内),它将产生零行...如下所示:

    > SELECT * FROM routes 
    WHERE start='A' AND end='B' 
    AND valid>='2016-02-02'AND valid<='2016-02-13';

 start | end | valid                    | tofrom | name
-------+-----+--------------------------+--------+---------

(0 rows)

这是一个有效的担忧。 关于两点:

  1. 就要求“等效于以下SQL语句”的问题而言 ,您在关系数据库中仍然会遇到相同的问题(在我的MariaDB测试实例上尝试过)。 实际上,情况会更糟,因为对valid>='2016-02-01'AND valid<='2016-02-13'的查询和valid>='2016-02-01'AND valid<='2016-02-13'的查询在Cassandra中返回了一行,但是validFrom>='2016-02-01' AND validTo<='2016-02-13'在MariaDB中不返回任何内容。

  2. 这确实成为业务逻辑问题,与数据存储无关。 为避免此问题,您应该查看业务逻辑/要求,并确定valid往返时间。 然后,您可以调整查询,使其始终超过该时间。 例如:如果路线仅有效两至三周,则一次查询一个月就足够了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM