Разница между ключом раздела, составным ключом и ключом кластеризации в Cassandra?

524

Я читал статьи по сети, чтобы понять различия между следующими keyтипами. Но мне просто трудно это понять. Примеры определенно помогут сделать понимание лучше.

primary key,
partition key, 
composite key 
clustering key
мозговой штурм
источник
23
Я нашел эту статью, которая содержит много подробных объяснений этих понятий.
Mynkow
В этой статье также четко указываются эти термины.
duong_dajgja
@duong_dajgja URL, которым вы поделились выше, не работает. Можете ли вы отредактировать комментарий с помощью действующего / полезного URL?
realPK
@realPK Ссылка как-то ушла. Но я нашел другую ссылку для вас здесь quora.com/... .
duong_dajgja

Ответы:

1173

Вокруг этого много путаницы, я постараюсь сделать это как можно проще.

Первичный ключ - это общая концепция для указания одного или нескольких столбцов, используемых для извлечения данных из таблицы.

Первичный ключ может быть ПРОСТОЙ и даже объявленным встроенным:

 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 - это ключ раздела), а вторая часть ключа - это 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)      
  );

За этими именами ...

  • Partition Key отвечает за распределение данных между узлами.
  • Кластеризация Key отвечает за сортировки данных в пределах раздела.
  • Первичный ключ эквивалентен Partition ключа в одной полевой ключ таблицы (т.е. Simple ).
  • Composite / Соединение Ключ просто любая клавиша несколько столбцов

Дополнительная информация об использовании: DATASTAX DOCUMENTATION


Небольшое использование и примеры контента
ПРОСТОЙ КЛЮЧ:

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

содержание таблицы

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

КОМПОЗИТНЫЙ / КОМПОЗИЦИОННЫЙ КЛЮЧ может извлекать «широкие строки» (т. Е. Вы можете делать запросы только по ключу раздела, даже если у вас определены ключи кластеризации)

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, это два столбца, которые определяют ключ раздела. «Общее» правило для создания запроса заключается в том, что вы должны пропустить хотя бы все столбцы ключей секционирования, а затем при желании вы можете добавить каждый ключ кластеризации в установленном порядке.

поэтому допустимые запросы ( за исключением вторичных индексов )

  • col1 и col2
  • col1 и col2 и col10
  • col1 и col2 и col10 и col 4

Недействительным:

  • col1 и col2 и col4
  • все, что не содержит ни col1, ни col2

Надеюсь это поможет.

Карло Бертуччини
источник
7
Как я уже писал - << «Общее» правило для создания запроса заключается в том, что вы должны пропустить по крайней мере все столбцы ключей секционирования, затем вы можете добавить каждый ключ в том порядке, в котором они установлены. >> - поскольку col10 определен ранее col4 Вы должны передать его, чтобы запросить также col4
Карло Бертуччини
2
Вы можете добавить вторичные индексы, но это не значит, что вы можете выполнить «любой» запрос cql - и даже больше: перед созданием вторичного индекса вы должны считать до 10 ... 000 ..... :)
Carlo Bertuccini
2
Вторичные индексы реализованы в виде локальных индексов - они не распределены в кластере. Каждый узел кластера отвечает за хранение вторичных индексов данных, которыми он владеет. По этой причине запрос к sec.index может включать все узлы в кластере
Карло Бертуччини
5
Это смутило меня несколько дней, спасибо за этот ответ, теперь я могу построить модель данных в моей голове.
Роджер Дван
2
Ух ты. ты только что спас мне часы или дни! Спасибо, блестящее объяснение.
Андре Гарсия
128

Добавление краткого ответа как принятого довольно длинное. Термины «строка» и «столбец» используются в контексте CQL, а не в том, как на самом деле реализована Cassandra.

  • Первичный ключ однозначно идентифицирует строку.
  • Составной ключ является ключом формируется из нескольких столбцов.
  • Ключ раздела является основным поиском , чтобы найти множество строк, то есть раздел.
  • Ключ кластеризации является частью первичного ключа , который не является ключом раздела (и определяет порядок внутри раздела).

Примеры:

  • 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).
OrangeDog
источник
15

В Кассандре разница между первичным ключом, ключом раздела, составным ключом, ключом кластеризации всегда вносит некоторую путаницу. Поэтому я собираюсь объяснить ниже и соотнести их друг с другом. Мы используем 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 состоит из двух частей: ключа разделения и столбцов кластеризации. Первая часть отображается на ключ строки механизма хранения, а вторая используется для группировки столбцов в строке.

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

Здесь device_id - это ключ раздела, а selected_at - это ключ cluster_key.

У нас может быть несколько ключей кластера, а также ключ раздела, который зависит от объявления.

Big Data Guy
источник
6
Вы могли бы отдать должное своим источникам (2013 = старше, чем ваш пост): thelastpickle.com/blog/2013/01/11/primary-keys-in-cql.html
Кристоф Руссси
11

Первичный ключ : состоит из ключа (ключей) раздела [и необязательных ключей (или столбцов) кластеризации].
Ключ раздела : значение хеш-кода ключа раздела используется для определения конкретного узла в кластере для хранения данных.
Ключ кластеризации : используется для сортировать данные в каждом из разделов (или ответственного узла и его реплик)

