Cassandra中相同主键的行/列重复

时间:2016-10-01 06:52:17

标签: cassandra cql

我在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进行倾销,但预计还需要一两周;)

2 个答案:

答案 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结果显示的内容。

<强>更新

您可以创建以下实验(请忽略并修复我将要执行的任何语法错误)。

这假设用复合主键做表:

  • “state”是“Partition Key”和
  • “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)

这意味着

  • “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”中的解释。