ycql について
ycqlは、YugabyteDB YCQLのベストプラクティスをまとめたデータベース開発者向けスキルです。スキーマ設計、クエリ最適化、運用設定を扱います。
主な機能
- 01パーティションキーとクラスタリング列の設計
- 02グローバル・カバリングインデックスの指針
- 03データ型とサイズ制限
- 04TTLと一貫性レベルの解説
- 05クエリ、バッチ、リトライの最適化
- 06大規模テーブルのスキャンと整理
活用シーン
- 01注文テーブルなどの分割と並び順を設計
- 02一般的なクエリに適したインデックスや文を選択
- 03データの有効期限と読み取り一貫性を設定
- 04バッチ処理や大規模テーブルのスキャンを最適化
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ yugabyte/ yugabytedb-skills --skill ycqlインストール後、Claude Code で/ycqlを入力して読み込まれたか確認します。
詳細
YugabyteDB YCQL のベストプラクティス
YCQL は YugabyteDB の Cassandra 互換 API(ポート 9042)です。強い一貫性(ACID)を備えたグローバルセカンダリインデックスを提供します。これは Apache Cassandra に対する重要な優位点です。
スキーマ設計
パーティションキーとクラスタリング列
データを均等に分散させるパーティションキーと、パーティション内で効率的に範囲スキャンを実行できるクラスタリング列を設計します。
CREATE TABLE orders (
customer_id UUID,
order_date TIMESTAMP,
order_id UUID,
total DECIMAL,
PRIMARY KEY ((customer_id), order_date DESC, order_id)
) WITH CLUSTERING ORDER BY (order_date DESC, order_id ASC);
- パーティションキー(
customer_id):タブレットの配置を決定します。データが均等に分散されるように選択してください。 - クラスタリング列(
order_date、order_id):パーティション内のソート順を決定します。
グローバルセカンダリインデックス
YugabyteDB の YCQL セカンダリインデックスは、Cassandra のローカルインデックスとは異なり、グローバルで強い一貫性(ACID)を備えています。
CREATE INDEX idx_orders_date ON orders (order_date);
カバリングインデックス
INCLUDE 句を使うと、テーブルを参照せずにインデックスから直接クエリに応答できます。
CREATE INDEX idx_orders_customer ON orders (customer_id) INCLUDE (total, order_date);
一意インデックス
CREATE UNIQUE INDEX idx_users_email ON users (email);
データ型
- JSONB: スキーマレスデータでサポートされていますが、本当に動的な値にのみ使用してください。頻繁にアクセスするパターンでは、通常の列のほうが JSONB よりも高いパフォーマンスを発揮します。
- カウンターの増減: YugabyteDB は CAS 操作を使用した整数の増減を、単一の Raft ラウンドトリップでサポートします(Apache Cassandra では 4 回)。
- コレクション: 小規模なデータセット向けに設計してください。大規模なコレクションはパフォーマンスに大きな影響を与えます。
サイズ制限
- 列: 2 MB 程度以下に抑えてください
- 行: 32 MB 程度以下に抑えてください
TTL(有効期間)
テーブル、行、列の各レベルでデータを自動的に期限切れにできます。
-- Table-level TTL
CREATE TABLE events (
id UUID PRIMARY KEY,
data TEXT
) WITH default_time_to_live = 86400; -- 24 hours
-- Row-level TTL on insert
INSERT INTO events (id, data) VALUES (uuid(), 'event data') USING TTL 3600;
-- Column-level TTL
UPDATE events USING TTL 7200 SET data = 'updated' WHERE id = ?;
注: トランザクションテーブルでは TTL はサポートされていません。
一貫性レベル
YugabyteDB YCQL がサポートする一貫性レベルは QUORUM(デフォルト)と ONE の 2 つだけです。書き込みは常に強い一貫性(QUORUM)を備えています。最寄りのレプリカから古いデータを低レイテンシで読み取るフォロワー読み取りには、ONE を使用してください。
// Default: QUORUM (strong consistency)
Statement stmt = SimpleStatement.newInstance("SELECT * FROM orders WHERE customer_id = ?", id)
.setConsistencyLevel(ConsistencyLevel.ONE); // Read from nearest replica (may be stale)
ライトウェイトトランザクション(アトミックな読み取り・変更・書き込み)
IF EXISTS/IF NOT EXISTS 操作は Apache Cassandra よりもはるかに高速です。Raft ラウンドトリップは 1 回で済み、LWT のラウンドトリップは 4 回です。
-- Atomic insert-if-not-exists
INSERT INTO users (id, email, name) VALUES (?, ?, ?) IF NOT EXISTS;
-- Atomic conditional update
UPDATE accounts SET balance = ? WHERE id = ? IF balance >= ?;
クエリの最適化
プリペアドステートメント(常に使用)
プリペアドステートメントを使うと、パーティションを考慮したルーティングが可能になります。ドライバーがパーティションハッシュを計算し、クエリを正しいタブレットリーダーに直接送信します。
PreparedStatement ps = session.prepare("SELECT * FROM orders WHERE customer_id = ?");
BoundStatement bs = ps.bind(customerId);
session.execute(bs);
バッチ処理
バッチ操作では、すべての操作を 1 回の RPC 呼び出しで送信します。
BatchStatement batch = BatchStatement.newInstance(DefaultBatchType.UNLOGGED);
batch = batch.add(ps1.bind(...));
batch = batch.add(ps2.bind(...));
session.execute(batch);
最高のパフォーマンスを得るには、同じパーティションを対象とする操作をまとめてバッチ処理してください。
コネクションプーリング
接続の管理には、単一のクラスタオブジェクトを使用してください。通常、64~128 スレッドの場合、YB-TServer ごとに 1~2 個の接続で十分です。プリペアドステートメントを使用すると、ドライバーがトークンを考慮したルーティングを自動的に処理します。
リトライポリシー
デフォルトのリトライポリシーでは、特定の障害が発生した場合に 1 回再試行します。書き込み負荷の高いワークロードでは、負荷分散中に発生する一時的なタブレットリーダーの変更に対応できるよう、バックオフを備えたカスタムリトライポリシーを設定してください。
大規模テーブルの操作
partition_hash を使用して、タブレット間でスキャンを並列化します。
SELECT * FROM large_table WHERE partition_hash(id) >= 0 AND partition_hash(id) < 5000;
SELECT * FROM large_table WHERE partition_hash(id) >= 5000 AND partition_hash(id) < 10000;
TRUNCATE と DELETE の比較
TRUNCATE は DELETE よりもはるかに高速です。DELETE はマーカー(トゥームストーン)を挿入するため、コンパクションが必要になります。テーブル全体をクリーンアップする場合は TRUNCATE を使用してください。
メモリ設定
YCQL のみのデプロイでは、PostgreSQL レイヤー用のメモリの予約を避けるため、yb-master で --use_memory_defaults_optimized_for_ysql=false を設定してください。