почему ключ кластеризации называется «ключ кластеризации» в Кассандре? - PullRequest
0 голосов
/ 05 июля 2018

Таблица-1:

create table mylistofitems (listid int, 
  itemid int, 
  quantity int, 
  itemdesc text, 
  primary key ((listid, itemid), itemdesc));

В приведенной выше таблице я делаю следующие вставки:

insert into mylistofitems (listid, itemid, itemdesc, quantity) values (1, 1000, 'apple', 5);
insert into mylistofitems (listid, itemid, itemdesc, quantity) values (1, 1000, 'banana', 10);
insert into mylistofitems (listid, itemid, itemdesc, quantity) values (1, 1000, 'orange', 6);
insert into mylistofitems (listid, itemid, itemdesc, quantity) values (1, 1000, 'orange', 50);

когда я выбираю * из списка mylistofitems, я получаю следующее:

 listid | itemid | itemdesc | quantity
--------+--------+----------+----------
      1 |   1000 |    apple |        5
      1 |   1000 |   banana |       10
      1 |   1000 |   orange |       50

Второй оператор вставки НЕ перезаписал 1-ю строку. Но четвертый оператор вставки перезаписал третий ряд.

В этом контексте, что означает ключ кластеризации?

Таблица-2:

create table myitems (listid int,
  itemid int, 
  idesc text, 
  qty int,
  primary key (listid, itemid));

Я вставляю в таблицу 2 следующие записи:

insert into myitems (listid, itemid, idesc, qty) values (1, 1000,
'apple', 5);
insert into myitems (listid, itemid, idesc, qty) values (1, 1000, 'banana', 10);
insert into myitems (listid, itemid, idesc, qty) values (1, 1000, 'orange', 6);
insert into myitems (listid, itemid, idesc, qty) values (1, 1000, 'orange', 50);

Запросы на вставку в таблице-2 точно такие же, как и в таблице-1. Но когда я выбираю * из myitems, я удивляюсь, увидев только одну строку, которая была вставлена ​​последней. Остальные все ряды потеряны. т.е. каждый оператор вставки перезаписывал предыдущую запись.

 listid | itemid | idesc  | qty
--------+--------+--------+-----
      1 |   1000 | orange |  50

Вопрос: Почему он ведет себя по-разному в таблице-2 по сравнению с таблицей-1? Что означает кластеризация ключа в этом контексте? Почему ключ кластеризации был назван «Ключ кластеризации». Это как-то связано с кластером кассандры?

Вопрос по обновлению: Я попытался сделать обновление таблицы-1:

update mylistofitems set quantity = 100 where listid = 1 and itemid = 1000;

Это говорит об ошибке 2200, некоторые ключи кластеризации отсутствуют. Почему это ограничено?

Ответы [ 2 ]

0 голосов
/ 07 июля 2018

Я бы хотел ответить на свой вопрос, чтобы закрыть эту ветку. Также, чтобы помочь другим, у которых были бы те же самые беспорядки:

В основном я рассматривал концепцию первичного ключа, ключа раздела, ключа кластеризации.

Первичный ключ таблицы-1:

primary key ((listid, itemid), itemdesc));

Это означает, что listid + itemid - это просто ключ раздела, помогающий записи найти свой узел для доступа.

Фактическая уникальность будет сохраняться только для комбинации listid + itemid + itemdesc.

В итоге:

listid+itemid = composite partition key
listid+itemid+itemdesc = composite primary key
itemdesc = clustering key 

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

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

Это сильно отличается от RDBMS. В мире RDBMS вы используете группирование и упорядочение во время поиска, как вы хотите. В Cassandra мы используем группировку и упорядочение во время самой вставки, чтобы ваш поиск был быстрее (в зависимости от используемых запросов)

Таблица-2 определяется как первичный ключ (listid, itemid), что означает:

listid = standalone partition key
itemid = standalone clustering key
listid + itemid = composite primary key
0 голосов
/ 05 июля 2018

