【发布时间】:2017-02-07 18:46:57
【问题描述】:
我有一张这样的桌子:
CREATE TABLE test.products (
id uuid PRIMARY KEY,
name text,
params map<text, text>);
我在 params 字段上创建了一个条目索引,如下所示:
CREATE INDEX products_params_idx ON test.products (entries(params));
假设我在该表中有 3 个具有此类参数值的产品:
1. {'param1' : 'value1', 'param2' : 'value2'}
2. {'param1' : 'value1', 'param2' : 'othervalue'}
3. {'param3' : 'value3', 'param2' : 'value2'}
每个产品的每个参数只能有一个值,但在整个数据库中,每个参数可以有 N 个参数和 X 个值。
我可以毫无问题地进行这样的查询:
SELECT * FROM products WHERE params['param1'] = 'value1';
但主要问题是我怎样才能进行这样的查询:
SELECT * FROM products WHERE params['param1'] = 'value1' AND params['param2'] = 'value2';
现在我收到一个错误,警告我效率:
InvalidRequest: Error from server: code=2200 [Invalid query] message="Cannot execute this query as it might involve data filtering and thus may have unpredictable performance. If you want to execute this query despite the performance unpredictability, use ALLOW FILTERING"
我对 Cassandra 和 NoSQL 很陌生。我从 Datastax 课程中知道,使用 ALLOW FILTERING 是我在 Cassandra 中应该做的最后一件事。有没有一种有效的方法可以在 Cassandra 中实现我想要的?也许我应该以完全不同的方式对此进行建模?我会很高兴在这个主题上得到一些帮助。
【问题讨论】:
-
是的,您更改模型是正确的,因为您不能使用参数(地图类型的列)作为主键或作为材料视图创建表(集合类型不能是主键的一部分,也不能计数器类型。)。所以如果你想跳过“允许过滤”,你需要在查询中包含主键。
-
集合是您一次性获取的一小组数据。如果您想在更精细的级别访问元组,并且仍然能够询问“给定键的所有数据对是什么”,您应该使用这样的表:CREATE TABLE details (key TEXT, detail_key text, detail_value文本,主键(键,detail_key));这将允许 SELECT * FROM details WHERE key = ?以及 SELECT * FROM detail WHERE key = ? AND detail_key = ?.
标签: cassandra query-optimization data-modeling