簡単な答え: セカンダリ インデックスを使用して、フルネーム UDT でクエリを実行できます。ただし、UDT の一部だけでクエリを実行することはできません。
// create table, type and index
create type fullname ( firstname text, lastname text );
create table people ( id UUID primary key, name frozen <fullname> );
create index fname_index on your_keyspace.people (name);
// insert some data into it
insert into people (id, name) values (now(), {firstname: 'foo', lastname: 'bar'});
insert into people (id, name) values (now(), {firstname: 'baz', lastname: 'qux'});
// query it by fullname
select * from people where name = { firstname: 'baz', lastname: 'qux' };
// the following will NOT work:
select * from people where name = { firstname: 'baz'};
このような動作の理由は、C* セカンダリ インデックスの実装方法にあります。一般に、これはC *によって維持される別の隠しテーブルであり、あなたの場合は次のように定義されています:
create table fname_index (name frozen <fullname> primary key, id uuid);
実際、このテーブルでは、セカンダリ キーとプライマリ キーが入れ替わっています。したがって、あなたのケースは、「PK の一部だけで照会できないのはなぜですか?」というより一般的な質問に縮小されます。
- PK 値全体 (名 + 姓) がハッシュされ、結果の数値が行を格納するパーティションを定義します。
- そのパーティションの場合、行は memtable に追加されます (その後、キーでソートされたファイルである SSTable にディスク上でフラッシュされます)。
- PK の一部のみ (名のみなど) でクエリを実行する場合、C* は検索するパーティションを推測できません (姓が不明であるためフルネーム全体のハッシュコードを計算できないため)。 、完全なテーブル スキャンを必要とする任意のパーティション内のどこにでも一致する可能性があるためです。C* はこれらのスキャンを明示的に禁止しているため、選択の余地はありません :)
推奨される解決策:
- UDT を姓名などの重要な部分に分割し、セカンダリ インデックスを作成します。
- マテリアライズド ビュー機能を備えた Cassandra 3.0 を使用します (実際には、cassandra に UDT の一部のカスタム インデックスを維持させます)。
- データ モデルを再検討して、厳密性を低くします (役に立たない UDT の使用を強制する人がいない場合)。