データベースの定義

インストール手順は、Cassandraのインストール を参考のこと。 また、 Apache Cassandraの公式ページ も参照すること。動作環境は、インストール環境と同じく以下の通りである。

[バージョン]

  • cqlsh 5.0.1
  • Cassandra 3.7
  • CQL spec 3.4.2
  • Native protocol v4

CQLで格納されたデータは、テーブルによりその構造が決定され、キースペースによりグルーピングされる。キースペースでは、全てのテーブル定義に対し適用される多くのオプションの定義や、レプリケーション戦略を決定する。

共通定義

キースペース及びテーブルは以下の文法により記述される。

keyspace_name ::=  name
table_name    ::=  [ keyspace_name '.' ] name
name          ::=  unquoted_name | quoted_name
unquoted_name ::=  re('[a-zA-Z_0-9]{1, 48}')
quoted_name   ::=  '"' unquoted_name '"'

キースペースとテーブル名は、空白を含まない、48文字以内の英数字のみで構成される必要がある。大文字小文字は区別はないが、ダブルクォートで囲むと大文字小文字区別する。テーブルはキースペースにより区別される必要があるが、指定しない場合、カレントで指定されているキースペースが使用される。

キースペース・テーブルの作成

CREATE KEYSPACE ステートメント

キースペースは、以下の構文のCREATE KEYSPACEステートメントにより作成される。

create_keyspace_statement ::=  CREATE KEYSPACE [ IF NOT EXISTS ] keyspace_name WITH options

オプションは、以下が選択できる。

CREATE KEYSPACEのオプション
オプション名 形式 必須 デフォルト値 詳細
replication マップ   キースペースのレプリケーション戦略。
replicationプロパティには”class”属性で、
レプリケーションクラス名を指定する。
durable_writes boolean × true キースペース内での更新にコミットログを
使用するか否か。

Note

アプリケーションごとに複数のキースペースを作成するのは可能であるが、あまり推奨されない。後述するレプリケーションファクタを絡むごとに分離したい場合などがあげられる。キースペースは、リレーショナルデータベースでいうところのデータベースに近い位置づけなので、直感的にアプリケーションで複数のデータベースに接続しない方が良い理由は直感的にも分かるだろう。

レプリケーション戦略
レプリケーション戦略クラス 詳細
SimpleStrategy クラスター全体のレプリケーションファクタを
定義する戦略。replication_factorのみが
定義可能である。
NetworkTopologyStrategy それぞれのデータセンターで独立してレプリケーションファクタを
設定する戦略。サブオプションの残りは、データセンタ名と、
レプリケーションファクタを指定する。

Note

レプリケーションファクタは各Rowがもつデータの複製を幾つのノードに行き渡させるかを決定する。レプリケーションファクタが3であれば、各Rowはリング上の3つのノードに複製される。レプリケーションの種類や配置戦略を別途 レプリケーション戦略 参考にすること。

ターミナルコマンドからcqlshを起動し、キースペースを作成する。

cqlsh localhost 9042

cqlsh> CREATE KEYSPACE sample WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 1};

cqlsh> describe keyspaces;

system_schema  system_auth  system  sample  system_distributed  system_traces

なお、上記のdescribeステートメントの詳細は、 DESCRIBE ステートメント を参照のこと。

USE ステートメント

USEステートメントは、現在のキースペースを切り替えるために、以下の構文で使用される。

use_statement ::=  USE keyspace_name

実行例は以下の通りである。

cqlsh> USE sample;

ALTER KEYSPACE ステートメント

ALTER KEYSPACEステートメントはキースペースの定義を変更するために、以下の構文で使用される。

alter_keyspace_statement ::=  ALTER KEYSPACE keyspace_name WITH options

実行例は以下の通りである。

cqlsh> ALTER KEYSPACE sample WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 4};

DROP KEYSPACE ステートメント

DROP KEYSPACEステートメントはキースペースを削除するために、以下の構文で使用される。

drop_keyspace_statement ::=  DROP KEYSPACE [ IF EXISTS ] keyspace_name

実行例は以下の通りである。

cqlsh> DROP KEYSPACE sample;

