Я пытаюсь преобразовать относительно распространенное требование в SQL в эффективную модель данных в Cassandra. Я пытаюсь решить, как лучше смоделировать свои данные, чтобы я мог упорядочивать свои строки в Cassandra в том же порядке, в котором я хочу сообщать о них в приложении. Обычно это был бы хороший случай для столбца кластеризации, за исключением того, что данные, по которым я хочу упорядочить свой результат, являются метрикой, которая будет обновляться несколько раз в день.
Я собираюсь объяснить проблему в SQL, а затем поделиться подходами к моделированию данных, которые пришли мне в голову. Я хотел бы знать, сталкивался ли кто-нибудь с подобным требованием к моему, и если да, то как вы моделировали данные в Cassandra.
Вот проблема, которую я пытаюсь решить.
Предположим, у меня есть таблица raw_data, определенная так:
CREATE TABLE raw_data (
A varchar,
B varchar,
C varchar,
D varchar,
ts timestamp,
val varint
PRIMARY KEY (ts,A,B,C,D)
);
А еще у меня есть сводная таблица
CREATE TABLE summary_table (
A varchar,
B varchar,
C varchar,
total_val varint
PRIMARY KEY (A,B,C)
);
Где данные в моей сводной таблице агрегируются моим приложением таким образом, который соответствует
SELECT A, B, C, SUM(val) FROM raw_data GROUP BY A, B, C
То, что я хочу сделать, это выполнить запрос, подобный следующему:
SELECT B, C, total_val FROM summary_table WHERE A = "Something" ORDER BY total_val DESC LIMIT 1000;
Другими словами, я хочу подмножить свою сводную таблицу для определенного значения A, а затем вернуть 1000 лучших строк, упорядоченных по total_val.
Total_val обновляется моим приложением каждые несколько минут, так как дополнительные данные передаются в мою таблицу raw_data. Поэтому я не могу использовать total_val в качестве столбца кластеризации для своих данных.
Я пытаюсь решить, как лучше смоделировать этот тип проблемы в Cassandra, в которой мне нужно создать подмножество сводной таблицы с помощью WHERE CLAUSE и упорядочить результирующий набор (который постоянно обновляется) в порядке DESC.
Можно ожидать, что некоторые результирующие наборы будут довольно большими — несколько сотен тысяч строк (то есть в моей сводной таблице есть некоторые значения для A, для которых SELECT COUNT(*) FROM summary_table WHERE A = "some value"
будет очень, очень большим, исчисляемым сотнями строк). тысяч). Очевидно, что неэффективно сортировать эти данные и отбрасывать их перед отправкой в мое приложение.
Кроме того, это не лучший вариант использования вторичных индексов. На меньших наборах результатов они очень эффективны. Для более крупных они отстают, и я подозреваю, что может быть лучший способ справиться с этой проблемой.
Другой способ моделирования, который я рассматривал, заключается в кэшировании больших наборов результатов в памяти, так что, по крайней мере, там, где мне нужно отсортировать многие тысячи строк, я, по крайней мере, делал бы это в памяти. Я также рассматривал возможность создания вторичной сводной таблицы, которая уже предварительно заполнена 1000 строками, которые я хочу предоставить своему приложению... хотя я не могу придумать хороший способ поддерживать эти данные в актуальном состоянии и избегать точных та же проблема, что и у меня с исходной сводной таблицей.
Кто-нибудь сталкивался с такой проблемой, когда вам нужно отфильтровать сводные данные с помощью предложения WHERE и упорядочить (часто меняющиеся) результаты в порядке описания? Если да, то нашли ли вы способ сделать это эффективным, когда определенные предложения WHERE будут возвращать много тысяч строк? Если да, то как вы собирались это сделать?