2016-11-02 2 views
5

Я рассматриваю Cassandra как промежуточное хранилище во время моего задания ETL для выполнения дедупликации данных.Получить первую строку для каждого ключа раздела в Cassandra

Предположим, у меня есть поток событий, каждый из которых имеет идентификатор бизнес-объекта, временную метку и некоторую ценность. Мне нужно получить только последнее значение с точки зрения временной метки для каждого бизнес-ключа, но события могут быть неупорядоченными.

Моя идея состояла в том, чтобы создать промежуточную таблицу с бизнес-идентификатор в качестве ключа секционирования и метку времени в качестве ключа кластеризации:

CREATE TABLE sample_keyspace.table1_copy1 (
id uuid, 
time timestamp, 
value text, 
PRIMARY KEY (id, time) 
) WITH CLUSTERING ORDER BY (time DESC) 

Теперь, если я вставить данные в этой таблице я могу получить последнее значение для некоторого данного раздела ключ:.

select * from table1 where id = 96b29b4b-b60b-4be9-9fa3-efa903511f2d limit 1; 

Но это потребует выдать такой запрос для каждого бизнес-ключ меня интересует

есть ли какой-то эффективный способ, которым я мог бы сделать это в CQL?

Я знаю, что у нас есть возможность перечислить все доступные ключи раздела (по select distinct id from table1). Поэтому, если я посмотрю на модель хранения Cassandra, получение первой строки для каждого ключа раздела не должно быть слишком сложным.

Это поддерживается?

ответ

13

Если вы используете версию после 3.6, есть опция в вашем запросе имени PER PARTITION LIMIT (CASSANDRA-7017), который можно установить в 1. Это не будет автоматически завершено в cqlsh до 3.10 с CASSANDRA-12803.

SELECT * FROM table1 PER PARTITION LIMIT 1; 
0

Одним словом: нет.

Разделительный ключ - это то, почему Cassandra может работать практически с любым количеством данных: он решает, куда помещать/искать данные, используя хэш ключа секционирования. Вот почему CQL SELECTs всегда необходимо сделать фильтр равенства на весь ключ раздела. Чтобы найти первый time для каждого id, Кассандре нужно было бы спросить все узлы для любого раздела данных, , затем выполнить сложную операцию над каждым из них. Реляционные базы данных позволяют это, Кассандра этого не делает. Все, что он разрешает, - это полное сканирование таблицы (SELECT * from table1) или сканирование разделов (SELECT DISTINCT id FROM table1), но они не могут * быть связаны с какой-либо сложной операцией.

*) Я не принимаю ALLOW FILTERING здесь, так как это не помогает в этом контексте.

Смежные вопросы