CREATE TABLE ステートメント

キースペースは、以下の構文の通り、CREATE TABLEステートメントにより作成される。

create_table_statement ::=  CREATE TABLE [ IF NOT EXISTS ] table_name
                         '('
                             column_definition
                             ( ',' column_definition )*
                             [ ',' PRIMARY KEY '(' primary_key ')' ]
                         ')' [ WITH table_options ]
column_definition      ::=  column_name cql_type [ STATIC ] [ PRIMARY KEY]
primary_key            ::=  partition_key [ ',' clustering_columns ]
partition_key          ::=  column_name
                             | '(' column_name ( ',' column_name )* ')'
clustering_columns     ::=  column_name ( ',' column_name )*
table_options          ::=  COMPACT STORAGE [ AND table_options ]
                         | CLUSTERING ORDER BY '(' clustering_order ')' [ AND table_options ]
                         | options
clustering_order       ::=  column_name (ASC | DESC) ( ',' column_name (ASC | DESC) )*

利用可能なデータ型は以下の通りである。

テーブルのデータ型
データ型 概要
ascii US-ASCII文字列
bigint 64bitLong型数値
blob 16進数で表記される任意のバイト
boolean True or False
counter 64bit型数値の累計
decimal 正確なDecimal型数値
double 64bit IEEE-754 Float数値
float 32bit IEEE-754 Float数値
inet IPv4 あるいはIPv6のIPアドレスを表す文字列
int 32bitint型数値
list 1つ以上の整列された要素
map JSON表記された文字列の連想配列
set 重複のない1つ以上の整列された要素
text UTF8エンコードされた文字列
timestamp 8byteで表現されたDateTime
uuid UUIDフォーマット
timeuuid Type 1 UUID
varchar UTF8エンコード文字列
varint 正確なint

実行例は以下の通りである。

cqlsh> CREATE TABLE monkeySpecies (
           species text PRIMARY KEY,
           common_name text,
           population varint,
           average_size int
       ) WITH comment='Important biological records'
       AND read_repair_chance = 1.0;

cqlsh> CREATE TABLE timeline (
           userid uuid,
           posted_month int,
           posted_time uuid,
           body text,
           posted_by text,
           PRIMARY KEY (userid, posted_month, posted_time)
       ) WITH compaction = { 'class' : 'LeveledCompactionStrategy' };

cqlsh> CREATE TABLE loads (
           machine inet,
           cpu int,
           mtime timeuuid,
           load float,
       PRIMARY KEY ((machine, cpu), mtime)
       ) WITH CLUSTERING ORDER BY (mtime DESC);

Note

上記の構文で、static修飾子は同一のパーティション内(同一のパーティションキーを持つ)で共有される値である。

static修飾された値は、値が共有されるので更新時には注意が必要である。下記の例では、static定義された”s”が共有されており、1番目のデータが後からINSERTされた2番目のデータに上書きされる例である。

cqlsh> CREATE TABLE t (
           pk int,
           t int,
           v text,
           s text static,
           PRIMARY KEY (pk, t)
      );

cqlsh> INSERT INTO t (pk, t, v, s) VALUES (0, 0, 'val0', 'static0');
cqlsh> INSERT INTO t (pk, t, v, s) VALUES (0, 1, 'val1', 'static1');
cqlsh> SELECT * FROM t;

  pk | t | v      | s
"----+---+--------+-----------"
  0  | 0 | 'val0' | 'static1'
  0  | 1 | 'val1' | 'static1'

static定義されたカラムは以下の制約をもつ。

  • COMPACT STORAGEオプションを選択したテーブルはstatic属性を利用できない。
  • staticなカラムを持つことが出来ない、クラスタカラムなしのテーブル。
  • PRIMARYキーを除くカラムのみがstatic定義できる。

Note

上記の構文において、テーブルのデータは必ず一意のパーティションキーを持つ。パーティションキーは、どのノードで、データを保持、処理するのかを決定し、パーティションキーによってノードが決定した行をパーティションと呼ぶ。パーティション内には、複数の行を持つ場合があり、これらを一意に識別するのがプライマリーキーである。プライマリーキーは、パーティションキー単独の場合(パーティション内に1つの行しかない場合)と、パーティションキー+クラスタカラムで構成される場合(パーティション内に複数の行が存在し、クラスタごとに保持するデータがそれぞれの行で異なる場合)の2ケースが存在する。

