Cassandra クエリ言語(CQL):挿入、更新、削除

⚡ スマートサマリー

Cassandra クエリ言語は、挿入、更新、削除、読み取り操作をSQLに近い構文で処理しますが、内部的には異なる意味論に基づいています。このページでは、各ステートメント、挿入と更新を統合するupsertの動作、およびWHERE句の実際の制限について説明します。

  • 動作を挿入する: 主キーのみが必須であり、省略された列はストレージを消費しません。
  • 🔄 アップサートのセマンティクス: 挿入と更新は同じ操作なので、既存のキーを書き込むと、自動的に上書きされます。
  • 🗑️ 削除費用: 削除された行は墓石となり、圧縮処理が実行された後にのみ消滅する。
  • 🔍 条項の制限事項: フィルタリングは、主キー列に対して機能するほか、インデックスが存在する場合は他の列に対しても機能します。
  • 📊 総合的なサポート: カウント、最小値、最大値、合計、 AVG GROUP BYもサポートされていますが、効率的に動作するのは1つのパーティション内のみです。
  • 🚫 まだサポートされていません: 結合、OR条件、およびパーティション間分析は、設計上、CQLの対象外となっています。

Cassandra CQL挿入更新削除

データの挿入

その Cassandra insert ステートメントはデータを書き込みます Cassandra 行形式の列。 Cassandra 挿入クエリは、ユーザーによって指定された列のみを保存します。必ず主キー列のみを指定する必要があります。

指定されていない値のためのスペースは必要ありません。 挿入後に結果は返されません。

構文

INSERT INTO KeyspaceName.TableName (ColumnName1, ColumnName2, ColumnName3)
VALUES (Column1Value, Column2Value, Column3Value);

例:

これが実行されたスナップショットです Cassandra 1 つのレコードを挿入するテーブルクエリに挿入します。 Cassandra テーブル「学生」。

データの挿入

INSERT INTO University.Student (RollNo, Name, dept, Semester)
VALUES (2, 'Michael', 'CS', 2);

コマンドが正常に実行された後、Insert into Cassandraに 1 行が挿入されます。 Cassandra 表 ロール番号 2 の学生、名前はマイケル、部門 CS、学期 2。

これは、現在のデータベース状態のスナップショットです。

データの挿入

データの更新/挿入

Cassandra アップサートを行います。アップサートとは次のことを意味します Cassandra 主キーがまだ存在しない場合は行を挿入し、主キーがすでに存在する場合はその行を更新します。

これには、明確に述べておくべき実用的な結果があります。INSERT文では重複キーエラーが報告されないため、誤って再挿入すると、警告なしに既存の行が上書きされてしまいます。これを防ぐ必要がある場合は、IF NOT EXISTS文を追加して、ステートメントを軽量なトランザクションにしてください。

INSERT INTO University.Student (RollNo, Name)
VALUES (2, 'Michael') IF NOT EXISTS;

軽量トランザクションはレプリカ間でコンセンサスラウンドを使用するため、通常の書き込みよりもかなり遅く、真にチェックが必要な場合にのみ使用すべきです。

Update Data

その Cassandra 更新クエリは、 Cassandra テーブルデータの更新後に結果が返されない場合は、データが正常に更新されたことを意味します。そうでない場合は、エラーが返されます。列の値は 'Set' 句で変更され、データは 'Where' 句でフィルター処理されます。

構文

UPDATE KeyspaceName.TableName
SET ColumnName1 = NewValue1,
    ColumnName2 = NewValue2
WHERE ColumnName = ColumnValue;

例:

以下は、データを更新する前のデータベースの状態を示すスクリーンショットです。

Update Data

これが実行されたスナップショットです Cassandra Student テーブルのレコードを更新する Update コマンド。

Update Data

UPDATE University.Student
SET name = 'Hayden'
WHERE rollno = 1;

で更新クエリが正常に実行された後、 Cassandra 「学生を更新」すると、学生名が「Clark」からロール番号 1 の「Hayden」に変更されます。

データ更新後のデータベースの状態を示すスクリーンショットは次のとおりです。

Update Data

upsert の動作により、存在しない主キーに対する UPDATE は、失敗するのではなく行を作成します。

Cassandra データの削除

コマンド「削除」は、テーブル Student から行全体または一部の列を削除します。 データが削除されても、テーブルからすぐには削除されません。 代わりに、削除されたデータには廃棄マークが付けられ、圧縮後に削除されます。

構文

DELETE FROM KeyspaceName.TableName
WHERE ColumnName1 = ColumnValue;

上記 Cassandra delete row 構文は、where 句のデータ フィルタリングに応じて 1 つ以上の行を削除します。

DELETE ColumnName1, ColumnName2 FROM KeyspaceName.TableName
WHERE ColumnName1 = ColumnValue;

上記の構文はテーブルからいくつかの列を削除します。

例:

以下は、データを削除する前の現在のデータベースの状態を示すスナップショットです。

Cassandra データの削除

以下は、Student テーブルから XNUMX 行を削除するコマンドのスナップショットです。

Cassandra データの削除

