Comment concevoir des tableaux dans Cassandra, où les lignes doivent être recherchées par list<varchar> ?

StackOverflow https://stackoverflow.com//questions/24017395

  •  21-12-2019
  •  | 
  •  

Question

étant donné que j'ai les objets suivants à conserver dans Cassandra :

Tableau de Foo :

{
    "id":1,
    "name": "this is a name",
    "bundleFields" : [
        "bundleByMe",
        "me2",
        "me also",
    ]
},
{
    "id":2,
    "name": "anotherName",
    "bundleFields" : [
        "bundleByMe",
        "me2",
        "me also",
    ]
},
{
    "id":3,
    "name": "thridName",
    "bundleFields" : [
        "differentBundleCriteria"
    ]
}

Je veux interroger quelque chose comme SELECT * FROM FOO where bundleFields = ["...", "..."].

Cela ne fonctionne évidemment pas, puisque les requêtes par list<> ne sont pas possibles (pas de clé primaire).

Voici le schéma que j'ai actuellement :

CREATE TABLE IF NOT EXISTS Foo (
    id int,
    name varchar,
    bundleFields list<varchar>,
    PRIMARY KEY(id)
);

La seule solution que je peux imaginer est une autre table où la PRIMARY KEY contient les valeurs concaténées du bundleFields-Array, ce qui permettrait une recherche par bundleString :

CREATE TABLE IF NOT EXISTS fooByBundleString (
    bundleString varchar,
    fooId int,
    PRIMARY KEY(bundleString)
);

Est-ce l'approche recommandée pour ce problème dans Cassandra.

L'idée de devoir sérialiser/désérialiser le tableau bundleFields ne me semble pas "juste".

Merci du conseil!


Modifier:Comme @rs_atl l'a suggéré, le DDL correct pour la table fooByBundleString devrait être (notez les fooId dans CLÉ PRIMAIRE) :

CREATE TABLE IF NOT EXISTS fooByBundleString (
    bundleString varchar,
    fooId int,
    PRIMARY KEY(bundleString, fooId)
);

pour créer un index de couverture, car sinon il ne serait pas possible de stocker la même bundleString pour différents fooId.

Était-ce utile?

La solution

Créer un index comme vous l'avez décrit est la bonne solution.Cependant, ce devrait être un couvrant index, ce qui signifie que vous souhaiterez dupliquer toutes les valeurs dont vous avez réellement besoin dans votre requête.Sinon, vous finirez par effectuer une jointure distribuée dans votre application, ce qui coûte très cher.De manière générale, préférez les modèles de données dénormalisés aux modèles relationnels normalisés.C'est essentiellement la même chose que vous devez faire dans votre SGBDR préféré pour effectuer des requêtes rapidement.La différence est que vous devez gérer l'index dans votre application ;Cassandra ne le fera pas à votre place.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top