用于过滤器和范围查询的 Cassandra 建模

Cassandra Modeling for filter and range queries

我正在尝试为用户数据库建模。这些用户有各种生命统计数据:年龄、性别、身高、体重、头发颜色等

我希望能够编写如下查询:

获取身高 5'1" 到 6'0" 且体重超过 100 磅的所有用户

获取所有 6'0" 年龄在 31-37 岁之间并且有黑头发的用户

如何为数据建模才能进行这些查询?让我们假设这个数据库将拥有数十亿用户。我想不出一种不需要我发出许多请求或将数据聚集在非常少的节点上的方法。

编辑:

再补充一点背景知识,我们假设这个思维问题是建立一个约会网站。该网站应允许用户根据上述标准(年龄、性别、身高、体重、头发等)过滤人员。这些过滤器是可选的,您可以拥有任意数量的过滤器。这个网站有 20 亿用户。仅通过数据建模就可以实现吗?

如果我理解正确 如果我有 20 亿用户,并且我创建了第一个答案中提到的两个 table(假设性别选项为男性和女性,头发颜色为金发、棕色、红色),我将首先创建table,如果每个人都是金发,则在一个节点上最多放置 20 亿条记录。最佳情况,三个节点上有 2/3 十亿条记录。在第二种情况下,我将在最好的情况和相同的最坏情况下在每个节点上放置 2/5 十亿条记录。我错了吗?分区键不应该比这更独特吗?

因此,如果您尝试在 Cassandra 中对数据建模,那么一般规则是您需要为每个查询创建一个 table。您可以根据什么来过滤查询也有很大的限制。如果你想了解一些限制,我建议你看看这个 post:

http://www.datastax.com/dev/blog/a-deep-look-to-the-cql-where-clause

或者我在这里的长答案:

以上所有内容仅适用于 运行 预先知道的固定查询。相反,如果您希望对您的数据执行某种分析(听起来您可能是),那么我会考虑将 Spark 与 Cassandra 结合使用。这将为您提供一个快速的工具来对您的数据进行内存处理。如果您考虑使用 Datastax(社区或企业),那么 Spark 也有一个连接器,可以轻松地从 Cassandra 读取和写入数据。

编辑了附加信息 根据查询 "get all users 5'1" 至 6'0" 身高超过 100 磅的红头发",您需要构建一个 table 并具有以下内容:

CREATE TABLE user_by_haircolor_weight_height ( haircolor text, weight float, height_in int, user varchar, PRIMARY KEY ((haircolor), weight, height_in) );

然后您可以通过以下方式查询: SELECT * from user_by_haircolor_weight_height where haircolor='red' and weight>100 and height_in>61 and height_in<73;

对于查询"get all users who are men who are 6'0" are ages 31-37 and have black hair"你需要建立一个类似的table PRIMARY KEY ((haircolor, sex), height_in, age)

最后,如果您要做的是对存储在 cassandra table 比我建议你看看使用 Spark。如果您需要更实时的东西来处理临时查询,您可以考虑使用 Solr 在 table.

上执行 Lucene 支持的搜索

我的建议是:

1) 保持 main table 具有适当的分区键,以便数百万条记录分布在集群中,不要在这里使用任何会跨越 2gb 等行键限制的集群列,

2) 根据查询模式,您最好尽可能多地创建额外的 tables(如索引)以将倒排索引数据保留在其中。因为写很便宜。

3) 使用多个查询来获取您需要的内容。

4) 最后一个选项是,使用 DSE solr 搜索功能。

再次重申对话的结尾:

"Your understanding is correct and you are correct in stating that partition keys should be more unique than that. Each partition had a maximum size of 2GB but a practical limit is lower. In practice you would want your data partitioned into far smaller chunks that the table above. Given the ad-hoc nature of your queries in your example I do not think you would be able to practically do this by data modelling alone. I would suggest looking at using a Solr index on a table. This would allow you a robust search capability. If you use Datastax you are even able to query this via CQL"

Cassandra 单独 不适合这种 对非常大的数据集进行复杂过滤。