MAX(), DISTINCT и группа в Кассандре

Я пытаюсь переделать базу данных SQL Cassandra таким образом, что я могу найти эквивалент Cassandra для SQL-запросов. Я использую CQL 3 и Cassandra v1.2. Я смоделировал проект db в cassandra, чтобы он поддерживал порядок по предложениям и денормализованным таблицам для поддержки операции объединения. Тем не менее, я нахожусь в море, когда речь идет о значениях DISTINCT, SUM() и GROUPBY

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'

Это похоже на демонстрацию моей работы за последние пару дней. Есть ли способ в Cassandra, чтобы я мог моделировать схему db для поддержки таких запросов? Я не могу думать о Кассандре. Как такие запросы могут быть реализованы с использованием Cassandra?

Я читал, что слой улья над Cassandra может заставить эти запросы работать. Мне просто интересно, является ли это единственным способом, которым такие запросы могут поддерживаться в Cassandra..? Pls советует по любым другим возможным методам.

Ответы

Ответ 1

Кассандра не поддерживает такие операции. Вы можете использовать что-то вроде Hive сверху или есть (несвободный) продукт от Acunu, который может делать то, что вам нужно.

Другим решением является выполнение самой работы. Например, вы можете суммировать вещи, читая во всех данных из определенных строк и суммируя. Или поддерживайте счетчик Cassandra для увеличения на лету.

Ответ 2

С Cassandra вы решаете эти проблемы, делая больше работы, когда вы вставляете свои данные - это звучит так, будто это будет медленным, но Cassandra предназначен для быстрой записи, и вы, вероятно, будете читать данные еще много чем вы его пишете, поэтому имеет смысл, когда вы рассматриваете всю систему.

Я не могу точно сказать, как создавать таблицы для моделирования вашей проблемы, потому что это будет зависеть от деталей. Вам нужно указать схему, которая позволяет вам получать данные, не выполняя никаких "на лету" агрегатов. Подумайте о том, как создавать представления для запросов в СУБД, а затем попытаться подумать, как вставлять данные непосредственно в эти представления, а не в базовые таблицы. Вот как вы моделируете вещи в Кассандре.

Ответ 3

Хотя это старый вопрос, он появляется в результатах поиска Google довольно высоко. Поэтому я хотел дать обновление.

Cassandra 2.2+ поддерживает пользовательскую функцию и агрегаты, определенные пользователем. ПРЕДУПРЕЖДЕНИЕ: это не означает, что вам больше не нужно выполнять моделирование данных (как это было указано в @Theo), а просто позволяет вам немного препроцитировать ваши данные после извлечения.

SELECT DISTINCT (a2) FROM demo2, где b2 = 'sea'

Чтобы реализовать DISTINCT, вы должны определить функцию и агрегировать. Я буду называть как функцию, так и агрегат 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';

SELECT sum (a3), sum (b3) из demo3, где c3 = 'water' и d3 = 'ocean'

SUM предоставляется из коробки и работает так, как вы ожидали. См. system.sum.

SELECT a1, MAX (b1) FROM demo1 group a1

GROUP BY является сложным. На самом деле, нет способа группировать строки результатов по одному столбцу. Но вы можете создать map<text, int> и сгруппировать их вручную на карте. На основе примера из блога Кристофера Батей, группового и макс:

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, чтобы включить функции
  • Вы можете перегружать функции для поддержки группировки по столбцам разных типов.

Ссылки:

Ответ 4

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