Разница между ключом раздела, составным ключом и ключом кластеризации в Cassandra?
Я читал статьи по сети, чтобы понять разницу между key
типы. Но мне просто трудно это понять. Примеры определенно помогут сделать понимание лучше.
primary key,
partition key,
composite key
clustering key
12 ответов
Вокруг этого много путаницы, я постараюсь сделать это как можно проще.
Первичный ключ - это общая концепция для указания одного или нескольких столбцов, используемых для извлечения данных из таблицы.
Первичный ключ может быть ПРОСТОЙ и даже объявленным встроенным:
create table stackru_simple (
key text PRIMARY KEY,
data text
);
Это означает, что это сделано одним столбцом.
Но первичным ключом также может быть COMPOSITE (он же COMPOUND), сгенерированный из нескольких столбцов.
create table stackru.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 stackru_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)
);
За этими именами...
- Ключ раздела отвечает за распределение данных по вашим узлам.
- Ключ кластеризации отвечает за сортировку данных в разделе.
- Первичный ключ эквивалентен ключу разделения в таблице ключей с одним полем (т. Е. Simple).
- Составной / составной ключ - это любой любой ключ из нескольких столбцов
Дополнительная информация об использовании: DATASTAX DOCUMENTATION
Небольшое использование и примеры контента
ПРОСТОЙ КЛЮЧ:
insert into stackru_simple (key, data) VALUES ('han', 'solo');
select * from stackru_simple where key='han';
содержание таблицы
key | data
----+------
han | solo
КОМПОЗИЦИОННЫЙ / КОМПОЗИЦИОННЫЙ КЛЮЧ может извлекать "широкие строки" (т. Е. Вы можете делать запросы только по ключу раздела, даже если у вас определены ключи кластеризации)
insert into stackru.composite (key_part_one, key_part_two, data) VALUES ('ronaldo', 9, 'football player');
insert into stackru.composite (key_part_one, key_part_two, data) VALUES ('ronaldo', 10, 'ex-football player');
select * from stackru.composite where key_part_one = 'ronaldo';
содержание таблицы
key_part_one | key_part_two | data
--------------+--------------+--------------------
ronaldo | 9 | football player
ronaldo | 10 | ex-football player
Но вы можете запросить все ключи (как разделение и кластеризация) ...
select * from stackru.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
Надеюсь это поможет.
Добавление избыточного ответа в качестве принятого довольно длинное. Термины "строка" и "столбец" используются в контексте 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)
,
В Кассандре разница между первичным ключом, ключом раздела, составным ключом, ключом кластеризации всегда вносит некоторую путаницу. Поэтому я собираюсь объяснить ниже и соотнести их друг с другом. Мы используем 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 - это ключ раздела, а check_at - это ключ cluster_key.
У нас может быть несколько ключей кластера, а также ключ раздела, который зависит от объявления.
Первичный ключ: состоит из ключа (ключей) раздела [и необязательных ключей кластеризации (или столбцов)]
Ключ раздела: значение хеш-кода ключа раздела используется для определения конкретного узла в кластере для хранения данных.
Ключ кластеризации: используется для сортировки данных в каждом из разделов (или ответственного узла и его реплик)
Составной первичный ключ: как сказано выше, ключи кластеризации являются необязательными в первичном ключе. Если они не упомянуты, это простой первичный ключ. Если упоминаются ключи кластеризации, это составной первичный ключ.
Составной ключ раздела. Использование только одного столбца в качестве ключа раздела может привести к проблемам с широкими строками (зависит от варианта использования / моделирования данных). Следовательно, ключ раздела иногда указывается как комбинация нескольких столбцов.
Что касается путаницы, какая из них обязательна, какую можно пропустить и т. Д. В запросе, попытка представить Кассандру как гигантскую хэш-карту помогает. Таким образом, в HashMap вы не можете получить значения без ключа.
Здесь ключи Разделения играют роль этого ключа. Таким образом, каждый запрос должен быть указан. Без которого Кассандра не будет знать, какой узел искать.
Ключи кластеризации (столбцы, которые являются необязательными) помогают дополнительно сузить поиск запроса после того, как Cassandra обнаружит конкретный узел (и его реплики), отвечающий за этот конкретный ключ раздела.
В кратком смысле:
Ключ разделения - это не что иное, как идентификация для строки, эта идентификация в большинстве случаев представляет собой один столбец (называемый первичным ключом), иногда комбинацию нескольких столбцов (называемых составным ключом разделения).
Ключ кластера - это не что иное, как индексирование и сортировка. Ключи кластера зависят от нескольких вещей:
Какие столбцы вы используете в предложении where, кроме столбцов первичного ключа.
Если у вас есть очень большие записи, то о том, что касается, я могу разделить дату для удобного управления. Например, у меня есть данные о 1 млн. Записей населения округа. Поэтому для простоты управления я кластеризую данные на основе состояния и после пин-кода и так далее.
Первичный ключ в Cassandra обычно состоит из двух частей - ключа раздела и столбцов кластеризации.
primary_key ((partition_key), clustering_col)
Ключ раздела - первая часть первичного ключа. Основная цель ключа раздела - идентифицировать узел, в котором хранится конкретная строка.
СОЗДАТЬ ТАБЛИЦУ phone_book ( phone_num int, name text, age int, city text, PRIMARY KEY ((phone_num, name), age);
Здесь (phone_num, name) - это ключ раздела. При вставке данных создается хеш-значение ключа раздела, и это значение определяет, в какой узел должна войти строка.
Рассмотрим кластер из 4 узлов, каждый узел имеет диапазон хеш-значений, которые он может хранить. (Написать) ВСТАВИТЬ В телефонную книгу ЗНАЧЕНИЯ (7826573732, 'Joey', 25, 'New York');
Теперь хеш-значение ключа раздела вычисляется секционером Cassandra. скажем, значение хеш-функции (7826573732, 'Joey') → 12, теперь эта строка будет вставлена в узел C.
(Чтение) SELECT * FROM phone_book WHERE phone_num=7826573732 and name= 'Joey';
Теперь снова вычисляется хэш-значение ключа раздела (7826573732, 'Joey'), которое в нашем случае равно 12 и находится в узле C, из которого выполняется чтение.
- Столбцы кластеризации - вторая часть первичного ключа. Основная цель кластеризации столбцов - хранить данные в отсортированном порядке. По умолчанию порядок возрастающий.
В первичном ключе может быть более одного ключа раздела и столбцов кластеризации, в зависимости от решаемого запроса.
primary_key((pk1, pk2), столбец 1, столбец2)
Стоит отметить, что вы, вероятно, будете использовать эти партии больше, чем в похожих концепциях в реляционном мире (составные ключи).
Пример - предположим, что вам нужно найти последних 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 дней, часто они используют один и тот же хеш и, следовательно, доступны из одного раздела!
Первичный ключ: как и во многих базах данных, это уникальный ключ в таблице, по сути, это означает, что для любых двух записей в таблице первичный ключ не может быть одинаковым. База данных, в данном случае Cassandra, спроектирована таким образом, чтобы это условие выполнялось во всех ситуациях. Поэтому, если вы попытаетесь записать запись с PK1 в качестве первичного ключа, если уже существует запись с тем же ключом PK1, она будет перезаписана, иначе будет создана новая запись.
Ключ раздела: это конструкция распределенных баз данных (где данные одной таблицы разделены на несколько частей, называемых разделами). Затем разделы распределяются по узлам с использованием стратегии распределения (обычно хэш ключа раздела), чтобы получить бесконечные возможности масштабирования. При этом ключ раздела — это набор столбцов записи, который определяет, к какому разделу будет принадлежать эта запись. И, следовательно, ключ раздела определяет физическое расположение записи в распределенном кластере узлов.
Ключ кластеризации: Ключ кластеризации определяет порядок записей в конкретном разделе. Таким образом, если в разделе есть 10 КБ записей, ключ кластеризации будет определять порядок, в котором эти 10 КБ будут физически храниться в отсортированном виде.
Пример:
Допустим, у вас есть таблица в Cassandra для хранения событий продаж веб-сайта электронной коммерции.
[order_id, item_id, quantity, amount, payment_id, status, order_time, PRIMARY KEY( (order_id, item_id), order_time)] with clustering ORDER BY (order_time DESC);
Так вот,
Первичный ключ
Ключ раздела
Ключ кластеризации для определенного раздела записи будут упорядочены по
Составной ключ — это просто термин, указывающий, что первичный ключ таблицы — это не один столбец, а несколько столбцов.
Первичный ключ представляет собой комбинацию ключа раздела и ключа кластеризации.
Мне бы хотелось поговорить с вами, поскольку ни один из ответов не помог мне понять , что они на самом деле означают.
Partition key
группирует ваши данные на основе их уникальности. Все, у кого одинаковый ключ, попадают в один и тот же раздел .
Clustering key
, с другой стороны, однозначно идентифицирует строку внутри раздела .
Например, у нас есть таблица:
CREATE TABLE temperature_readings (
sensor_id text,
time timestamp,
temperature float,
PRIMARY KEY (sensor_id, time)
)
в котором мы будем хранить показания датчика температуры по адресу .
является ключом раздела и является ключом кластеризации .
Мы можем загрузить много строк с одним и тем жеsensor_id
и они будут храниться в одном разделе, отсортированные по ихtime
. Для каждого датчика они будут «сгруппированы» (и физически сохранены на одном узле Cassandra).
Я представляю это так:
+-----------+------------+--------------
| sensor_id | time | other row data...
+-----------+------------+--------------
| 1 | 1682615843 |
| +------------+
| | 1682615848 |
| +------------+
| | 1682615890 |
+-----------+------------+
| 2 | 1682615111 |
| +------------+
| | 1682615123 |
+-----------+------------+
| 99909 | 1682615688 |
| +------------+
and so on...
(Хотя это неверно с точки зрения того, как фактические данные физически хранятся на диске.)
Cassandra использует особый тип первичного ключа, называемый составным ключом (или составным ключом), для представления групп связанных строк, также называемых разделами. Составной ключ состоит из ключа раздела и дополнительного набора столбцов кластеризации. Ключ раздела используется для определения узлов, в которых хранятся строки, и сам может состоять из нескольких столбцов.
Отказ от ответственности: это ответ относится к DynamoDB, однако концепции применимы и к Cassandra, поскольку обе являются базами данных NoSQL.
При создании таблицы, помимо имени таблицы, необходимо указать первичный ключ таблицы. Первичный ключ однозначно идентифицирует каждый элемент в таблице, так что никакие два элемента не могут иметь один и тот же ключ.
DynamoDB поддерживает два разных типа первичных ключей:
Ключ раздела - простой первичный ключ , состоящий из одного атрибута, известного как ключ раздела.
DynamoDB использует значение ключа раздела в качестве входных данных для внутренней хэш-функции. Выходные данные хэш-функции определяют раздел (физическое хранилище, внутреннее для DynamoDB), в котором будет храниться элемент.
В таблице, которая имеет только ключ раздела, никакие два элемента не могут иметь одинаковое значение ключа раздела.
Ключ раздела и ключ сортировки. Этот тип ключа, называемый составным первичным ключом , состоит из двух атрибутов. Первый атрибут - это ключ раздела, а второй атрибут - это ключ сортировки.
DynamoDB использует значение ключа раздела в качестве входных данных для внутренней хэш-функции. Выходные данные хэш-функции определяют раздел (физическое хранилище, внутреннее для DynamoDB), в котором будет храниться элемент. Все элементы с одинаковым значением ключа раздела хранятся вместе в отсортированном порядке по значению ключа сортировки.
В таблице с ключом раздела и ключом сортировки два элемента могут иметь одно и то же значение ключа раздела. Однако эти два элемента должны иметь разные значения ключа сортировки.
Составной первичный ключ дает вам дополнительную гибкость при запросе данных. Например, если вы указываете только значение «Исполнитель», DynamoDB извлекает все песни этого исполнителя. Чтобы получить только подмножество песен определенного исполнителя, вы можете указать значение для Artist вместе с диапазоном значений для SongTitle.
Примечание. Ключ раздела элемента также известен как его атрибут хэша. Термин «атрибут хеширования» происходит от использования внутренней хеш-функции в DynamoDB, которая равномерно распределяет элементы данных по разделам на основе значений их ключей раздела.
Ключ сортировки из пункта также известен в качестве атрибута диапазона. Атрибут диапазона терминов является производным от способа, которым DynamoDB хранит элементы с одним и тем же ключом раздела, физически близко расположенные друг к другу, в порядке сортировки по значению ключа сортировки.
В проектировании базы данных составной ключ - это набор суперключей, который не является минимальным.
Составной ключ - это набор, который содержит составной ключ и хотя бы один атрибут, который не является суперключем
Данная таблица: 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}) и атрибут, который не является суперключем ({фамилия}).