Как построить отсортированный список рангов из таблицы Cassandra?

Я храню свои данные в одной таблице Cassandra 2.0.10. Есть один столбец (с именем score), целочисленный тип, может принимать любые значения. Мне нужно написать фоновое задание, которое будет присваивать значение другому столбцу, rank, присваивая значение 1 строке с наибольшим значением в поле оценки, значение 2 — следующему за самым высоким и так далее. Строка с наименьшим значением score должна получить общее количество строк, назначенное rank. В настоящее время он определен в CQL как

CREATE TABLE players
    (user int, rank int, score int, details blob, PRIMARY KEY(user))

Держу пари, это что-то вроде PostgreSQL, я бы сделал что-то вроде

select id, rank from players order by score desc offset A limit 100;

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

Когда я пытаюсь сделать то же самое в Cassandra CQL, оказывается, что многие необходимые функции не поддерживаются (нет порядка, нет смещения, нет четкого способа посетить все строки). Я попытался построить индекс для столбца оценок, но это не помогло.

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

Можно ли каким-то образом реализовать это присвоение ранга, сочетая Java и CQL, или ограничения достаточно серьезны, и мне нужно использовать другой механизм базы данных?


person Audrius Meskauskas    schedule 31.08.2014    source источник
comment
Пожалуйста, отредактируйте свой пост, добавив описание таблицы.   -  person Carlo Bertuccini    schedule 01.09.2014
comment
Добавлено объявление таблицы в CQL.   -  person Audrius Meskauskas    schedule 01.09.2014


Ответы (1)


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

игроки (id, ранг) и rank_to_id (ранг, id_list). Затем вы должны запросить вторую страницу, используя:

выберите * из rank_to_id, где ранг > 100 предел 100

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

Также я бы порекомендовал вам вместо этого взглянуть на Redis DB. У него такой замечательный тип данных, как Sorted Set, который реализует почти то, что вам нужно: http://redis.io/commands#sorted_set. Однако это зависит от объема данных, которые у вас есть. Redis — это база данных в памяти.

PostgreSQL также может быть хорошим решением. Почему ты не хочешь его использовать?

person Maxim Zakharenkov    schedule 01.09.2014