Cassandraのパーティションキー、複合キー、およびクラスタリングキーの違いは何ですか?


523

私はネット上の記事を読んで、次のkeyタイプの違いを理解しています。しかし、私には理解するのが難しいようです。例は間違いなく理解を深めるのに役立ちます。

primary key,
partition key, 
composite key 
clustering key

23
これらの概念に関する多くの詳細な説明を含むこの記事を見つけました。
mynkow 14年

この記事では、これらの用語も明確に指摘しています。
duong_dajgja 2016年

上記で共有している@duong_dajgjaのURLが壊れています。コメントを有効なURLで編集していただけますか?
realPK 2018年

@realPKリンクがどういうわけかなくなっています。しかし、ここでquora.com/…に別のリンクを見つけました。
duong_dajgja 2018年

回答:


1172

これについては多くの混乱がありますが、できるだけ簡単にするように努めます。

主キーは、テーブルからデータを取得するために使用される1つ以上の列を示す一般的な概念です。

主キーは単純で、インラインで宣言することもできます。

 create table stackoverflow_simple (
      key text PRIMARY KEY,
      data text      
  );

つまり、単一の列で構成されています。

ただし、主キーは、より多くの列から生成されたCOMPOSITE(別名COMPOUND)にすることもできます。

 create table stackoverflow_composite (
      key_part_one text,
      key_part_two int,
      data text,
      PRIMARY KEY(key_part_one, key_part_two)      
  );

COMPOSITEプライマリキーの状況では、キーの「最初の部分」はPARTITION KEY(この例ではkey_part_oneはパーティションキーです)と呼ばれ、キーの2番目の部分はCLUSTERING KEY(この例ではkey_part_two)です

パーティションキーとクラスタリングキーの両方を、より多くの列作成できることに注意してください。方法は次のとおりです。

 create table stackoverflow_multiple (
      k_part_one text,
      k_part_two int,
      k_clust_one text,
      k_clust_two int,
      k_clust_three uuid,
      data text,
      PRIMARY KEY((k_part_one, k_part_two), k_clust_one, k_clust_two, k_clust_three)      
  );

これらの名前の後ろに...

  • パーティション・キーは、あなたのノード間でデータ配信を担当しています。
  • クラスタリングキーは、パーティション内のデータをソートする責任があります。
  • 主キーは同等ですパーティション・キーの単一フィールドキーテーブル(すなわちでシンプル)。
  • コンポジット/複合キーはただの複数列のキーです

さらなる使用情報:DATASTAX DOCUMENTATION


小さな使用法とコンテンツの例
SIMPLE KEY:

insert into stackoverflow_simple (key, data) VALUES ('han', 'solo');
select * from stackoverflow_simple where key='han';

テーブルの内容

key | data
----+------
han | solo

COMPOSITE / COMPOUND KEYは「広い行」を取得できます(つまり、クラスタリングキーが定義されている場合でも、パーティションキーだけでクエリを実行できます)

insert into stackoverflow_composite (key_part_one, key_part_two, data) VALUES ('ronaldo', 9, 'football player');
insert into stackoverflow_composite (key_part_one, key_part_two, data) VALUES ('ronaldo', 10, 'ex-football player');
select * from stackoverflow_composite where key_part_one = 'ronaldo';

テーブルの内容

 key_part_one | key_part_two | data
--------------+--------------+--------------------
      ronaldo |            9 |    football player
      ronaldo |           10 | ex-football player

しかし、すべてのキー(パーティションとクラスタリングの両方)でクエリを実行できます...

select * from stackoverflow_composite 
   where key_part_one = 'ronaldo' and key_part_two  = 10;

クエリ出力

 key_part_one | key_part_two | data
--------------+--------------+--------------------
      ronaldo |           10 | ex-football player

重要な注意:パーティションキーは、を使用してクエリを実行するために必要な最小指定子ですwhere clause。次のような複合パーティションキーがある場合

例えば: PRIMARY KEY((col1, col2), col10, col4))

クエリを実行するには、少なくともcol1とcol2の両方を渡す必要があります。これらは、パーティションキーを定義する2つの列です。クエリを作成するための「一般的な」ルールは、少なくともすべてのパーティションキー列を渡す必要があることです。その後、オプションで各クラスタリングキーを設定された順序で追加できます。

したがって、有効なクエリは(セカンダリインデックスを除く

  • col1およびcol2
  • col1およびcol2およびcol10
  • col1およびcol2およびcol10およびcol 4

無効:

  • col1およびcol2およびcol4
  • col1とcol2の両方を含まないもの

お役に立てれば。


7
私が書いたように、<<クエリを作成するための「一般的な」ルールは、少なくともすべてのパーティションキー列を渡す必要がある場合、設定された順序で各キーを追加できます。>>-col10は以前に定義されているためcol4は、col4についてもクエリに渡す必要があります
Carlo Bertuccini

2
あなたは、セカンダリインデックスを追加することができますが、それはあなたが「任意の」CQLクエリを実行できるという意味ではありません-多くの:あなたは10までカウントするセカンダリインデックスを作成する前に... 000 ..... :)
カルロBertuccini

