[英]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)
这是一个有效的担忧。 关于两点:
就要求“等效于以下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中不返回任何内容。
这确实成为业务逻辑问题,与数据存储无关。 为避免此问题,您应该查看业务逻辑/要求,并确定valid
往返时间。 然后,您可以调整查询,使其始终超过该时间。 例如:如果路线仅有效两至三周,则一次查询一个月就足够了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.