Кассандра: выбрать только последние строки

Я работаю со следующей таблицей:

CREATE TABLE IF NOT EXISTS lp_registry.domain (
ownerid text,
name1st text,
name2nd text,
name3rd text,
registrar text,
registered timestamp,
expiration timestamp,
updated timestamp,
technologies list<text>,
techversions list<text>,
ssl boolean,
PRIMARY KEY (
(name1st, name2nd, name3rd),
registrar, ownerid, registered, expiration, updated
)
);

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

Я выполняю этот выбор:

SELECT * FROM lp_registry.domain WHERE
registrar = 'REG-WEDOS' AND
ownerid = 'FORPSI-JAF-S497436'
ALLOW FILTERING;

Но в результате я хочу только строки с последним «обновленным» значением для каждого уникального «name3rd.name2nd.name1st».

Если бы я был в стандартной базе данных SQL, я бы использовал вложенный выбор с MAX или GROUP BY. Однако это не поддерживается Кассандрой (MAX (), DISTINCT и группа в Кассандре). Но что мне делать в CQL?

4

Решение

Расширение на Ответ Седрика (что является отличным советом и будет рассматривать это как ответ, чтобы принять), вы получите структуру таблицы примерно так:

CREATE TABLE IF NOT EXISTS lp_registry.domain (
ownerid text,
name1st text,
name2nd text,
name3rd text,
registrar text,
registered timestamp,
expiration timestamp,
updated timestamp,
technologies list<text>,
techversions list<text>,
ssl boolean,
PRIMARY KEY ((registrar, ownerid), updated, name1st, name2nd, name3rd)
) WITH CLUSTERING ORDER BY (updated desc);

При выборе данных будут возвращаться строки с самыми последними updated значения в разделе для регистратора и ownerid вы запрашиваете.

Этот запрос будет невероятно быстрым, потому что ваши данные будут организованы на диске регистратором, идентификатор владельца по строкам в порядке убывания.

Это ключевая концепция cassandra в том, что ваши данные организованы в зависимости от того, как вы их запрашиваете. Вы теряете гибкость в своих запросах, но можете чувствовать себя комфортно, так как получите высокую производительность, потому что вы извлекаете данные в том виде, в каком они организованы. Вот почему денормализация ваших данных на основе ваших запросов имеет жизненно важное значение.

Где все становится сложным, если вы хотите получить самые последние обновления все данные. Эту проблему нелегко решить с помощью cassandra, если только у всех нет общего раздела с собственным набором проблем (пример стратегии с использованием «фиктивного» ключа раздела).

3

Другие решения

Вся схема должна быть изменена. SELECT вы делаете, по-видимому, важный с вашей точки зрения приложения не должен требовать ALLOW FILTERING: вы должны денормализовать ваши данные и создать таблицу, в которой registrar а также ownerid являются ключами раздела.

В этой денормализованной структуре, updated должен быть ключом раздела, отсортированным по DESC, Тогда запрос будет

SELECT * FROM lp_registry.domain WHERE registrar='XXX' AND ownerid='YYY' LIMIT 10;

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

Энди ответ предоставляет больше деталей и пример для вашей структуры таблицы.

3