Apache Cassandraで定義できるデータモデルとして、スーパーカラムなるものがあります。
http://wiki.apache.org/cassandra/DataModel
が、オライリー本でもさらっとしか触れられていませんし

- 作者: Eben Hewitt,大谷晋平,小林隆
- 出版社/メーカー: オライリージャパン
- 発売日: 2011/12/24
- メディア: 大型本
- 購入: 1人 クリック: 170回
- この商品を含むブログ (7件) を見る

Cassandra実用システムインテグレーション (NEXT-ONE)
- 作者: 中村寿一,長田伊織,谷内隼斗,藤田洋,森井幸希,岸本康二
- 出版社/メーカー: 翔泳社
- 発売日: 2013/01/16
- メディア: 大型本
- 購入: 2人 クリック: 8回
- この商品を含むブログ (3件) を見る
Dynamoとは違う独自の概念で、面白いよみたいなことが書かれているものもありますが、最近のCassandraでは推奨しているものではないみたいですね。
DataStaxのドキュメントにも、使うなって書かれていますし
Super Columns
Do not use super columns. They are a legacy design from a pre-open source release. This design was structured for a specific use case and does not fit most use cases. Super columns read entire super columns and all its sub-columns into memory for each read request. This results in severe performance issues. Additionally, super columns are not supported in CQL 3.
Use composite columns instead. Composite columns provide most of the same benefits as super columns without the performance issues.
http://www.datastax.com/docs/1.1/ddl/column_family
IBMのドキュメントにも…。
スーパー・カラムと OrderPreservingPartitioner は推奨されません
マルチレベルのデータをモデル化する際には、Cassandra のスーパー・カラムが役に立つことがあります。その場合、階層にもう 1 つのレベルが追加されます。ただし、スーパー・カラムを使ってモデル化できるものは、カラムでもサポートすることが可能です。すなわち、スーパー・カラムならではの追加機能はありません。また、スーパー・カラムはセカンダリー・インデックスをサポートしていません。これらの理由から、Cassandra の開発者たちはスーパー・カラムの使用を推奨していません。サポートを中止する日程は確定されていないものの、今後のリリースではスーパー・カラムのサポートが中止されることになるはずです。
Apache Cassandra データベースについての検討
DataStaxのドキュメントでは、スーパーカラムはサブカラムを全部読んでしまうので、パフォーマンス上の問題を抱えているという話らしいです。CQL3ではスーパーカラムはサポートしていないし、同じようなことがやりたかったらComposite Columnを使えば?って感じみたいですね。
http://www.datastax.com/dev/blog/introduction-to-composite-columns-part-1
まあ、せっかくなので使ってみようかなと思い、今回試してみました。以後、触ることはないかもしれませんが…。
まずは、テスト用のキースペースを作成。
[default@unknown] create keyspace SuperColumnTest ... with placement_strategy = 'org.apache.cassandra.locator.SimpleStrategy' ... and strategy_options = {replication_factor:1}; 0e7b5c93-14a4-3443-8778-26ff2982ea04 [default@unknown] use SuperColumnTest; Authenticated to keyspace: SuperColumnTest
スーパーカラムの作成を行います。名前は、「DataStoreSuper」で。
[default@SuperColumnTest] create column family DataStoreSuper ... with column_type = 'Super' ... and key_validation_class = 'UTF8Type' ... and comparator = 'UTF8Type' ... and subcomparator = 'UTF8Type' ... and default_validation_class = 'UTF8Type'; ac877e2b-1f39-3e0c-a079-199f488d01b0
定義は、オライリー本とStack Overflowを見ながら…。
describe。
[default@SuperColumnTest] describe DataStoreSuper; WARNING: CQL3 tables are intentionally omitted from 'describe' output. See https://issues.apache.org/jira/browse/CASSANDRA-4377 for details. ColumnFamily: DataStoreSuper (Super) Key Validation Class: org.apache.cassandra.db.marshal.UTF8Type Default column value validator: org.apache.cassandra.db.marshal.UTF8Type Columns sorted by: org.apache.cassandra.db.marshal.UTF8Type/org.apache.cassandra.db.marshal.UTF8Type GC grace seconds: 864000 Compaction min/max thresholds: 4/32 Read repair chance: 0.1 DC Local Read repair chance: 0.0 Populate IO Cache on flush: false Replicate on write: true Caching: KEYS_ONLY Bloom Filter FP chance: default Built indexes: [] Compaction Strategy: org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy Compression Options: sstable_compression: org.apache.cassandra.io.compress.SnappyCompressor
ColumnFamilyがSuperになって
ColumnFamily: DataStoreSuper (Super)
Comparatorがサブカラムとで分かれています。
Columns sorted by: org.apache.cassandra.db.marshal.UTF8Type/org.apache.cassandra.db.marshal.UTF8Type
DataStoreと名前を切ったので、なんとなくRDBMSとNoSQLをロウキーにして、データを入れていってみます。
[default@SuperColumnTest] set DataStoreSuper['RDBMS']['MySQL']['version'] = '5.6.11'; Value inserted. Elapsed time: 95 msec(s). [default@SuperColumnTest] set DataStoreSuper['RDBMS']['MySQL']['URL'] = 'http://dev.mysql.com/'; Value inserted. Elapsed time: 4.79 msec(s). [default@SuperColumnTest] set DataStoreSuper['RDBMS']['PostgreSQL']['version'] = '9.2.4'; Value inserted. Elapsed time: 3.14 msec(s). [default@SuperColumnTest] set DataStoreSuper['RDBMS']['PostgreSQL']['URL'] = 'http://www.postgresql.org/'; Value inserted. Elapsed time: 3.61 msec(s). [default@SuperColumnTest] set DataStoreSuper['NoSQL']['Infinispan']['type'] = 'In Memory Data Grid'; Value inserted. Elapsed time: 43 msec(s). [default@SuperColumnTest] set DataStoreSuper['NoSQL']['Infinispan']['version'] = '5.2.5.Final'; Value inserted. Elapsed time: 36 msec(s). [default@SuperColumnTest] set DataStoreSuper['NoSQL']['Infinispan']['URL'] = 'http://www.jboss.org/infinispan/'; Value inserted. Elapsed time: 6.62 msec(s). [default@SuperColumnTest] set DataStoreSuper['NoSQL']['Apache Cassandra']['type'] = 'Document Database'; Value inserted. Elapsed time: 3.21 msec(s). [default@SuperColumnTest] set DataStoreSuper['NoSQL']['Apache Cassandra']['version'] = '1.2.4'; Value inserted. Elapsed time: 2.55 msec(s). [default@SuperColumnTest] set DataStoreSuper['NoSQL']['Apache Cassandra']['URL'] = 'http://cassandra.apache.org/'; Value inserted. Elapsed time: 3.52 msec(s).
listしてみます。
[default@SuperColumnTest] list DataStoreSuper; Using default limit of 100 Using default column limit of 100 ------------------- RowKey: NoSQL => (super_column=Apache Cassandra, (column=URL, value=http://cassandra.apache.org/, timestamp=1367228147081000) (column=type, value=Document Database, timestamp=1367228119219000) (column=version, value=1.2.4, timestamp=1367228126639000)) => (super_column=Infinispan, (column=URL, value=http://www.jboss.org/infinispan/, timestamp=1367228045150000) (column=type, value=In Memory Data Grid, timestamp=1367228000945000) (column=version, value=5.2.5.Final, timestamp=1367228022587000)) ------------------- RowKey: RDBMS => (super_column=MySQL, (column=URL, value=http://dev.mysql.com/, timestamp=1367227862881000) (column=version, value=5.6.11, timestamp=1367227838823000)) => (super_column=PostgreSQL, (column=URL, value=http://www.postgresql.org/, timestamp=1367227930874000) (column=version, value=9.2.4, timestamp=1367227919607000)) 2 Rows Returned. Elapsed time: 71 msec(s).
ロウキーに続いて、super_columnが続いていますね。
データの取得を指定する時は、
get カラムファミリ[ロウキー][スーパーカラム名][カラム名];
といった感じで指定します。
例えば、ロウキーを指定するならこんな感じ。
[default@SuperColumnTest] get DataStoreSuper['RDBMS']; => (super_column=MySQL, (column=URL, value=http://dev.mysql.com/, timestamp=1367227862881000) (column=version, value=5.6.11, timestamp=1367227838823000)) => (super_column=PostgreSQL, (column=URL, value=http://www.postgresql.org/, timestamp=1367227930874000) (column=version, value=9.2.4, timestamp=1367227919607000)) Returned 2 results. Elapsed time: 8.58 msec(s). [default@SuperColumnTest] get DataStoreSuper['NoSQL']; => (super_column=Apache Cassandra, (column=URL, value=http://cassandra.apache.org/, timestamp=1367228147081000) (column=type, value=Document Database, timestamp=1367228119219000) (column=version, value=1.2.4, timestamp=1367228126639000)) => (super_column=Infinispan, (column=URL, value=http://www.jboss.org/infinispan/, timestamp=1367228045150000) (column=type, value=In Memory Data Grid, timestamp=1367228000945000) (column=version, value=5.2.5.Final, timestamp=1367228022587000)) Returned 2 results. Elapsed time: 9.46 msec(s).
スーパーカラム名まで指定してみます。
[default@SuperColumnTest] get DataStoreSuper['RDBMS']['MySQL']; => (column=URL, value=http://dev.mysql.com/, timestamp=1367227862881000) => (column=version, value=5.6.11, timestamp=1367227838823000) Returned 2 results. Elapsed time: 8.75 msec(s).
最後は、カラム名まで。
[default@SuperColumnTest] get DataStoreSuper['RDBMS']['MySQL']['URL']; => (column=URL, value=http://dev.mysql.com/, timestamp=1367227862881000) Elapsed time: 61 msec(s).
一応、普通のカラムファミリを作る場合と比べてみましょう。
先の例ではスーパーカラム名となっていたRDBMSとNoSQLを普通のカラムファミリとして作成します。
[default@SuperColumnTest] create column family RDBMS ... with column_type = 'Standard' ... and key_validation_class = 'UTF8Type' ... and comparator = 'UTF8Type' ... and default_validation_class = 'UTF8Type'; 6e414327-74be-3b20-99e1-f1f317a44f01 [default@SuperColumnTest] create column family NoSQL ... with column_type = 'Standard' ... and key_validation_class = 'UTF8Type' ... and comparator = 'UTF8Type' ... and default_validation_class = 'UTF8Type'; 606eec53-52c0-3bc4-8560-9d5a8a073eaa
column_typeは、デフォルトの「Standard」を明示的に指定。
RDBMSカラムファミリをdescribe。
[default@SuperColumnTest] describe RDBMS; WARNING: CQL3 tables are intentionally omitted from 'describe' output. See https://issues.apache.org/jira/browse/CASSANDRA-4377 for details. ColumnFamily: RDBMS Key Validation Class: org.apache.cassandra.db.marshal.UTF8Type Default column value validator: org.apache.cassandra.db.marshal.UTF8Type Columns sorted by: org.apache.cassandra.db.marshal.UTF8Type GC grace seconds: 864000 Compaction min/max thresholds: 4/32 Read repair chance: 0.1 DC Local Read repair chance: 0.0 Populate IO Cache on flush: false Replicate on write: true Caching: KEYS_ONLY Bloom Filter FP chance: default Built indexes: [] Compaction Strategy: org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy Compression Options: sstable_compression: org.apache.cassandra.io.compress.SnappyCompressor
データを登録していってみます。
lt@SuperColumnTest] set RDBMS['MySQL']['version'] = '5.6.11'; Value inserted. Elapsed time: 8.29 msec(s). [default@SuperColumnTest] set RDBMS['MySQL']['URL'] = 'http://dev.mysql.com/'; Value inserted. Elapsed time: 8.25 msec(s). [default@SuperColumnTest] set RDBMS['PostgreSQL']['version'] = '9.2.4'; Value inserted. Elapsed time: 3.0 msec(s). [default@SuperColumnTest] set RDBMS['PostgreSQL']['URL'] = 'http://www.postgresql.org/'; Value inserted. Elapsed time: 35 msec(s). [default@SuperColumnTest] set NoSQL['Infinispan']['type'] = 'In Memory Data Grid'; Value inserted. Elapsed time: 5.87 msec(s). [default@SuperColumnTest] set NoSQL['Infinispan']['version'] = '5.2.5.Final'; Value inserted. Elapsed time: 8.44 msec(s). [default@SuperColumnTest] set NoSQL['Infinispan']['URL'] = 'http://www.jboss.org/infinispan/'; Value inserted. Elapsed time: 7.25 msec(s). [default@SuperColumnTest] set NoSQL['Apache Cassandra']['type'] = 'Document Database'; Value inserted. Elapsed time: 3.4 msec(s). [default@SuperColumnTest] set NoSQL['Apache Cassandra']['version'] = '1.2.4'; Value inserted. Elapsed time: 2.72 msec(s). [default@SuperColumnTest] set NoSQL['Apache Cassandra']['URL'] = 'http://cassandra.apache.org/'; Value inserted. Elapsed time: 2.9 msec(s).
list。
[default@SuperColumnTest] list RDBMS; Using default limit of 100 Using default column limit of 100 ------------------- RowKey: MySQL => (column=URL, value=http://dev.mysql.com/, timestamp=1367228934643000) => (column=version, value=5.6.11, timestamp=1367228920876000) ------------------- RowKey: PostgreSQL => (column=URL, value=http://www.postgresql.org/, timestamp=1367229001008000) => (column=version, value=9.2.4, timestamp=1367228990537000) 2 Rows Returned. Elapsed time: 17 msec(s). [default@SuperColumnTest] list NoSQL; Using default limit of 100 Using default column limit of 100 ------------------- RowKey: Apache Cassandra => (column=URL, value=http://cassandra.apache.org/, timestamp=1367229246005000) => (column=type, value=Document Database, timestamp=1367229228761000) => (column=version, value=1.2.4, timestamp=1367229235363000) ------------------- RowKey: Infinispan => (column=URL, value=http://www.jboss.org/infinispan/, timestamp=1367229207248000) => (column=type, value=In Memory Data Grid, timestamp=1367229140183000) => (column=version, value=5.2.5.Final, timestamp=1367229156563000) 2 Rows Returned. Elapsed time: 5.7 msec(s).
普通のカラムファミリの場合は、データの取得は
get カラムファミリ名[ロウキー][カラム名];
ですね。
というわけで、getしてみます。
[default@SuperColumnTest] get RDBMS['MySQL']; => (column=URL, value=http://dev.mysql.com/, timestamp=1367228934643000) => (column=version, value=5.6.11, timestamp=1367228920876000) Returned 2 results. Elapsed time: 3.84 msec(s). [default@SuperColumnTest] get RDBMS['MySQL']['URL']; => (column=URL, value=http://dev.mysql.com/, timestamp=1367228934643000) Elapsed time: 3.18 msec(s). [default@SuperColumnTest] get NoSQL['Apache Cassandra']; => (column=URL, value=http://cassandra.apache.org/, timestamp=1367229246005000) => (column=type, value=Document Database, timestamp=1367229228761000) => (column=version, value=1.2.4, timestamp=1367229235363000) Returned 3 results. Elapsed time: 8.51 msec(s). [default@SuperColumnTest] get NoSQL['Apache Cassandra']['URL']; => (column=URL, value=http://cassandra.apache.org/, timestamp=1367229246005000) Elapsed time: 4.39 msec(s).