Что такое ключ кластеризации?

Ключи кластеризации определяют, как данные хранятся на диске. Это одна из причин того, что Кассандра такая работоспособная. Поскольку порядок столбцов изменяет способ хранения данных, важно, чтобы вы знали, что они управляются во внутренних органах Cassandra.

Визуализация данных на диске в виде массива. Это эффективно, как Кассандра будет хранить ваши данные. Вот как будет выглядеть первая таблица после первых 3 запросов:

table1 =
(listid(1) - itemid(1000)) // Partition key
    idesc('apple') // Clustering key
        = {listid: 1, itemid: 1000, idesc: apple, qty: 5}
    idesc('banana') // Clustering key
        = {listid: 1, itemid: 1000, idesc: banana, qty: 10}
    idesc('orange') // Clustering key
        = {listid: 1, itemid: 1000, idesc: orange, qty: 6}

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

table1 =
(listid(1) - itemid(1000)) // Partition key
    idesc('apple') // Clustering key
        = {listid: 1, itemid: 1000, idesc: apple, qty: 5}
    idesc('banana') // Clustering key
        = {listid: 1, itemid: 1000, idesc: banana, qty: 10}
    idesc('orange') // Clustering key
        = {listid: 1, itemid: 1000, idesc: orange, qty: 50}

Отсутствует раздел / ключ кластеризации

Возьмите следующие запросы и мои примеры доступа к данным, как это сделала бы Кассандра.

  1. WHERE listid IN (1, 2) and itemid = 1000

    result = (data[1-1000], data[2-1000])

  2. WHERE listid = 1 AND itemid = 1000 AND idesc = 'apple'

    result = data[1-1000]['apple']

  3. WHERE idesc = 'apple'

    result = data[????]['apple']

    C * не будет знать, какой индекс искать apple.

Важно отметить, что это то же самое при вставке или обновлении данных. Давайте в качестве примера используем ваш запрос UPDATE.

UPDATE mylistofitems SET quantity = 100 WHERE listid = 1 AND itemid = 1000;

С помощью этого запроса вы пытаетесь сделать это:

`data[1-1000][????] = {listid: 1, itemid: 1000, idesc:????, qty: 1000}`

C * не знает, в каком индексе хранить данные.

Вы должны обновить свой запрос следующим образом:

UPDATE mylistofitems SET quantity = 100 WHERE listid = 1 AND itemid = 1000 AND idesc = 'orange';

В виде массива это будет выглядеть так:

`data[1-1000]['orange'] = {listid: 1, itemid: 1000, idesc: 'orange', qty: 1000}`

Добавление количества в качестве ключа кластеризации

Если вы добавите quantity в качестве ключа кластеризации, структура данных будет выглядеть следующим образом:

table1 =
(listid(1) - itemid(1000)) // Partition key
    idesc('apple') // Clustering key
        quantity(5) // Clustering key
            = {listid: 1, itemid: 1000, idesc: 'apple', qty: 5}
    idesc('banana') // Clustering key
        quantity(10) // Clustering key
            = {listid: 1, itemid: 1000, idesc: 'banana', qty: 10}
    idesc('orange') // Clustering key
        quantity(6) // Clustering key
            = {listid: 1, itemid: 1000, idesc: 'orange', qty: 6}
        quantity(50 // Clustering key
            = {listid: 1, itemid: 1000, idesc: 'orange', qty: 50}

Это позволит вам иметь несколько строк для каждой комбинации, хотя вы не сможете иметь несколько строк с одинаковыми данными.

Общие правила

  1. Ключи разделения + кластеризации - это уникальные поля *1070* для каждой строки
  2. Нельзя выполнить запрос по ключу, не включив предыдущие ключи в запрос
  3. Cassandra не имеет вставок / обновлений - только upserts
  4. При вставке строки необходимо указать все ключи
...