MAX(), DISTINCT и group by в Кассандре
Я пытаюсь переделать базу данных SQL Cassandra так, чтобы я мог найти эквивалент Cassandra для SQL-запросов. Я использую CQL 3 и Cassandra v1.2. Я смоделировал дизайн БД в cassandra, чтобы он поддерживал предложения order by и денормализованные таблицы для поддержки операции соединения. Однако я нахожусь в море, когда дело доходит до различных, SUM() и GROUPBY equvalents
SELECT a1,MAX(b1) FROM demo1 group by a1.
SELECT DISTINCT (a2) FROM demo2 where b2='sea'
SELECT sum(a3), sum(b3) from demo3 where c3='water' and d3='ocean'
Это похоже на showstopper для моей работы за последние пару дней. Есть ли способ в Кассандре, чтобы я может ли модель схемы БД поддерживать запросы такого рода? Я не могу думать о Кассандре . Как такие запросы реализуются с помощью Cassandra?
Я прочитал, что слой улья над Кассандрой может заставить эти запросы работать. Мне просто интересно, является ли это единственным способом поддержки таких запросов в Cassandra..? Pls советует на всех других возможных методах..
4 ответов
Кассандра не поддерживает такие операции. Вы можете использовать что-то вроде улья сверху или есть (несвободный) продукт от Acunu, который может сделать то, что вам нужно.
другое решение-сделать работу самостоятельно. Например, вы можете суммировать вещи, читая все данные из определенных строк и суммируя. Или поддерживать счетчик Cassandra для увеличения на лету.
с Кассандрой вы решаете такие проблемы, делая больше работы при вставке данных , что звучит так, как будто это будет медленно, но Кассандра предназначена для быстрой записи, и вы, вероятно, будете читать данные много раз, чем вы пишете, поэтому имеет смысл, когда вы рассматриваете всю систему.
Я не могу точно сказать, как создать таблицы для моделирования вашей проблемы, потому что это будет зависеть от деталей. Вам нужно найти схему, которая позволит вам получить данные без выполнения каких-либо агрегаций на лету. Подумайте о том, как создавать представления для запросов в СУБД, а затем попробуйте подумать, как вставлять данные непосредственно в эти представления, а не в базовые таблицы. Вот как ты моделируешь вещи в Кассандре.
хотя это старый вопрос, он появляется в результатах поиска Google довольно высокой. Так что я хотел сообщить новости.
Cassandra 2.2 + поддерживает определенную пользователем функцию и определенные пользователем агрегаты. предупреждение: это не означает, что вам больше не нужно делать моделирование данных (как было указано @Theo), а просто позволяет немного предварительно обрабатывать ваши данные при извлечении.
выберите DISTINCT (a2) из demo2, где Б2='море'
для реализации DISTINCT
, вы должны определить функцию и agreggate. Я вызову как функцию, так и совокупность uniq
, а не distinct
подчеркнуть тот факт, что он является пользователем.
CREATE OR REPLACE FUNCTION uniq(state set<text>, val text)
CALLED ON NULL INPUT RETURNS set<text> LANGUAGE java
AS 'state.add(val); return state;';
CREATE OR REPLACE AGGREGATE uniq(text)
SFUNC uniq STYPE set<text> INITCOND {};
тогда вы используете его следующим образом:
SELECT uniq(a2) FROM demo2 where b2='sea';
выберите sum(a3), sum (b3) из demo3, где c3= "вода" и d3= "океан"
SUM
предоставляется из коробки и работает, как вы ожидаете. Видеть system.sum
.
выберите a1, MAX (b1) из группы demo1 по a1
GROUP BY
- это непросто. На самом деле, нет способа сгруппировать строки результатов по некоторому столбцу. Но что вы можете сделать, это создать map<text, int>
и группировать их вручную на карте. На основе примера из блога Кристофера Бейти, group-by и max:
CREATE OR REPLACE FUNCTION state_group_and_max(state map<text, int>, type text, amount int)
CALLED ON NULL INPUT
RETURNS map<text, int>
LANGUAGE java AS '
Integer val = (Integer) state.get(type);
if (val == null) val = amount; else val = Math.max(val, amount);
state.put(type, val);
return state;
' ;
CREATE OR REPLACE AGGREGATE state_group_and_max(text, int)
SFUNC state_group_and_max
STYPE map<text, int>
INITCOND {};
тогда вы используете его следующим образом:
SELECT state_group_and_max(a1, b1) FROM demo1;
Примечания
- как уже было сказано выше, вы все еще должны инвестировать некоторое время в моделирование данных, не злоупотребляйте этими функциями
- вы должны установить
enable_user_defined_functions=true
в своемcassandra.yaml
для включения функции - вы можете перегрузить функции для поддержки группировки по столбцам разных типов.
ссылки:
Cassandra 3.10 теперь поддерживает Group BY parition key и ключ кластеризации. Вы можете обратиться к этой ссылке подробнее.