2
セカンダリインデックスはローカルインデックスとして実装されます-それらはクラスターに分散されません。クラスターの各ノードは、所有するデータのセカンダリインデックスを格納する役割を果たします。このためsec.index上のクエリは、クラスタ内のすべてのノードを伴うかもしれない
カルロBertuccini

5
これは数日間私を混乱させました、この答えのおかげで、今私は頭の中でデータモデルを構築することができます。
Roger Dwan

2
ワオ。あなたはちょうど私を数時間または数日節約しました!素晴らしい説明ありがとうございます。
Andre Garcia

128

承認された回答として要約回答を追加するのは非常に長いです。「行」および「列」という用語は、Cassandraが実際に実装される方法ではなく、CQLのコンテキストで使用されます。

  • 主キーは行を一意に識別する。
  • 複合キーが複数の列から形成されたキーです。
  • パーティション・キーは、すなわちパーティションの行のセットを見つけるための主要な検索です。
  • クラスタリング・キーは、パーティション・キーではない(とパーティション内の順序を定義する)主キーの一部です。

例:

  • PRIMARY KEY (a):パーティションキーはaです。
  • PRIMARY KEY (a, b):パーティションキーはa、クラスタリングキーはbです。
  • PRIMARY KEY ((a, b)):複合パーティションキーは(a, b)です。
  • PRIMARY KEY (a, b, c):パーティションキーはa、複合クラスタリングキーは(b, c)です。
  • PRIMARY KEY ((a, b), c):複合パーティションキーは(a, b)、クラスタリングキーはcです。
  • PRIMARY KEY ((a, b), c, d):複合パーティションキーは(a, b)、複合クラスタリングキーは(c, d)です。

15

cassandraでは、主キー、パーティションキー、複合キー、クラスタリングキーの違いにより、常に混乱が生じます。したがって、以下で説明し、相互に関連させます。CassandraデータベースへのアクセスにはCQL(Cassandra Query Language)を使用します。注:-回答は、Cassandraの更新されたバージョンによるものです。 主キー:-

cassandraでは、主キーを使用する2つの異なる方法があります。

CREATE TABLE Cass (
    id int PRIMARY KEY,
    name text 
);

Create Table Cass (
   id int,
   name text,
   PRIMARY KEY(id) 
);

CQLでは、PRIMARY KEYに対して列が定義される順序が重要です。キーの最初の列はパーティションキーと呼ばれ、同じパーティションキーを共有するすべての行が(実際にはテーブル間でさえ)同じ物理ノードに格納されるというプロパティがあります。また、特定のテーブルの同じパーティションキーを共有する行の挿入/更新/削除は、アトミックかつ分離して実行されます。括弧の追加セットを使用して、どの列がパーティションキーを形成するかを定義する、複合パーティションキー、つまり複数の列で構成されるパーティションキーを持つことが可能であることに注意してください。

パーティション化とクラスタリング PRIMARY KEYの定義は、パーティションキーとクラスタリング列の2つの部分で構成されています。最初の部分はストレージエンジンの行キーにマップされ、2番目の部分は行の列をグループ化するために使用されます。

CREATE TABLE device_check (
  device_id   int,
  checked_at  timestamp,
  is_power    boolean,
  is_locked   boolean,
  PRIMARY KEY (device_id, checked_at)
);

ここで、device_idはパーティションキーで、checked_atはcluster_keyです。

宣言に依存する複数のクラスターキーとパーティションキーも持つことができます。


6
あなたはあなたのソースにいくつかの信用を与えることができたでしょう(2013 =あなたの投稿より古い):thelastpickle.com/blog/2013/01/11/primary-keys-in-cql.html
Christophe Roussy

11

PRIMARY KEY:パーティション・キー(複数可)で構成されている[および任意のクラスタリング・キー(または列)]
パーティションキー:パーティションキーのハッシュ値がデータ格納するために、クラスタ内の特定ノードを決定するために使用される
クラスタリングキー:するために使用され各パーティション(または責任ノードとそのレプリカ)のデータをソートする

複合主キー:上記のように、クラスタリングキーは主キーではオプションです。それらが言及されていない場合、それは単純な主キーです。クラスタリングキーが言及されている場合、それは複合主キーです。

複合パーティションキー:パーティションキーとして1つの列のみを使用すると、幅広い行の問題が発生する可能性があります(ユースケース/データモデリングによって異なります)。したがって、パーティションキーは、複数の列の組み合わせとして指定される場合があります。

どちらが必須であるか、どれがスキップできるかなどの混乱について Cassandraを巨大なHashMapが役立つと想像してみてください。したがって、HashMapでは、キーがないと値を取得できません。
ここでは、パーティションキーがそのキーの役割を果たします。したがって、各クエリでそれらを指定する必要があります。これがないと、Cassandraは検索するノードを認識できません。クラスタ化キー、さらにカサンドラは、特定のノードを発見した後、クエリの検索を狭める(およびそれのレプリカ)のヘルプ、その特定の責任(オプションである列、)パーティションキー


5