プライマリーキーの表現方法は、

  • PRIMARY KEY (a) : aはパーティションキーでもあり、クラスタカラムはない。
  • PRIMARY KEY (a, b, c) : aはパーティションキーであり、bとcはクラスタカラムである。
  • PRIMARY KEY ((a, b), c) : aとbは複合パーティションキーと呼び、cはクラスタカラムである。

以下の例は、row1とrow2のデータが同じパーティション、row3とrow4が同じパーティションに属する。ただし、row3とrow4は配置されたクラスタが異なる。

cqlsh> CREATE TABLE t (
           a int,
           b int,
           c int,
           d int,
           PRIMARY KEY ((a, b), c, d)
       );

 cqlsh> SELECT * FROM t;

   a | b | c | d
 "---+---+---+---"
   0 | 0 | 0 | 0    // row 1
   0 | 0 | 1 | 1    // row 2
   0 | 1 | 2 | 2    // row 3
   0 | 1 | 3 | 3    // row 4
   1 | 1 | 4 | 4    // row 5

また、パーティションキーが同じであれば、レプリカ内にも同じデータセットで格納されていることをするが、クラスタカラムでは、レプリカセット内で行がどのように保存されるかを制御するために利用される。ソートされることで、SELECT * FROM t WHERE a = 0 AND b = 0 And c > 1 and c <= 3 のように、効率的なデータ検索に役立つ。

テーブルオプションはWITHキーワードを使用して指定するが、COMPACT STORAGEオプションと、CLUSTERING ORDERオプションについては、生成後に変更が出来ないことと、実行されるクエリに影響があるため注意が必要である。

テーブルオプションの注意点
オプション 概要
COMPACT STOAGE 複合PRIMARYキーを使用してデータを作成する場合は、
キー以外の項目は1つの行データにまとめるオプション。
このオプションを採用すると以下の制約が課せられる。

1.コレクションやstatic定義カラムを使用することは出来ない。
2.少なくともクラスタカラムを持ち、PRIMARYキーの外側に
少なくとも1つのカラムが必要である。これはテーブル生成後に、
追加したり削除することは出来ない。
3.作成されたインデックスに制約があり、マテリアライズドビューは
使用できない。
CLUSTERING ORDER クラスタカラムのデータの並び順を昇順から降順に変更するオプション。
このオプションを採用すると、以下の制約が課せられる。

1.テーブルにSELECTを実行した際のORDER順が変更される。
2.ORDER BYオプションを指定しなければ、CLUSTERING ORDERで
定義されたデータは返却される。
3.逆順の定義は幾つかのクエリにおいて、若干のパフォーマンス低下を
引き起こす。

その他、以下のテーブルオプションをサポートする。

CREATE TABLEのその他のオプション
オプション名 形式 デフォルト 詳細
comment 文字列 none フリーフォーマットの手書きコメント
read_repair_chance 数値 0.1 Read_Repairのために、他のノードへクエリを送信する割合
求められる一貫性レベル以上のノード数に従って指定する。
dclocal_read_repair_chance 数値 0 同一データセンタにおけるレプリカへのread_repair_chance
gc_grace_seconds 数値 864000 サーバがトゥームストーンのガーベージコレクションを待つ時間
シングルノードクラスタは安全に0を設定できる。
bloom_filter_fp_chance 数値 0.00075 SSTableのブルームフィルタ誤検出(False Positive)の確率
この値で、メモリ上、ディスク上のフィルタのサイズが決定される。
default_time_to_live 数値 0 テーブルのデフォルトの有効期限。制御がないときに
MapReduce/Hiveシナリオで使用される。
compaction マップ 下表参照 コンパクションのオプション。
compression マップ 下表参照 コンプレッションのオプション。
caching マップ 下表参照 キャッシュオプション。

オプションをデフォルトにした場合の例は以下の通りである。

