Cassandra 数据库模式和选择 IN 问题

Posted

技术标签:

【中文标题】Cassandra 数据库模式和选择 IN 问题【英文标题】:Cassandra database schema and select IN issue 【发布时间】:2014-08-31 23:38:04 【问题描述】:

我有以下数据库架构

CREATE TABLE sensor_info_table 
(
  asset_id text,
  event_time timestamp,
  "timestamp" timeuuid,
  sensor_reading map<text, text>,
  sensor_serial_number text,
  sensor_type int,
  PRIMARY KEY ((asset_id), event_time, "timestamp")
);

CREATE INDEX event_time_index ON sensor_info_table (event_time);

CREATE INDEX timestamp_index ON sensor_info_table ("timestamp");

现在我可以将数据插入到此表中,但是我无法执行以下查询,我想选择具有特定 timeuuid 值的项目。它给了我以下错误。

SELECT * from mydb.sensor_info_table where timestamp IN ( bfdfa614-3166-11e4-a61d-b888e30f5d17 , bf4521ac-3166-11e4-87a3-b888e30f5d17) ;

错误请求:PRIMARY KEY 列“timestamp”不能被限制(前面的列“event_time”要么不受限制,要么受非 EQ 关系限制)

我必须做些什么才能完成这项工作?以下是软件版本信息。

显示版本;

[cqlsh 4.1.1 | Cassandra 2.0.9 | CQL spec 3.1.1 | Thrift protocol 19.39.0]

我真的不明白“event_time”列之前的错误消息是不受限制还是不受EQ关系的限制?

-苏博德

【问题讨论】:

执行此更改并检查 PRIMARY KEY ((asset_id, event_time), "timestamp") 【参考方案1】:

你不能让它像这样工作。 IN 不支持查找索引列上的谓词。 因此,您将无法在“时间戳”列上使用 IN。如果您还提供了asset_id 和event_time,则可以使用IN——这就是cqlsh 通过消息告诉您的内容

错误请求:无法限制 PRIMARY KEY 列“时间戳” (前面的列“event_time”要么不受限制,要么受非 EQ 关系)

您的问题的解决方案是非规范化。创建索引时,Cassandra 将为您创建并处理一个将索引作为分区键的新表——因此 Cassandra 已经对您的数据进行了非规范化和复制。删除索引并创建一个新表

CREATE TABLE sensor_info_table_by_timestamp
(
  asset_id text,
  event_time timestamp,
  "timestamp" timeuuid,
  sensor_reading map<text, text>,
  sensor_serial_number text,
  sensor_type int,
  PRIMARY KEY ("timestamp", asset_id, event_time )
);

现在,您可以随时写入放入两个表中的数据(您可以使用批处理)。 您的查询将是

SELECT * from mydb.sensor_info_table_by_timestamp where timestamp IN ( bfdfa614-3166-11e4-a61d-b888e30f5d17 , bf4521ac-3166-11e4-87a3-b888e30f5d17) ;

我看到您还在 event_time 上创建了一个查找索引——如果您必须使用 IN 谓词执行查询,您将不得不创建第三个表...

HTH, 卡罗

【讨论】:

【参考方案2】:

[我已经在 cassandra 用户邮件列表上发布了这个查询,根据建议我最终创建了两个表来处理这个要求]

CREATE TABLE sensor_asset (
  asset_id text,
  event_time timestamp,
  tuuid timeuuid,
  sensor_reading map<text, text>,
  sensor_serial_number text,
  sensor_type int,
  PRIMARY KEY ((asset_id), event_time)
);

CREATE TABLE sensor_tuuid (
  asset_id text,
  event_time timestamp,
  tuuid timeuuid,
  sensor_reading map<text, text>,
  sensor_serial_number text,
  sensor_type int,
  PRIMARY KEY (tuuid)
);

【讨论】:

以上是关于Cassandra 数据库模式和选择 IN 问题的主要内容,如果未能解决你的问题,请参考以下文章

Paxos 和 Cassandra 中的 W+R>=N 有啥区别?

为啥 Cassandra 不允许通过 IN 限制查询集群键?

带有 Spring Data 和 Cassandra @Query 的 IN 子句

在 CassandraTable 中设置分区数

在 cassandra 中导入和导出模式

cassandra中的分区计数