動作確認バージョンはサーバ/クライアントともに0.7.0
。**(2010/01/12更新)**
Raptanoの記事の写経ですが。
普通のインデックスはカラムのRowキーに対するもので、全てのカラムが持つ。セカンダリインデックスは、カラムの値に対して作られるもの。値での検索がしやすくなる(これまでは転置インデックスのようなものが必要だった)。
セカンダリインデックス作成
カラムファミリを作成する際にメタデータとしてカラム名を設定でき、その時にIndex Type
も指定できる模様。メタデータに設定する値は以下。
キー | 設定値 |
---|---|
column_name | カラム名 |
validation_type | カラム値の型(制限する場合) |
index_type | インデックスの種類 |
この例では、full_name
カラムにはインデックスを作らず、birth_date
カラムにはインデックスを作成している。
[default@unknown] create keyspace demo;
62c689d4-0df2-11e0-b3ea-e700f669bcfc
[default@unknown] use demo;
Authenticated to keyspace: demo
[default@demo] create column family users with comparator=UTF8Type and column_metadata=[{column_name:full_name, validation_class:UTF8Type},{column_name:birth_date, validation_class:LongType, index_type:KEYS}];
b21a9d05-0df2-11e0-b3ea-e700f669bcfc
[default@demo] describe keyspace demo;
Keyspace: demo:
Replication Strategy: org.apache.cassandra.locator.SimpleStrategy
Replication Factor: 1
Column Families:
ColumnFamily: users
Columns sorted by: org.apache.cassandra.db.marshal.UTF8Type
Row cache size / save period: 0.0/0
Key cache size / save period: 200000.0/3600
Memtable thresholds: 0.2953125/63/60
GC grace seconds: 864000
Compaction min/max thresholds: 4/32
Read repair chance: 1.0
Column Metadata:
Column Name: full_name (full_name)
Validation Class: org.apache.cassandra.db.marshal.UTF8Type
Column Name: birth_date (birth_date)
Validation Class: org.apache.cassandra.db.marshal.LongType
Index Type: KEYS
インデックスの種類は0.7.0の段階ではKEYS
しかサポートされていない。ハッシュのキーみたいなものらしい。
bitmap
インデックスが0.7.1からサポートされるとのこと。
何やらそれらしきログが出力されている。
INFO [Create index users.62697274685f64617465] 2010-12-22 23:11:24,344 ColumnFamilyStore.java (line 325) Creating index org.apache.cassandra.db.Table@6239da8a.users.62697274685f64617465
INFO [CompactionExecutor:1] 2010-12-22 23:11:24,383 CompactionManager.java (line 341) Compacted to C:\var\lib\cassandra\data\system\Schema-tmp-e-5-Data.db. 15,751 to 11,562 (~73% of original) bytes for 4 keys. Time: 48ms.
INFO [Create index users.62697274685f64617465] 2010-12-22 23:11:24,384 ColumnFamilyStore.java (line 339) Index users.62697274685f64617465 complete
INFO [Create index users.62697274685f64617465] 2010-12-22 23:11:24,385 ColumnFamilyStore.java (line 639) switching in a fresh Memtable for IndexInfo at CommitLogContext(file='/var/lib/cassandra/commitlog\CommitLog-1293039030618.log', position=24885)
INFO [Create index users.62697274685f64617465] 2010-12-22 23:11:24,386 ColumnFamilyStore.java (line 943) Enqueuing flush of Memtable-IndexInfo@1162212835(41 bytes, 1 operations)
INFO [FlushWriter:1] 2010-12-22 23:11:24,387 Memtable.java (line 155) Writing Memtable-IndexInfo@1162212835(41 bytes, 1 operations)
INFO [FlushWriter:1] 2010-12-22 23:11:24,423 Memtable.java (line 162) Completed flushing \var\lib\cassandra\data\system\IndexInfo-e-1-Data.db (164 bytes)
where句をつけてクエリ実行
セカンダリインデックスを付けたカラムに対してはSQLのようなwhere
句をつけて値を検索できる。
入っているデータは以下
[default@demo] list users;
Using default limit of 100
-------------------
RowKey: nobunaga
=> (column=birth_date, value=1534, timestamp=1293042940549000)
=> (column=blood, value=A, timestamp=1293042957506000)
=> (column=full_name, value=Nobunaga Oda, timestamp=1293042893235000)
-------------------
RowKey: making
=> (column=birth_date, value=1984, timestamp=1293042776114000)
=> (column=blood, value=B, timestamp=1293042734033000)
=> (column=full_name, value=Toshiaki Maki, timestamp=1293042756442000)
-------------------
RowKey: hideyoshi
=> (column=birth_date, value=1537, timestamp=1293042846014000)
=> (column=blood, value=A, timestamp=1293042867208000)
=> (column=full_name, value=Hideyoshi Toyotomi, timestamp=1293042812951000)
検索するのにRowキーではなく、where
句が使える。
[default@demo] get users where birth_date = 1984;
-------------------
RowKey: making
=> (column=birth_date, value=1984, timestamp=1293042776114000)
=> (column=blood, value=B, timestamp=1293042734033000)
=> (column=full_name, value=Toshiaki Maki, timestamp=1293042756442000)
1 Row Returned.
単体での範囲検索まだサポートされていない模様。多分KEYS
インデックスではサポートされない。
[default@demo] get users where birth_date > 1500;
No indexed columns present in index clause with operator EQ
動的にセカンダリインデックス追加
blood
にはインデックスが作られていないので、
[default@demo] get users where blood = 'A';
No indexed columns present in index clause with operator EQ
怒られる。
後からインデックスを追加したい場合はupdate
文でスキーマ更新。
[default@demo] update column family users with comparator=UTF8Type and column_metadata=[{column_name:full_name, validation_class:UTF8Type},{column_name:birth_date, validation_class:LongType, index_type:KEYS},{column_name:blood, validation_class:UTF8Type, index_type:KEYS}];
9225fc2b-0dfb-11e0-b3ea-e700f669bcfc
ちゃんと更新された。
[default@demo] describe keyspace demo;
Keyspace: demo:
Replication Strategy: org.apache.cassandra.locator.SimpleStrategy
Replication Factor: 1
Column Families:
ColumnFamily: users
Columns sorted by: org.apache.cassandra.db.marshal.UTF8Type
Row cache size / save period: 0.0/0
Key cache size / save period: 200000.0/3600
Memtable thresholds: 0.2953125/63/60
GC grace seconds: 864000
Compaction min/max thresholds: 4/32
Read repair chance: 1.0
Column Metadata:
Column Name: full_name (full_name)
Validation Class: org.apache.cassandra.db.marshal.UTF8Type
Column Name: blood (blood)
Validation Class: org.apache.cassandra.db.marshal.UTF8Type
Index Type: KEYS
Column Name: birth_date (birth_date)
Validation Class: org.apache.cassandra.db.marshal.LongType
Index Type: KEYS
これでblood
でも検索できる。
[default@demo] get users where blood = 'A';
-------------------
RowKey: nobunaga
=> (column=birth_date, value=1534, timestamp=1293042940549000)
=> (column=blood, value=A, timestamp=1293042957506000)
=> (column=full_name, value=Nobunaga Oda, timestamp=1293042893235000)
-------------------
RowKey: hideyoshi
=> (column=birth_date, value=1537, timestamp=1293042846014000)
=> (column=blood, value=A, timestamp=1293042867208000)
=> (column=full_name, value=Hideyoshi Toyotomi, timestamp=1293042812951000)
2 Rows Returned.
あるカラムに対して=
検索が入っていれば他のカラムの範囲検索が使える。
[default@demo] get users where birth_date > 1535 and blood = 'A';
-------------------
RowKey: hideyoshi
=> (column=birth_date, value=1537, timestamp=1293042846014000)
=> (column=blood, value=A, timestamp=1293042867208000)
=> (column=full_name, value=Hideyoshi Toyotomi, timestamp=1293042812951000)
1 Row Returned.
ただし、KEYS
インデックスはハッシュのキーみたいなものであり、btree
ではないため、パフォーマンスは多分良くない。
Oreilly & Associates Inc
売り上げランキング: 20382