对Cassandra来说很新 - 我的数据看起来像这样:
<geohash text, category int, payload text>
我要运行的仅查询是:
SELECT category, payload FROM table WHERE geohash IN (list of 9 geohashes)
在这种情况下最好的架构是什么?
我知道我可以简单地将我的geohash作为主键并完成它,但是有更好的方法吗?
定义PRIMARY KEY (geohash, category, payload)
有什么好处?
答案 0 :(得分:0)
这取决于每行的数据大小(geohash文本,类别int,有效负载文本)。如果您的有效负载大小未达到数十Mb,那么您可能希望使用人工 bucketId int 将更多 geohash 值放入同一分区,因此您的查询可以在服务器上执行。架构看起来像这样 geohash text,bucketId int,category int,payload text 其中分区键是goehash和bucketId。 建议使用一个相当大的分区&lt; = 100 Mb,这样您就不必查找太多分区。有更多内容here。
如果您在(geohash, category, payload)
上有主键,则可以按升序顺序在category and payload
上对数据进行排序。
答案 1 :(得分:0)
所以基于查询,听起来你正在考虑一个如下所示的CQL模式:
CREATE TABLE geohash_data (
geohash text,
category int,
data text,
PRIMARY KEY (geohash)
);
在Cassandra中,PRIMARY KEY
中的第一个(仅在此情况下)列是分区键。分区密钥用于在集群周围分发数据。因此,当您执行SELECT ... IN ()
查询时,您基本上是在查询9个不同分区中的数据,这取决于您的群集的大小,复制因子以及用于执行查询的一致性级别,最终查询至少 9台服务器(可能还有更多)。为什么这很重要?
这两个都是糟糕的情况(正如Toan在他的回答和他提供的链接中正确指出的那样),我们尝试在Cassandra中使用数据模型,这样我们的查询就会像在很少的分区(以及复制品/服务器)上一样可能。这对你的场景意味着什么?在不知道所有细节的情况下,很难肯定地说,但是让我对你的场景做一些猜测,并举例说明我将如何解决它。
听起来你可能已经提前知道了可能的geohash
值列表(也许它们处于预定义网格的某个规则间隔的间隔)。这听起来也许你正在查询9个geohash值,因为你正在进行某种“接近”搜索,你试图在给定点周围的每个方向上获取9个地理数据的数据。
如果是这种情况,诀窍可能是在写入时将数据非规范化为优化用于读取的数据模型。例如,这样的架构:
CREATE TABLE geohash_data (
geohash text,
data_geohash text,
category int,
data text,
PRIMARY KEY (geohash, data_geohash)
);
当您INSERT
数据点时,您将计算您希望数据应显示在结果中的周围区域的地理位置。对于您计算的每个地理位置,然后INSERT
数据多次。因此,geohash
的值是您希望它显示在查询结果中的计算值,而data_geohash
的值是您要插入的数据的实际值。因此,对于给定的geohash
,您的分区中有多个(最多9个)行,表示周围地理数据的数据。
这意味着您的SELECT
查询现在不必执行IN
并点击多个分区。您只需查询WHERE geohash = ?
以查找要搜索的点。