CREATE TABLE sample.users (
    user_id bigint PRIMARY KEY,
    first_name text,
    last_name text,
    user_name text
) WITH bloom_filter_fp_chance = 0.01
    AND caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'}
    AND comment = ''
    AND compaction = {'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold': '32', 'min_threshold': '4'}
    AND compression = {'chunk_length_in_kb': '64', 'class': 'org.apache.cassandra.io.compress.LZ4Compressor'}
    AND crc_check_chance = 1.0
    AND dclocal_read_repair_chance = 0.1
    AND default_time_to_live = 0
    AND gc_grace_seconds = 864000
    AND max_index_interval = 2048
    AND memtable_flush_period_in_ms = 0
    AND min_index_interval = 128
    AND read_repair_chance = 0.0
    AND speculative_retry = '99PERCENTILE';

Note

Read Repairとは、読み込み時に各レプリカでデータに違いがあった場合、
最新のデータでレプリカを修復することである。修復はバッググラウンドで行われる。

Note

トゥームストーンは、RDBにおいて、削除のSQLを実行する代わりに、削除を定義されたカラムを更新する「論理削除」と同様の仕組みを実現するための目印に相当する。Cassandraでは、削除操作を実行しても、SSTableのコンパンクションが実行されるまで実際の削除操作は保留されるが、削除までの間、トゥームストーンが削除マーカーとして保持される。詳細は DATASTAXの削除について を参照すること。

この概念を理解するための、重要なポイントとしては、データ削除が行われる場合、レプリカが1つでもダウンしていると、削除が反映されず、レプリカ復帰時に、復帰したレプリカへのアクセスが発生すると、Read Repairによって、削除したはずのデータが復元してしまう可能性があることだ。そのため、ノード間のデータ不整合が発生した場合、トゥームストーンの有無により削除の要否を判断する。基本的にはトゥームストーンがあった場合、削除が優先される。トゥームストーンのデフォルトの設定は864000秒、すなわち10日である。実際の削除はSSTableのコンパクション時となるが、コンパクションの戦略によっては実際にデータ削除されるタイミングが長期に可能性があるので、必要に応じてデフォルトのコンパクション戦略を見直すこと。なお、この時間を過ぎて復旧できなかったノードは障害発生または交換が必要なノード対象となる。

Note

SSTableブルームフィルタとは、指定されたキーがSSTable内のデータに含まれているかを検査するための高速な非決定性アルゴリズムで、パフォーマンス向上のために使用される。

コンパクションのオプションは、’class’属性に以下のクラスを指定する必要がある。

コンパクションの戦略
オプション名 詳細
SizeTieredCompactionStrategy デフォルトのコンパクションストラテジ。min_thresholdで指定された
ファイルの個数を閾値として、同じサイズのファイルが上限を超えるとSSTableの
マイナーコンパクションが発生する。
LeveledCompactionStrategy 固定されたサイズのSSTableを格納する領域をレベルごとに分類し、
SSTableが作成されるごとに 順次下のレベルから占有させていき、
レベル単位でデータのマージを行う戦略。
データ検索時にはレベルごとにマージされたSSTableを検索する。
TimeWindowCompactionStrategy データのタイムスタンプにより、ウィンドウと呼ばれる単位で1ファイルにつき
1つのSSTableを割当て、コンパクションを実行する戦略
DateTieredCompactionStrategy 非推奨、代わりにTimeWindowCompactionStrategyの使用を推奨。

Note

コンパクションには、メジャーコンパクションとマイナーコンパクションが存在する。 マイナーコンパクションは複数のSSTableを1つにまとめるもので、メジャーコンパクションは 全てのSSTableを1つにまとめるものである。

コンプレッションのオプションは、SSTableの圧縮方法を指定するもので、以下が利用可能である。

コンプレッションのオプション
オプション名 デフォルト 詳細
class LZ4Compressor 圧縮アルゴリズムを指定する。その他、
SnappyCompressorとDeflateCompressorを選択できる。
enabled true SSTableの圧縮可否
chunk_length_in_kb 64KB SSTableの圧縮のブロックサイズを定義する。
より大きい方が圧縮率はよいが、読み出しのデータサイズが増加する。
crc_check_chance 1.0 ブロックに含まれるチェックサムをチェックする割合

