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 и ключ кластеризации. Вы можете обратиться к этой ссылке подробнее.