9

ユーザー定義型フィールドでcassandraクエリをフィルタリングする方法は? cassandra データベースに people テーブルを作成したいので、このユーザー定義型を cassandra データベースに作成します。

    create type fullname ( firstname text, lastname text );

私もこのテーブルを持っています。

    create table people ( id UUID primary key, name frozen <fullname> );

そして、姓がジョリーのすべての人を知るために、クエリをフィルタリングする必要があります。このテーブルからこれを照会するにはどうすればよいですか。カサンドラでのフィルタリングとクエリはどうですか?fullname タイプを削除して、firstname と lastname をメイン テーブルに追加できることはわかっていますが、これは私がやりたいことのサンプルです。fullname タイプが必要です。

4

1 に答える 1

11

簡単な答え: セカンダリ インデックスを使用して、フルネーム 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 の使用を強制する人がいない場合)。
于 2015-11-23T12:39:03.463 に答える