Cassandraの場合、選択した行が存在しない場合、UPDATE
sは暗黙のINSERT
になりますか?つまり、私が言うなら
UPDATE users SET name = "Raedwald" WHERE id = 545127
id
はPRIMARY KEY
of the users
table、and the row has no row with a key 545127、that will it equal to
INSERT INTO users (id, name) VALUES (545127, "Raedwald")
私はその逆が真であることを知っています。すでに存在するINSERT
のid
は、そのUPDATE
を持つ行のid
になります。古いCassandraドキュメンテーションは、その理由で実際に挿入が「upsert」である挿入について話しました。
CQL3のケースに興味があります、Cassandraバージョン1.2+。
はい、Cassandra UPDATE
はINSERT
と同義です。これは CQLドキュメント で説明されています。ここでUPDATE
:
SQLとは異なり、
UPDATE
は行の以前の存在を確認しないことに注意してください。以前に行が存在しない場合は行が作成され、それ以外の場合は更新されます。さらに、作成と更新のどちらが起こったかを知る手段はありません。実際、INSERT
とUPDATE
の意味は同じです。
セマンティクスが異なる場合、Cassandraは、行がすでに存在するかどうかを知るために読み取りを行う必要があります。Cassandraは書き込み最適化されているため、常に書き込み操作では、書き込み前に読み取りを行いません。唯一の例外はカウンターです(unlessreplicate_on_write = false
)。この場合、増分のレプリケーションには読み取りが含まれます。
残念ながら、受け入れられた答えは100%正確ではありません。 insert
sはupdate
sとは異なります:
cqlsh> create table ks.t (pk int, ck int, v int, primary key (pk, ck));
cqlsh> update ks.t set v = null where pk = 0 and ck = 0;
cqlsh> select * from ks.t where pk = 0 and ck = 0;
pk | ck | v
----+----+---
(0 rows)
cqlsh> insert into ks.t (pk,ck,v) values (0,0,null);
cqlsh> select * from ks.t where pk = 0 and ck = 0;
pk | ck | v
----+----+------
0 | 0 | null
(1 rows)
スキュラも同じことをします。
ScyllaとCassandra行はcellsのシーケンスです。各列は対応するセル(または非凍結コレクションまたはUDTの場合。ただし、1つの追加の非表示のセルがあります-行マーカー(少なくともScyllaで、私は= Cassandraは同様のものを持っています)。
行マーカーは、他のすべてのセルが無効になっている行に違いをもたらします。行は、少なくとも1つの生きているセルがある場合にのみ、クエリに表示されます。したがって、行マーカーが有効な場合、他のすべての列が以前にnullに設定されていても、その行は表示されます。 update
s。
insert
sはライブ行マーカーを作成しますが、update
sは行マーカーに触れないため、明らかに異なります。上記の例はそれを示しています。行マーカーはCassandra/Scyllaの「内部」にあると主張することもできますが、ご覧のとおり、その効果は目に見えます。行マーカーは、あなたが好きかどうかに関係なくあなたの人生に影響を与えるので、それらについて覚えておくと役に立ちます。
ドキュメントが行マーカーについて言及していないのは残念です(まあ、私はこれを見つけました: https://docs.scylladb.com/architecture/sstable/sstable2/sstable-data-file/#cql-row-marker しかし、それはSSTableの内部を説明するコンテキストにあります。SSTableの内部は、おそらくユーザーよりもScylla開発者に捧げられています)。
ボーナス:aセル削除:
delete v from ks.t where pk = 0 and ck = 0
null
アップデートと同じです:
update ks.t set v = null where pk = 0 and ck = 0
実際、セルの削除も行マーカーには影響しません。指定されたセルをnull
に設定するだけです。
これはrow deleteとは異なります。
delete from ks.t where pk = 0 and ck = 0
行を削除すると、行の墓石が挿入され、行内のすべてのセル(行マーカーを含む)が削除されるためです。行の削除は挿入の反対であると言えます。更新とセルの削除は、その中間にあります。
ただし、これができることは次のとおりです。
UPDATE table_name SET field = false WHERE key = 55 IF EXISTS;
これにより、更新が真の更新であり、アップサートではないことが保証されます。