2016-10-01 2 views
3

У меня есть таблица/columnfamily в Cassandra 3.7 с сенсортатами.Повторяющиеся строки/столбцы для одного и того же первичного ключа в Cassandra

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} 

Я думаю, что часть проблемы заключается в том, что эти данные, как было написано «вживую» с помощью Java и драйвер Datastax Java, и он был загружен вместе с историческими данными из другого источника, используя sstableloader.

Независимо от того, это должно быть невозможно. У меня нет возможности соединиться с наследием cassandra-cli в этом кластере, возможно, это сказало бы мне то, что я не вижу, используя cqlsh.

Итак, вопросы:
* Есть ли это в известных обстоятельствах?
* Можно ли читать более сырые данные с помощью cqlsh? Укажите время записи этих двух строк. функция writetime() не может работать с первичными ключами или коллекциями, и это все, что у меня есть.

Спасибо.

Update:

Это то, что я пытался, от комментариев, ответов и других источников
* выбирающий используя blobAsBigInt дает ту же большое число для всех идентичных строк
* Подключение с помощью Кассандры-кли, после того, как возможность бережливости, возможно, но чтение таблицы - нет. Он не поддерживается после 3.x
* сбрасывание с использованием sstabledump продолжается, но ожидается, что потребуется еще неделя или две;)

+0

вы можете проверить данные с cassandra-cli? – Nick

+0

Нет, cassandra-cli не поддерживается в 3.x. Я мог бы сделать sstabledump, но файлы данных огромны, и этот инструмент не предлагает фильтрации. –

+0

Я считаю, что sensor_time отличается для обеих строк, но усекается и отображается так, как если бы время было таким же. Вы также можете спросить в списке рассылки Cassandra. – Nick

ответ

-1

«sensor_time» является частью первичного ключа. Это не в «Ключ раздела», а «Кластерная колонка». вот почему вы получаете две «строки».

Однако в таблице на диске обе «визуальные строки» хранятся в одной строке Cassandra. В действительности, это просто разные столбцы, а CQL просто притворяются, что это две «визуальные строки».

Уточнение - Я не работал с Кассандрой какое-то время, поэтому я не могу использовать правильные условия. Когда я говорю «визуальные строки», я имею в виду результат CQL.

Update

Вы можете создать следующий эксперимент (пожалуйста, игнорировать и исправить синтаксические ошибки я делаю).

Это, предполагает, чтобы сделать таблицу с составным первичным ключом:

  • "состояние" является "Partition Key" и
  • "городом" является "Кластеризация колонна".

    создать таблицу городов ( состояние INT, город ИНТ, название текста, первичный ключ ((состояние), город) );

    Вставить в города (состояние, город, имя) значения (1, 1, 'Нью-Йорк'); Вставить в города (состояние, город, название) значения (1, 2, 'Корона');

    выбрать * из городов, где state = 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" является "Partition Key" и
  • «sensor_time» - это «Кластерная колонна».

Итак, когда вы выберете, настоящая строка выплёта и покажется, как если бы было несколько строк.

Update

http://www.planetcassandra.org/blog/primary-keys-in-cql/

первичное определение KEY состоит из двух частей: Partition Key и кластеризация Столбцы. Первая часть сопоставляется с двигателем хранения , а вторая используется для группировки столбцов в строке. В модуле хранения столбцы сгруппированы путем префикса их имени значением столбцов кластеризации. Это стандартный шаблон проектирования при использовании Thrift API. Но теперь CQL позаботится о переносе значений столбцов кластера в и из неинтегрированных полей в таблице.

Затем прочитайте объяснения в «Композитной энчиладе».

+0

Я не думаю, что это правда, по крайней мере, не после 3.x. Независимо от того, как он сохраняется, он должен быть отфильтрован при чтении, если весь первичный ключ тот же. –

+0

было отличное объяснение для этого где-то на сайте datastax, но я не могу его найти. Я отредактирую с экспериментом, который вы можете сделать. – Nick

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 InPlace из даты и времени вставки, удалось воспроизвести ...

+0

Вставка с целыми числами, как и вы, дает мне две строки, однако они показывают разные значения, напечатанные как обычно, так и с помощью 'blobAsBigInt'. При работе с моим большим кластером я получаю одинаковые значения для 'blobAsBigInt' для всех трех строк. –

+0

@ Андреас хорошо, я вроде как в убыток. с тем, что я знаю о Кассандре, то, что у вас там, не должно быть возможным. Мне будет интересно узнать, что показывает ваше исследование. Как вы считаете, вы запрашиваете несколько узлов? Каков результат описания test.sensor_data? – Highstead

+0

Я вижу из 'tracing on', что я только запрашиваю один узел. Повторение других узлов или добавление 'consistency all' дает тот же результат, чтобы эта« ошибка »находилась на всех узлах, содержащих данные. –