2017-07-03 3 views
0

Disons que je le tableau suivant Cassandra:Supprimer les données de Cassandra avec une partie de la partition clé

customer_bought_product (
    store_id uuid, 
    product_id text, 
    order_time timestamp, 
    email text, 
    first_name text, 
    last_name text, 
    PRIMARY KEY ((store_id, product_id), order_time, email) 

Les clés de partition sont store_id et order_id et il est utilisé afin de stocker des données de séries chronologiques.

Les données n'ont pas de TTL, car elles devraient être accessibles en tout temps. Dans certains cas, nous pouvons avoir besoin de supprimer toutes les données pour store_id. Quelle est la meilleure pratique pour le faire?

Jusqu'à présent, j'ai pensé des solutions suivantes:

  1. Ecrire un programme, qui sélectionnera toutes les données de la table et supprimer les enregistrements avec la donnée store_id. - L'inconvénient est que cela prendra de plus en plus de temps car nous insérons plus de données dans le tableau.
  2. Laissez les données dans le tableau. - Le seul problème avec cela, c'est que nous aurons des données inutiles.
  3. Stockez le nom de la table avec les clés de partition disponibles dans une table différente, qui peut être interrogée par store_id, récupérez les clés et créez une instruction de suppression pour chacune de ces clés. - Je n'aime pas ce concept, parce que je dois tenir les dossiers.

Est-ce que quelqu'un a rencontré ce problème? Quelle est la meilleure pratique pour effacer les enregistrements inutilisés de Cassandra (à l'exclusion de TTL)?

+0

Comment pouvez-vous accéder aux données avec une partie de clé de partition? AUTORISER LE FILTRAGE va être si coûteux et inefficace dans la production. – dilsingi

+0

Lorsque j'accède aux données, j'ai un 'product_id' spécifique et un' store_id'. –

+0

C'est donc seulement pendant les suppressions que vous avez juste le store_id et le modèle d'accès normal est via la clé de partition de product_id et store_id. A fourni ma réponse basée sur ceci. – dilsingi

Répondre

2

Créez une vue matérialisée pour stocker les ID_produit appartenant à un store_ids correspondant. De cette façon, vous pouvez interroger le MV pour un store_id donné puis supprimer les lignes correspondantes de la table principale. De cette façon, le code d'application supplémentaire pourrait être évité pour maintenir deux tables différentes.

create materialized view mv_customer_bought_product 
as select product_id, store_id, order_time, email 
from customer_bought_product 
where order_time is not null 
and email is not null 
and product_id is not null 
and store_id is not null 
primary key (store_id, product_id, order_time, email) ; 
+0

dans la vue matérialisée, les colonnes autres que store_id et product_id peuvent être exclues, cela aidera à économiser de l'espace disque. –

+1

@ArunJoyThekkiniyath Vous devez également avoir toutes les colonnes de la clé primaire de la table principale dans la vue matérialisée. Il n'y a aucune exception pour sauvegarder le stockage :) – dilsingi

+0

Merci pour la réponse. L'utilisation de vues matérialisées est une bonne solution, car je ne devrais conserver qu'une seule table. –

1

La suppression par une partie de la clé de partition n'est pas possible.

Voici une approche:

Créer une table séparée qui aura toutes les années Product_ID pour un magasin donné.

CREATE TABLE product_by_store(
store_id uuid, 
product_id set<text>, 
PRIMARY KEY(store_id) 
); 

maintenant Wile écrit à customer_bought_product, mettre à jour aussi product_by_store, quelque chose comme

UPDATE product_by_store SET product_id=product_id + 'someValue' WHERE store_id=GIVEN_STORE_ID

Vous pouvez utiliser la déclaration de LOT en écrivant, de cette façon, vous obtiendrez atomicité.

Maintenant, tout en supprimant vous pouvez obtenir toutes product_id pour store_id donné puis utiliser

DELETE FROM customer_bought_product WHERE store_id=GIVEN_STORE_ID and product_id in (PRODUCT_ID YOU GET from product_by_store table)

supprimer également enregistrement correspondant de customer_bought_product