comment éviter les index secondaires de cassandra?

j'ai entendu à plusieurs reprises que les indices secondaires (en cassandra) sont seulement pour la commodité mais pas pour une meilleure performance. Le seul cas où il est recommandé d'utiliser des index secondaires lorsque vous avez une faible cardinalité (comme le genre column qui a deux valeurs (Mâle Ou Femelle)

prenons cet exemple:

CREATE TABLE users ( 
userID uuid, 
firstname text, 
lastname text, 
state text, 
zip int, 
PRIMARY KEY (userID) 
);

pour l'instant je ne peux pas faire cette requête à moins de créer un index secondaire sur usersfirstname index

select * from users where firstname='john'

Comment puis-je dénormaliser ceci table telle que je puisse avoir cette requête: Est-ce la seule manière efficace en utilisant des clés composites? D'autres solutions de rechange ou suggestions?

CREATE TABLE users ( 
    userID uuid, 
    firstname text, 
    lastname text, 
    state text, 
    zip int, 
    PRIMARY KEY (firstname,userID) 
    );
13
demandé sur brain storm 2014-08-04 22:15:06

3 réponses

pour trouver un bon modèle de données, vous devez d'abord identifier les requêtes que vous souhaitez effectuer. Si vous avez seulement besoin de rechercher les utilisateurs par leur prénom (ou prénom et nom d'utilisateur), alors votre deuxième conception est très bien...

si vous avez également besoin de rechercher les utilisateurs par leur nom de famille, alors vous pouvez créer une autre table ayant les mêmes champs mais une clé primaire sur (lastname, userID). Évidemment, vous aurez besoin de mettre à jour les deux tableaux dans le même temps. La duplication de données est très bien à Cassandra.

cependant, si vous êtes préoccupé par l'espace nécessaire pour les deux tables ou plus, vous pouvez créer une table d'utilisateurs unique partitionnée par l'ID utilisateur, et des tables supplémentaires pour les champs que vous voulez interroger par:

CREATE TABLE users ( 
    userID uuid, 
    firstname text, 
    lastname text, 
    state text, 
    zip int, 
    PRIMARY KEY (userID) 
);

CREATE TABLE users_by_firstname (
    firstname text,
    userid uuid,
    PRIMARY KEY (firstname, userid)
);

L'inconvénient de cette solution est que vous aurez besoin de deux requêtes pour récupérer les utilisateurs par leur prénom:

SELECT userid FROM users_by_firstname WHERE firstname = 'Joe';
SELECT * FROM users WHERE userid IN (...);

J'espère que cela aidera

17
répondu medvekoma 2014-08-06 16:24:21

il y a plusieurs façons de le faire, toutes avec des avantages et des inconvénients.

  • votre deuxième requête fonctionnera, mais ce n'est qu'une table d'index. http://wiki.apache.org/cassandra/SecondaryIndexes Un index secondaire peut être utile, et si vous frappez une partition en premier (ce que vous ne pouvez pas faire dans votre première table), alors l'implémentation de cassandra vous sauvera les tracas, et gardera les choses "atomiques locales". Sans frapper une partition cependant, votre première table avec l'index ne pas être grand avec votre requête car il va frapper tout partout.

  • vous pouvez dénormaliser complètement, mais vous pouvez aussi faire un tour de table. c'est-à-dire que votre deuxième table ne peut exister que pour retourner l'identifiant de l'utilisateur. Vous pouvez ensuite faire une deuxième requête pour récupérer uniquement pour les partitions concernées. Si vous attendez quelques résultats, cela peut être bon. Si non, vous allez frapper de nombreuses partitions à travers de nombreux noeuds (qui dépend de la taille de votre cluster et des critères d'évitement hotspot, peut être bon ou mauvais). Faire beaucoup de requêtes ~1ms est généralement mieux que faire une requête ~1000ms.

  • vous pouvez faire du bucketing artificiel, et émettre des requêtes n=bucketcount. Ceci a des frais généraux supplémentaires, mais réduit le nombre de requêtes et peut être une bonne option.

  • Votre index pourrait être les premiers caractères du prénom. Ou ça pourrait être un hachage consistant dans quelques seaux. Le premier peut vous donner "commence par" sémantique.

ce ne sont que quelques options. Passer d'un modèle de données logique à un modèle physique nécessite une évaluation des compromis que vous souhaitez faire.

4
répondu ashic 2014-08-05 04:02:46

il y a aussi des vues matérialisées avec des udpates automatiques qui cloisonnent les données sur différentes colonnes, ce qui permet donc de faire des lectures beaucoup plus rapides et d'éviter les indices secondaires tout à fait. Il y a quelques avantages supplémentaires de le faire sur votre propre.

L'idée générale d'éviter chaud partitions reste.

et puis, il y a aussi l'index SASI si vous faites beaucoup de mises à jour sur la clé primaire de la vue matérialisée pour éviter les pierres tombales.

0
répondu kisna 2018-04-19 20:02:26