我在 Cassandra 3.7 中有一个带有传感器数据的表/列族。
CREATE TABLE test.sensor_data (
house_id int,
sensor_id int,
time_bucket int,
sensor_time timestamp,
sensor_reading map<int, float>,
PRIMARY KEY ((house_id, sensor_id, time_bucket), sensor_time)
)
Run Code Online (Sandbox Code Playgroud)
现在,当我从这个表中选择时,我发现同一个主键有重复项,我认为这是不可能的。
cqlsh:test> select * from sensor_data;
house_id | sensor_id | time_bucket | sensor_time | sensor_reading
----------+-----------+-------------+---------------------------------+----------------
1 | 2 | 3 | 2016-01-02 03:04:05.000000+0000 | {1: 101}
1 | 2 | 3 | 2016-01-02 03:04:05.000000+0000 | {1: 101}
Run Code Online (Sandbox Code Playgroud)
我认为部分问题在于这些数据都是使用 java 和 Datastax java 驱动程序“实时”编写的,并且已经使用 sstableloader 与来自另一个来源的历史数据一起加载。
无论如何,这应该是不可能的。我无法将旧的 cassandra-cli 连接到这个集群,也许这会告诉我一些我无法使用 cqlsh 看到的东西。
所以,问题是:
* 无论如何,在已知情况下会发生这种情况吗?
* 我可以使用 cqlsh 读取更多原始数据吗?具体写这两行的时间。writetime() 函数不能对主键或集合进行操作,这就是我所拥有的。
谢谢。
更新:
这是我尝试过的,来自评论、答案和其他来源
* 选择使用 blobAsBigInt 为所有相同的行提供相同的大整数
* 使用 cassandra-cli 连接,启用 thrift 后,是可能的,但无法读取表格。它在 3.x 之后不受支持
* 使用 sstabledump 进行转储正在进行中,但预计还需要一两个星期;)
“sensor_time”是主键的一部分。它不在“分区键”中,而是在“聚类列”中。这就是为什么你会得到两“行”。
但是,在磁盘表中,两个“可视行”都存储在单个 Cassandra 行上。实际上,它们只是不同的列,CQL 只是假装它们是两个“可视行”。
澄清- 我有一段时间没有使用 Cassandra,所以我可能不会使用正确的术语。当我说“可视行”时,我指的是 CQL 结果显示的内容。
更新
您可以创建以下实验(请忽略并修复我将要做的任何语法错误)。
这假设用复合主键做表:
“城市”是“聚类列”。
创建表城市(state int,city int,名称文本,主键((state),city));
插入城市(州、城市、名称)values(1, 1, '纽约'); 插入城市(州、城市、名称)values(1, 2, 'Corona');
从州 = 1 的城市中选择 *;
这将返回类似:
1, 1, New York
1, 2, Corona
Run Code Online (Sandbox Code Playgroud)
但在磁盘上,这将存储在单行中,如下所示:
+-------+-----------------+-----------------+
| state | city = 1 | city = 2 |
| +-----------------+-----------------+
| | city | name | city | name |
+-------+------+----------+------+----------+
| 1 | 1 | New York | 2 | Corona |
+-------+------+----------+------+----------+
Run Code Online (Sandbox Code Playgroud)
当你有这样的复合主键时,你可以选择或删除它,例如
select * from cities where state = 1;
delete from cities where state = 1;
Run Code Online (Sandbox Code Playgroud)
在问题中,主键定义为:
PRIMARY KEY ((house_id, sensor_id, time_bucket), sensor_time)
Run Code Online (Sandbox Code Playgroud)
这意味着
因此,当您选择时,真实的行会被分割并显示为好像有几行。
更新
http://www.planetcassandra.org/blog/primary-keys-in-cql/
主键定义由两部分组成:分区键和聚类列。第一部分映射到存储引擎行键,而第二部分用于对行中的列进行分组。在存储引擎中,通过在列名称前加上集群列的值作为前缀来对列进行分组。这是使用 Thrift API 时的标准设计模式。但现在 CQL 负责将集群列值与表中的非关键字段进行转置。
然后阅读“复合辣酱玉米饼馅”中的解释。