Составной первичный ключ : как сказано выше, ключи кластеризации являются необязательными в первичном ключе. Если они не упомянуты, это простой первичный ключ. Если упоминаются ключи кластеризации, это составной первичный ключ.

Составной ключ раздела : использование только одного столбца в качестве ключа раздела может привести к проблемам с широкими строками (зависит от варианта использования / моделирования данных). Следовательно, ключ раздела иногда указывается как комбинация нескольких столбцов.

Что касается путаницы, какая из них обязательна , какую можно пропустить и т. Д. В запросе, топомогает представить Кассандру как гигантскую хэш-карту . Таким образом, в HashMap вы не можете получить значения без ключа.
Здесь ключи раздела играют роль этого ключа. Таким образом, каждый запрос должен быть указан. Без которого Кассандра не будет знать, какой узел искать.
В кластеризация ключи (столбцы, которыеявляются обязательными) помощь в дальнейшем сужающих ваш поисковый запрос послеCassandra выясняет конкретный узел (и это репликами) отвечает за этот конкретный ключ раздела .

Чандан Хегде
источник
5

В кратком смысле:

Ключ разделения - это не что иное, как идентификация для строки, эта идентификация в большинстве случаев представляет собой один столбец (называемый первичным ключом ), иногда комбинацию нескольких столбцов (называемых составным ключом разделения ).

Ключ кластера - это не что иное, как индексирование и сортировка . Ключи кластера зависят от нескольких вещей:

  1. Какие столбцы вы используете в предложении where, кроме столбцов первичного ключа.

  2. Если у вас есть очень большие записи, то о том, что касается, я могу разделить дату для удобного управления. Например, у меня есть данные о 1 млн. Записей населения округа. Поэтому для простоты управления я кластеризирую данные на основе состояния и после пин-кода и так далее.

солнце
источник
3
Ключ раздела НЕ является идентификацией для строки ... он идентифицирует группу строк, каждая из которых имеет один и тот же ключ раздела
wmac
1

Стоит отметить, что вы, вероятно, будете использовать эти партии больше, чем в похожих концепциях в реляционном мире (составные ключи).

Пример - предположим, что вам нужно найти последних N пользователей, которые недавно присоединились к группе пользователей X. Как бы вы сделали это эффективно, учитывая, что чтения в этом случае преобладают? Вот так (из официального руководства Кассандры ):

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 ? Теперь пользователи из той же группы и с той же датой присоединения будут находиться в одном разделе! Это означает, что мы всегда будем читать как можно меньше разделов (сначала начните с самого нового, затем перейдите к старому и т. Д., А не прыгайте между ними).

На самом деле, в крайних случаях вам также нужно будет использовать хеш от join_date, а не только join_date - так что если вы выполняете запросы в течение последних 3 дней, часто они используют один и тот же хеш и, следовательно, доступны из одного раздела!

kboom
источник
0

Первичный ключ в Cassandra обычно состоит из двух частей - ключа раздела и столбцов кластеризации.

primary_key ((partition_key), clustering_col)

Ключ раздела - первая часть первичного ключа. Основная цель ключа раздела - определить узел, в котором хранится конкретная строка.

CREATE TABLE phone_book (phone_num int, текст имени, age int, текст города, PRIMARY KEY ((phone_num, name), возраст);

Здесь (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 и name = 'Joey';

Теперь снова вычисляется хеш-значение ключа разделения (7826573732, «Joey»), которое в нашем случае равно 12, который находится в узле C, из которого выполняется чтение.

  1. Кластеризация столбцов - Вторая часть первичного ключа. Основная цель кластеризации столбцов - хранить данные в отсортированном порядке. По умолчанию порядок возрастает.

В первичном ключе может быть несколько ключей раздела и столбцов кластеризации, в зависимости от того, какой запрос вы решаете.

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

Sumon Saikan
источник
-3

При проектировании базы данных составной ключ - это набор неключевых ключей.

Составной ключ - это набор, который содержит составной ключ и хотя бы один атрибут, который не является суперключем

Данная таблица: EMPLOYEES {employee_id, имя, фамилия}

Возможные суперключи:

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

{employee_id} - это единственный минимальный суперключ, который также делает его единственным подходящим ключом - учитывая, что {имя} и {фамилия} не гарантируют уникальность. Поскольку первичный ключ определен как выбранный ключ-кандидат, и в этом примере существует только один ключ-кандидат, {employee_id} - это минимальный суперключ, единственный ключ-кандидат и единственный возможный первичный ключ.

Полный список составных ключей:

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

Единственный составной ключ - это {employee_id, firstname, фамилия}, поскольку этот ключ содержит составной ключ ({employee_id, firstname}) и атрибут, который не является суперключем ({фамилия}).

Khurana
источник
Абсолютно не имеет отношения к заданному вопросу. Пожалуйста, измените ответ на адресные ключи, заданные в контексте Cassandra, а не общее объяснение. TY.
realPK