Кассандра меняет первичный ключ против запуска множественных запросов выбора - PullRequest
0 голосов
/ 08 января 2019

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

create table my_keyspace.userproducts{
  userid,
  username,
  productid,
  productname,
  producttype,
Primary Key(userid)
}

Все пользователи принадлежат группе, может быть от 1 до 100 пользователей в группе

userid|groupid|groupname|
1     |g1     | grp1  
2     |g2     | grp2  
3     |g3     | grp3  

У нас есть новое требование для отображения всех продуктов для всех пользователей в одной группе.

Итак, я могу изменить свои пользовательские продукты, чтобы мой ключ раздела теперь стал идентификатором группы, а идентификатор пользователя использовался в качестве ключа кластера, чтобы я мог получить все свои результаты в одном запросе.

Или я сохраняю свой дизайн таблицы как есть и запускаю несколько запросов на выборку, выбирая всех пользователей в группе из второй таблицы, а затем запускаю один запрос на выборку для каждого пользователя, объединяю данные в моем коде и затем возвращаю их пользователям

Спасибо.

1 Ответ

0 голосов
/ 08 января 2019

Даже перед тем, как перейти к вашему вопросу, у вашего моделирования данных, как вы его представили, есть проблема: вы говорите, что хотите сохранить «список продуктов, которые есть у пользователя». Но это не та таблица, которую вы представили - у вашей таблицы есть один продукт для каждого идентификатора пользователя. «Идентификатор пользователя» - это ключ вашей таблицы, и каждая запись в таблице, т. Е. Каждый уникальный идентификатор пользователя, имеет одну комбинацию других полей.

Если вы действительно хотите, чтобы у каждого пользователя был список продуктов, первичный ключ должен быть (userid, productid). Это означает, что каждая запись индексируется с помощью и ИД пользователя и продукта, или, другими словами, - ИД пользователя имеет список записей, каждая из которых имеет свой собственный продукт. Cassandra позволяет эффективно извлекать все производимые записи для одного идентификатора пользователя, поскольку она реализует первую часть ключа как «ключ раздела», а вторая часть - «ключ кластеризации».

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

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

Вы также можете достичь аналогичной цели в Cassandra, используя функцию Secondary Index , которая имеет свои собственные характеристики производительности (в некоторых отношениях она аналогична решению «несколько запросов»).

...