DELETE FROM University.Student WHERE rollno = 1;

CQLの削除コマンドが正常に実行されると、rollnoの値が1であるStudentテーブルから1行が削除されます。

以下は、データ削除後のデータベースの状態を示すスナップショットです。

Cassandra データの削除

削除対象を示すマーカーは、デフォルトでは10日間、gc_grace_secondsの間保持されるため、削除処理中にオフラインになったノードが復帰しても、削除対象の行を復元することはできません。したがって、大量のデータを削除すると、後続の読み取り処理で必ず通過しなければならないマーカーが残ります。

この試験は Cassandra サポートしていません。

CQLはSQLの構文を借用していますが、リレーショナルな実行モデルは採用していないため、お馴染みの構文のいくつかは動作が異なったり、存在しなかったりします。

  1. CQLはテーブル間の結合をサポートしていません。関連データは書き込み時に1つのテーブルに非正規化する必要があります。
  2. CQLでは、WHERE句でOR条件をサポートしていません。単一の列に対してIN条件を使用するか、個別のクエリを実行してください。
  3. CQLはUNIONやINTERSECTをサポートしていません。
  4. 主キー以外の列は、インデックスが作成されるまでフィルタリングできません。
  5. 大小比較はクラスタリング列にのみ適用されます。なぜなら、ディスク上でソートされるのはクラスタリング列のみだからです。
  6. LIKE句を用いたパターンマッチングにはSASIインデックスが必要であり、通常の列では使用できません。

長年の定説の一つを訂正する必要がある。集計関数はサポートされている。 カウント、最小値、最大値、合計、 AVG 到着した Cassandra 2.2、 グループ化 バージョン3.10で実装されました。ただし、これは利用可能性というよりは、適用範囲に関する注意点です。

SELECT dept, COUNT(*) FROM University.Student
WHERE RollNo = 1 GROUP BY dept;

上記のように単一のパーティションに限定すれば、集約は効率的です。テーブル全体で実行するとクラスタ全体のスキャンになるため、 Cassandra アドホック分析には不向きであり、そのため、通常、大規模なレポート作成は Spark または外部倉庫。

Cassandra Where句

In Cassandra、データの取得はデリケートな問題です。列は次でフィルタリングされます Cassandra 非主キー列にインデックスを作成することによって。

構文

SELECT ColumnNames FROM KeyspaceName.TableName
WHERE ColumnName1 = Column1Value
  AND ColumnName2 = Column2Value;

例:

  • 以下は、データ フィルタリングを行わない Student テーブルからのデータ取得を示すスナップショットです。

Cassandra Where句

SELECT * FROM University.Student;

Student テーブルから XNUMX つのレコードが取得されます。

  • 以下は、データ フィルタリングを使用した Student からのデータ取得を示すスナップショットです。 XNUMX つのレコードが取得されます。

データは名前列でフィルタリングされます。名前が等しいすべてのレコードが取得されます。 Guru99.

Cassandra Where句

SELECT * FROM University.Student WHERE name = 'Guru99';

WHERE句が参照できる列を規定するルールは、主キーから直接導き出されます。

  • その パーティションキー 効率的なクエリを実行するには、データを保持するノードを識別するため、この情報を完全に提供する必要があります。
  • Clusterコラム その後制限される可能性がありますが、宣言された順序でのみ制限されます。スキップping 1つは却下された。
  • 範囲比較は、参照された最後のクラスタリング列に対してのみ許可され、それ以前の列に対しては許可されません。
  • 任意 その他の列 二次索引が必要で、 インデックスの作成と削除 チュートリアル。

クエリが拒否された場合、 Cassandra ALLOW FILTERING を追加するように提案されることがよくあります。これは修正ではなく警告として扱ってください。すべてのノードのすべてのパーティションをスキャンするため、スキーマの変更がほぼ常に正しい対応策となります。

よくあるご質問

バッチ処理はステートメントをグループ化し、それらが同時に成功または失敗するようにします。重複するテーブルの同期を保つために使用し、複数のパーティションにまたがる一括ロードには使用しないでください。一括ロードでは、バッチ処理によってコーディネーターの処理速度が著しく低下します。

ドライバーはページング状態トークンを使用して自動的にページングします。cqlsh では、PAGING でサイズを設定します。カウンターで OFFSET をエミュレートすることは避けてください。 Cassandra 効率的な行スキップ機能はありませんping 機構。

レプリカがgc_grace_secondsよりも長く停止していて、かつトゥームストーンが既に圧縮されている場合、そのレプリカは古い行を保持したまま、それを再び展開します。定期的な修復はこれを防ぎます。

単純な単一テーブル選択はうまく変換できます。結合、OR、またはサブクエリを含むものには、CQL に直接対応するものがなく、AI はしばしば ALLOW FILTERING でそのギャップを埋めようとしますが、これは解決策ではありません。

はい。貼り付け TRACING ON の出力では、通常、トゥームストーン スキャン、ワイド パーティション、またはノード間ホップに関する明確な情報が得られます。提案されたスキーマ変更を適用する前に、コピーでその変更を確認してください。