J'essaie de remodeler une base de données SQL Cassandra de telle sorte que je puisse trouver l'équivalent Cassandra pour les requêtes SQL. J'utilise CQL 3 et Cassandra v1.2. J'ai modélisé la conception de la base de données dans cassandra afin qu'il prenne en charge les clauses order by et les tables dénormalisées pour prendre en charge l'opération de jointure. Cependant, je suis en mer quand il vient aux équivalents DISTINCT, SUM () et 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'
Cela ressemble à un étalage de mon travail depuis quelques jours. Existe-t-il un moyen dans Cassandra, que je puisse modéliser le schéma db pour prendre en charge des requêtes de ce type? Je ne peux pas penser à quoi que ce soit dans Cassandra. Comment ces requêtes peuvent-elles être implémentées en utilisant Cassandra?
J'ai lu qu'une couche Hive sur Cassandra peut éventuellement faire fonctionner ces requêtes. Je me demande simplement si c'est la seule façon de prendre en charge de telles requêtes dans Cassandra ..? Veuillez conseiller sur tout autre méthodes possibles ..
Cassandra ne prend pas en charge des opérations comme celle-ci. Vous pouvez utiliser quelque chose comme Hive ou un produit (non gratuit) d'Acunu qui peut faire ce dont vous avez besoin.
L'autre solution est de faire le travail vous-même. Par exemple, vous pouvez additionner des choses en lisant toutes les données de certaines lignes et en les additionnant. Ou maintenez un compteur Cassandra pour incrémenter à la volée.
Avec Cassandra vous résolvez ces types de problèmes en faisant plus de travail lorsque vous insérez vos données - ce qui semble être lent, mais Cassandra est conçu pour écrit rapidement, et vous allez probablement lire les données beaucoup plus de fois que vous ne les écrivez, il est donc logique de considérer l'ensemble du système.
Je ne peux pas vous dire exactement comment créer vos tables pour modéliser votre problème car cela dépendra beaucoup des détails. Vous devez comprendre un schéma qui vous permet d'obtenir les données sans effectuer d'agrégation à la volée. Réfléchissez à la façon dont vous créeriez des vues pour les requêtes dans un SGBDR, puis essayez de penser à la façon dont vous inséreriez des données directement dans ces vues, pas dans les tables sous-jacentes. Voilà comment vous modélisez les choses à Cassandra.
Bien que ce soit une vieille question, elle apparaît assez élevée dans les résultats de recherche Google. Je voulais donc faire une mise à jour.
Cassandra 2.2+ prend en charge la fonction définie par l'utilisateur et les agrégats définis par l'utilisateur. [~ # ~] avertissement [~ # ~] : cela ne signifie pas que vous n'avez plus à faire de modélisation de données (comme cela a été souligné par @Theo), il vous permet plutôt de prétraiter légèrement vos données lors de leur récupération.
SELECT DISTINCT (a2) FROM demo2 where b2 = 'sea'
Pour implémenter DISTINCT
, vous devez définir une fonction et un agreggate. J'appellerai à la fois la fonction et l'agrégat uniq
plutôt que distinct
pour souligner le fait qu'elle est définie par l'utilisateur.
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 {};
Ensuite, vous l'utilisez comme suit:
SELECT uniq(a2) FROM demo2 where b2='sea';
SELECT somme (a3), somme (b3) de demo3 où c3 = 'eau' et d3 = 'océan'
SUM
est fourni hors de la boîte et fonctionne comme vous vous en doutez. Voir system.sum
.
SELECT a1, MAX (b1) FROM demo1 group by a1
GROUP BY
est délicat. En fait, il n'y a aucun moyen de regrouper les lignes de résultats par une colonne. Mais ce que vous pouvez faire, c'est créer un map<text, int>
et pour les regrouper manuellement dans la carte. Basé sur un exemple du blog de Christopher Batey, group-by et 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 {};
Ensuite, vous l'utilisez comme suit:
SELECT state_group_and_max(a1, b1) FROM demo1;
enable_user_defined_functions=true
dans ton cassandra.yaml
pour activer les fonctionnalitésCassandra 3.10 prend désormais en charge le regroupement par clé de partition et clé de clustering. Vous pouvez vous référer à ce lien pour plus de détails.