Cassandra: выбор ключа раздела
Я не решил, лучше ли, с точки зрения производительности, использовать очень распространенное значение столбца (например,Country
) в качестве ключа раздела для составного первичного ключа или довольно уникального значения столбца (например,Last_Name
).
смотрим документация Cassandra 1.2 о индексах Я понимаю:
"когда использовать индекс: Кассандра встроенные индексы на таблице наличие многих строк, содержащих индексированное значение. более уникальным значения, существующие в определенном столбце, тем больше накладных расходов должны, в среднем, запрашивать и поддерживать индекс. например, предположим, у вас есть таблица пользователей с миллиардом пользователей и вы хотите посмотреть пользователей по состоянию, в котором они жили. многие пользователи будут делиться тем же значение столбца для состояния (например, CA, NY,TX и т. д.). Это будет хороший кандидат для индекса."
"если не использовать индекс: Не используйте индекс для запроса большого объема записей для небольшого количество результатов. Например, при создании индекса для столбца это имеет много различных значений, запрос между полями будет выполняться многие стремятся к очень немногим результатам. в таблице с миллиардом пользователей, поиск пользователей по адресу электронной почты (значение, которое обычно уникальный для каждого пользователя), а не по их состоянию, скорее всего, будет очень неэффективный. вероятно, было бы более эффективно вручную поддерживать таблица как форма индекса вместо использования Cassandra встроенный индекс. Для столбцов, содержащих уникальные данные, иногда высокое качество-разумно использовать индекс для удобства, пока том запроса к таблице, имеющей индексированный столбец, является умеренным и не под постоянной нагрузкой."
глядя на примеры из выберите CQL по на
"запрос составных первичных ключей и результаты сортировки" я вижу что-то вроде UUID, используемого в качестве ключа раздела... что указывает на то, что предпочтительнее использовать что-то довольно уникальное?
3 ответов
индексирование в документации, что вы написали, относится к вторичным индексам. В Кассандре есть разница между первичным и вторичным индексами. Для вторичного индекса было бы действительно плохо иметь очень уникальные значения, однако для компонентов в первичном ключе это зависит от того, на каком компоненте мы фокусируемся. В первичном ключе мы имеем следующие компоненты:
первичный ключ(ключ секционирования, кластеризация key_1 ... кластеризация key_n)
ключ секционирования используется для распределения данных по разным узлам, и если вы хотите, чтобы ваши узлы были сбалансированы (т. е. хорошо распределенные данные по каждому узлу), то вы хотите, чтобы ваш ключ секционирования был как можно более случайным. Вот почему в вашем примере используется UUIDs.
используется ключ кластеризации на заказ так что запрос столбцы с определенным ключом кластеризации может быть более эффективным. Вот где вы хотите, чтобы ваши ценности не быть уникальным и где будет хит производительности, если уникальные строки были частыми.
на cql документы есть хорошее объяснение того, что происходит.
Если вы используете cql3, учитывая семейство столбцов:
CREATE TABLE table1 (
a1 text,
a2 text,
b1 text,
b2 text,
c1 text,
c2 text,
PRIMARY KEY ( (a1, a2), b1, b2) )
);
определив a первичный ключ ((a1, a2,...), b1, b2,... )
Это означает, что:
a1, a2,... используются ли поля для создания ключа строки, чтобы:
- определите, как данные секционируются
- определите, что физически хранится в одной строке
- называется ключом строки или ключом раздела
b1, b2,... семейный колонки поля, используемые для кластеризации ключа строки, чтобы:
- создание логических наборов внутри одной строки
- позволит более гибкие схемы, такие как диапазон
- называется ключом столбца или ключом кластера
все остальные поля эффективно мультиплексируются / дублируются для каждой возможной комбинации клавиш столбцов. Ниже приведен пример работы составных ключей с ключами разделов и ключами кластеризации.
Если вы хотите использовать запросы диапазона, вы можете использовать вторичные индексы или (начиная с cql3) вы можете объявить эти поля как ключи кластеризации. С точки зрения скорости, имея их в качестве ключа кластеризации, будет создана одна широкая строка. Это влияет на скорость, так как вы получите несколько значений ключа кластеризации, таких как:
select * from accounts where Country>'Italy' and Country<'Spain'
Я уверен, что вы получили бы ответ, но все же это может помочь вам лучше понять.
CREATE TABLE table1 (
a1 text,
a2 text,
b1 text,
b2 text,
c1 text,
c2 text,
PRIMARY KEY ( (a1, a2), b1, b2) )
);
здесь ключи раздела (a1,a2) и ключи строки b1, b2.
сочетание клавиш разделов и клавиш строк должно быть уникальным для каждой новой записи.
вышеуказанный первичный ключ можно определить следующим образом.
Node< key, value>
Node<(a1a2), Map< b1b2, otherColumnValues>>
как известно Ключевые Разделы отвечает за распространение данных через ваш узлы.
Итак, если вы вставляете 100 записей в table1 с одинаковыми ключами разделов и разными ключами строк. он будет хранить данные в одном узле, но в разных столбцах.
логически мы можем представить, как это.
Node<(a1a2), Map< string1, otherColumnValues>, Map< string2, otherColumnValues> .... Map< string100, otherColumnValues>>
таким образом, запись будет храниться последовательно в памяти.