Quelle est la différence entre UPDATE
et INSERT
lors de l'exécution de CQL contre Cassandra?
Il semble qu’il n’y ait pas eu de différence auparavant, mais la documentation indique que INSERT
ne prend pas en charge les compteurs, alors que UPDATE
le fait.
Existe-t-il une méthode "préférée" à utiliser? Ou existe-t-il des cas où l'un devrait être utilisé par rapport à l'autre?
Merci beaucoup!
Les colonnes de compteur dans Cassandra ne peuvent pas être définies sur une valeur arbitraire: elles ne peuvent être incrémentées ou décrémentées que par une valeur arbitraire.
Pour cette raison, INSERT
ne prend pas en charge Counter Column car vous ne pouvez pas "insérer" une valeur dans une colonne Counter. Vous ne pouvez que UPDATE
(incrémenter ou décrémenter) d'une valeur. Voici comment mettre à jour une colonne Counter.
UPDATE ... SET name1 = name1 + <value>
Tu as demandé:
Existe-t-il une méthode "préférée" à utiliser? Ou existe-t-il des cas où l'un devrait être utilisé par rapport à l'autre?
Oui. Si vous insérez des valeurs dans la base de données, vous pouvez utiliser INSERT
. Si la colonne n'existe pas, elle sera créée pour vous. Sinon, l'effet de INSERT
est similaire à UPDATE
. INSERT
est utile lorsque vous n’avez pas de schéma prédéfini (famille de colonnes dynamiques, c’est-à-dire insérer quoi que ce soit, à tout moment). Si vous concevez le schéma à l'avance (famille de colonnes statiques, similaire à RDMS) et connaissez chaque colonne, vous pouvez utiliser UPDATE
.
Il y a une différence subtile. Les enregistrements insérés via INSERT restent si vous définissez tous les champs non-clés sur NULL. Les enregistrements insérés via UPDATE disparaissent si vous définissez tous les champs non clés à null.
Essaye ça:
CREATE TABLE T (
pk int,
f1 int,
PRIMARY KEY (pk)
);
INSERT INTO T (pk, f1) VALUES (1, 1);
UPDATE T SET f1=2 where pk=2;
SELECT * FROM T;
Résultats:
pk | f1
----+----
1 | 1
2 | 2
Maintenant, mettez à jour chaque paramètre de ligne f1 à null.
UPDATE T SET f1 = null WHERE pk = 1;
UPDATE T SET f1 = null WHERE pk = 2;
SELECT * FROM T;
Notez que la ligne 1 reste, tandis que la ligne 2 est supprimée.
pk | f1
----+------
1 | null
Si vous les utilisez avec Cassandra-cli, vous verrez une différence dans la façon dont les lignes sont ajoutées.
Je voudrais bien savoir si c'est par conception ou un bug et voir ce comportement documenté.
Une autre différence subtile (je commence à croire que cql est une interface terrible pour cassandra, pleine de subtilités et de mises en garde dues à l’utilisation d’une syntaxe SQL similaire mais d’une sémantique légèrement différente) réside dans la définition de TTL sur des données existantes. Avec UPDATE
, vous ne pouvez pas mettre à jour le TTL des clés, même si les nouvelles valeurs réelles sont égales aux anciennes. La solution consiste à INSÉRER la nouvelle ligne à la place, avec le nouveau TTL déjà défini
En ce qui concerne la différence subtile soulignée par billbaird (je ne peux pas commenter directement cet article), une ligne créée par une opération de mise à jour sera supprimée si tous les champs non clés sont nuls:
C'est le comportement attendu et non un bogue basé sur le rapport de bogue à https://issues.Apache.org/jira/browse/CASSANDRA-11805 (qui a été fermé en tant que "Pas un problème")
Je me suis heurté à cela lorsque j'ai utilisé Spring Data pour la première fois. J'utilisais la méthode save(T entity)
d'un référentiel, mais aucune ligne n'était en cours de création. il s'est avéré que Spring Data utilisait une UPDATE
car il a déterminé que l'objet n'était pas «nouveau» (je ne suis pas sûr que le test de 'isNew' ait du sens ici), et il m'est arrivé de tester avec des entités disposant uniquement des champs de clé définis .
Pour ce cas Spring Data, les interfaces de référentiel spécifiques à Cassandra fournissent une méthode insert
qui semble utiliser systématiquement une INSERT
si ce comportement est souhaité (bien que la documentation de Spring ne documente pas suffisamment ces détails).