キャッシュオプションはテーブルのキーとRowのキャッシュを定義する。

キャッシュオプション
オプション名 デフォルト 詳細
keys ALL テーブルのキャッシュを行うかどうかをALLorNONE指定。
rows_per_partition NONE パーティションにつきキャッシュする行の量。
Integer型のNを指定すると、パーティションのクエリ行から取得した
N行のクエリがキャッシュされる。その他ALLorNONEを指定可能。

ALTER TABLE ステートメント

存在済みのテーブルの変更を加えるのは、以下のALTER TABLEステートメントを利用する。

alter_table_statement   ::=  ALTER TABLE table_name alter_table_instruction
alter_table_instruction ::=  ALTER column_name TYPE cql_type
                             | ADD column_name cql_type ( ',' column_name cql_type )*
                             | DROP column_name ( column_name )*
                             | WITH options

以下は実行例である。

cqlsh> ALTER TABLE addamsFamily ALTER lastKnownLocation TYPE uuid;

cqlsh> ALTER TABLE addamsFamily ADD gravesite varchar;

cqlsh> ALTER TABLE addamsFamily
       WITH comment = 'A most excellent and useful table'
       AND read_repair_chance = 0.2;

ALTER TABLE構文では、以下が可能である。

  • ALTER命令で、テーブル内のカラムの型を変更できる。カラムの型は簡単に変更できるものではない。型の変更は以前の型から新しい型へ有効なデータである必要がある。加えて、クラスタカラムでは、セカンダリインデックスが定義されているため、新しい型も以前の型と同様にソートされる必要がある。型の競合は以降を参照すること。
  • ADD命令で、テーブルへ新しいカラムを追加できる。PRIMARYキーは変更できないので、新しく追加したカラムをその一部に組み込むことはできない。同様にCOMPACT STORAGEオプションを付与しているテーブルはカラムの追加は制限される。
  • REMOVE命令でテーブル内のカラムを削除できる。定義とデータ両方削除されるが、定義は即時で利用不能になるのに対して、データはコンパクション後に削除される。
  • WITH句でテーブルオプションを変更できる。サポートオプションはCREATE時と同様だが、前述の通り、COMAPACT STORAGEオプションと、CLUSTERING ORDERは変更できない。コンパクションのオプションは以前のコンパクションを削除する影響があるので注意。コンプレッションオプションも同様。
ALTER TABLE時の型の競合
変換前の型 変更可能な型
timestamp bigint
ascii, bigint, boolean, date, decimal, double,
float, inet, int, smallint, text, time, timestamp,
timeuuid, tinyint, uuid, varchar, varint
blob
int date
ascii, varchar text
bigint time, timestamp
timeuuid uuid
ascii, text varchar
bigint, int, timestamp varint

クラスタカラムにおいては、以下の変更のみが許容される。

クラスタカラム変更時の制約
変換前の型 変更可能な型
ascii, text, varchar blob
ascii, varchar text
ascii, text varchar

DROP TABLE ステートメント

存在済みのテーブルを削除するには、以下のDROP TABLEステートメントを利用する。

drop_table_statement ::=  DROP TABLE [ IF EXISTS ] table_name

テーブルの削除に伴い、データも同時に削除される。

TRUNCATEステートメント

存在済みのテーブル内のデータを削除するには、以下のDROP TABLEステートメントを利用する。

truncate_statement ::=  TRUNCATE [ TABLE ] table_name

DESCRIBE ステートメント

describeステートメントの構文及びオプションである。

DESCRIBE FULL( CLUSTER | SCHEMA )
| KEYSPACES
| ( KEYSPACE keyspace_name )
| TABLES
| ( TABLE table_name )
| TYPES
| ( TYPES user_defined_type )
describeコマンドの利用例
コマンド 実行結果
cqlsh> describe cluster; Cluster: Test Cluster
Partitioner: Murmur3Partitioner
cqlsh> describe keyspaces; system_schema system_auth system sample system_distributed system_traces