簡単に言うと:

パーティションキーは行の識別にすぎません。その識別は、ほとんどの場合、単一の列(主キーと呼ばれる)である場合があり、複数の列の組み合わせ(複合パーティションキーと呼ばれる)になることもあります。

クラスタキーは、インデックス作成並べ替えにすぎません。クラスターキーはいくつかの要素に依存します。

  1. 主キー列以外のwhere句で使用する列。

  2. 非常に大きなレコードがある場合は、日付を分割して管理しやすくすることができます。例、私は100万の郡の人口記録のデータを持っています。したがって、管理を簡単にするために、状態やピンコード後などに基づいてデータをクラスター化します。


3
パーティションキーはA行の識別ではありません...すべてのパーティションキーが同じ行の束を識別します
wmac

1

注目に値するのは、リレーショナルの世界(コンポジットキー)の同様の概念よりも、これらをより多く使用することでしょう。

例-ユーザーグループXに最近参加した最後のN人のユーザーを見つける必要があると仮定します。この場合、読み取りが主流である場合、これをどのように効率的に実行しますか?そのように(公式のCassandraガイドから):

CREATE TABLE group_join_dates (
    groupname text,
    joined timeuuid,
    join_date text,
    username text,
    email text,
    age int,
    PRIMARY KEY ((groupname, join_date), joined)
) WITH CLUSTERING ORDER BY (joined DESC)

ここでは、パーティショニングキーはそれ自体が複合であり、クラスタリングキーは結合された日付です。クラスタリングキーが結合日である理由は、結果がすでにソートされている(そして格納されているため、検索が高速になる)ためです。しかし、なぜパーティションキーに複合キーを使用するのですか?ので、私たちは常に可能な限り少ないパーティションとして読んでもらいたいです。そこにjoin_dateを入れるとどのように役立ちますか?これで、同じグループの同じ参加日付のユーザーが1つのパーティションに存在するようになります。これは、可能な限り少ないパーティションを常に読み取ることを意味します(最初に新しいパーティションから始め、次に古いパーティションに移動するなど、パーティション間をジャンプするのではなく)。

実際、極端なケースでは、join_dateだけではなく、join_dateのハッシュを使用する必要もあります。そのため、過去3日間のクエリを実行すると、同じハッシュを共有することが多く、同じパーティションから使用できるようになります。


0

Cassandraの主キーは通常、パーティションキーとクラスタリング列の2つの部分で構成されます。

primary_key((partition_key)、clustering_col)

パーティションキー-主キーの最初の部分。パーティションキーの主な目的は、特定の行を格納するノードを識別することです。

CREATE TABLE phone_book(phone_num int、name text、age int、city text、PRIMARY KEY((phone_num、name)、age);

ここで、(phone_num、name)はパーティションキーです。データの挿入時に、パーティションキーのハッシュ値が生成され、この値によって行がどのノードに移動するかが決まります。

4ノードのクラスターを考えてみます。各ノードには、保存できるハッシュ値の範囲があります。(書き込み)INSERT INTO phone_book VALUES(7826573732、 'Joey'、25、 'New York');

これで、パーティションキーのハッシュ値がCassandraパーティショナーによって計算されます。たとえば、ハッシュ値(7826573732、 'Joey')→12とすると、この行がノードCに挿入されます。

(読み込み)SELECT * FROM phone_book WHERE phone_num = 7826573732 and name = 'Joey';

ここでも、パーティションキーのハッシュ値(7826573732、 'Joey')が計算されます。この例では、ノードCにある12であり、そこから読み取りが行われます。

  1. 列のクラスタリング-主キーの2番目の部分。列をクラスタリングする主な目的は、データをソートされた順序で格納することです。デフォルトでは、順序は昇順です。

解決するクエリによっては、主キーに複数のパーティションキーとクラスタリング列が存在する場合があります。

primary_key((pk1、pk2)、col 1、col2)


-3

データベース設計では、複合キーは最小限ではないスーパーキーのセットです。

複合キーは、複合キーとスーパーキーではない少なくとも1つの属性を含むセットです

与えられたテーブル:EMPLOYEES {employee_id、firstname、surname}

可能なスーパーキーは次のとおりです。

{employee_id}
{employee_id, firstname}
{employee_id, firstname, surname}

{employee_id}は唯一の最小限のスーパーキーです。これにより、{firstname}と{surname}が一意性を保証しない場合、これが唯一の候補キーになります。主キーは選択された候補キーとして定義され、この例では候補キーが1つしか存在しないため、{employee_id}は最小のスーパーキーであり、唯一の候補キーであり、唯一の可能な主キーです。

複合キーの完全なリストは次のとおりです。

{employee_id, firstname}
{employee_id, surname}
{employee_id, firstname, surname}

複合キーは{employee_id、firstname、surname}です。そのキーには複合キー({employee_id、firstname})とスーパーキーではない属性({surname})が含まれているためです。


質問とはまったく関係ありません。一般的な説明ではなく、Cassandraのコンテキストで尋ねられたキーに対処するための回答を編集してください。TY。
realPK 2018年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.