我在Cassandra 3.7中有一个表/列家庭与sensordata。
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)
)
现在,当我从这个表中选择时,我发现同一个主键的重复项,我认为这是不可能的。
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}
我认为问题的一部分是这些数据都已写入&#34; live&#34;使用java和Datastax java驱动程序,它已使用sstableloader与来自其他源的历史数据一起加载。
无论如何,这不可能。 我无法将遗留的cassandra-cli连接到这个集群,或许这会告诉我一些我无法使用cqlsh看到的内容。
所以,问题是:
*无论如何,在已知的情况下会发生这种情况吗?
*我可以使用cqlsh读取更多原始数据吗?具体写这两行的时间。 writetime() - 函数不能对主键或集合进行操作,这就是我所拥有的。
感谢。
更新:
这是我尝试过的,来自评论,答案和其他来源
*使用blobAsBigInt选择为所有相同的行提供相同的大整数
*在启用节俭之后使用cassandra-cli进行连接是可能的,但是阅读表格并非如此。 3.x后不支持
*正在使用sstabledump进行倾销,但预计还需要一两周;)
答案 0 :(得分:0)
我不希望在时间戳字段中看到纳秒,另外我的印象是他们完全不受支持?试试这个:
SELECT house_id, sensor_id, time_bucket, blobAsBigint(sensor_time) FROM test.sensor_data;
我可以通过整数插入行来复制它:
INSERT INTO sensor_data(house_id, sensor_id, time_bucket, sensor_time) VALUES (1,2,4,1451692800000);
INSERT INTO sensor_data(house_id, sensor_id, time_bucket, sensor_time) VALUES (1,2,4,1451692800001);
这是有道理的,因为我怀疑你的一个驱动程序正在使用bigint来插入时间戳,而且实际上可能正在使用日期时间。
尝试使用时区和bigints来重现这个......似乎只有bigint可以重现
house_id | sensor_id | time_bucket | sensor_time | sensor_reading
----------+-----------+-------------+--------------------------+----------------
1 | 2 | 3 | 2016-01-02 00:00:00+0000 | null
1 | 2 | 4 | 2016-01-01 23:00:00+0000 | null
1 | 2 | 4 | 2016-01-02 00:00:00+0000 | null
1 | 2 | 4 | 2016-01-02 00:00:00+0000 | null
1 | 2 | 4 | 2016-01-02 01:01:00+0000 | null
编辑:尝试使用bigint代替日期时间插入一些恶作剧,设法重现......
答案 1 :(得分:-1)
“sensor_time”是主键的一部分。它不在“分区键”中,而是“聚类列”。这就是为什么你得到两个“行”。
但是,在磁盘表中,两个“可视行”都存储在单个Cassandra行中。实际上,它们只是不同的列,而CQL只是假装它们是两个“视觉行”。
澄清 - 我没有和Cassandra合作过一段时间,所以我可能不会使用正确的术语。当我说“视觉行”时,我指的是CQL结果显示的内容。
<强>更新强>
您可以创建以下实验(请忽略并修复我将要执行的任何语法错误)。
这假设用复合主键做表:
“city”是“Clustering Column”。
创建表城市( state int, city int, 姓名文字, 主键((州),城市) );
插入城市(州,市,名)值(1,1,'纽约'); 插入城市(州,市,名)值(1,2,'Corona');
从州= 1;
这将返回类似:
1, 1, New York
1, 2, Corona
但是在磁盘上,这将存储在单行上,如下所示:
+-------+-----------------+-----------------+
| state | city = 1 | city = 2 |
| +-----------------+-----------------+
| | city | name | city | name |
+-------+------+----------+------+----------+
| 1 | 1 | New York | 2 | Corona |
+-------+------+----------+------+----------+
当你有这样的复合主键时,可以选择或删除它,例如
select * from cities where state = 1;
delete from cities where state = 1;
在问题中,主键定义为:
PRIMARY KEY ((house_id, sensor_id, time_bucket), sensor_time)
这意味着
因此,当您选择时,实际行将被吐出并显示为好像有几行。
<强>更新强>
http://www.planetcassandra.org/blog/primary-keys-in-cql/
PRIMARY KEY定义由两部分组成:分区键 和聚类列。第一部分映射到存储引擎 行键,而第二行用于对一行中的列进行分组。在里面 存储引擎列的前缀为其名称 聚类列的值。这是一种标准的设计模式 使用Thrift API时。但现在CQL负责转置 将列值与表中的非键字段进行聚类。
然后阅读“The Composite Enchilada”中的解释。