Как избежать вторичных индексов в Кассандре?
Я неоднократно слышал, что вторичные индексы (в Кассандре) предназначены только для удобства, но не для повышения производительности. Единственный случай, когда рекомендуется использовать вторичные индексы, когда у вас низкая кардинальность (например, пол column
который имеет два значения мужской или женский)
рассмотрим этот пример:
CREATE TABLE users (
userID uuid,
firstname text,
lastname text,
state text,
zip int,
PRIMARY KEY (userID)
);
Прямо сейчас я не могу сделать этот запрос, если я не создаю вторичный индекс на users
на firstname index
select * from users where firstname='john'
Как мне денормализовать эту таблицу так, чтобы у меня мог быть такой запрос: это единственный эффективный способ с использованием составных ключей? Любые другие альтернативы или предложения?
CREATE TABLE users (
userID uuid,
firstname text,
lastname text,
state text,
zip int,
PRIMARY KEY (firstname,userID)
);
3 ответа
Чтобы создать хорошую модель данных, вам нужно определить первые ВСЕ запросы, которые вы хотели бы выполнить. Если вам нужно искать пользователей только по имени (или имени и идентификатору пользователя), тогда ваш второй дизайн в порядке...
Если вам также нужно искать пользователей по их фамилии, то вы можете создать другую таблицу с такими же полями, но с включенным первичным ключом (фамилия, ID пользователя). Очевидно, вам нужно будет обновить обе таблицы одновременно. Дублирование данных в Кассандре прекрасно.
Тем не менее, если вас беспокоит пространство, необходимое для двух или более таблиц, вы можете создать одну таблицу пользователей, разделенную по идентификатору пользователя, и дополнительные таблицы для полей, по которым вы хотите запросить:
CREATE TABLE users (
userID uuid,
firstname text,
lastname text,
state text,
zip int,
PRIMARY KEY (userID)
);
CREATE TABLE users_by_firstname (
firstname text,
userid uuid,
PRIMARY KEY (firstname, userid)
);
Недостатком этого решения является то, что вам потребуется два запроса для получения пользователей по имени:
SELECT userid FROM users_by_firstname WHERE firstname = 'Joe';
SELECT * FROM users WHERE userid IN (...);
Надеюсь это поможет
Есть несколько способов сделать это, все с плюсами и минусами.
Ваш второй запрос будет работать, но это просто таблица индексов. http://wiki.apache.org/cassandra/SecondaryIndexes Вторичный индекс может быть полезен, и если вы сначала нажмете на раздел (что вы не можете сделать в первой таблице), то реализация cassandra избавит вас от хлопот и сохранит вещи "местные атомные". Однако без попадания в раздел ваша первая таблица с индексом будет не очень удачной для вашего запроса, поскольку она повсеместно попадет во все.
Вы можете полностью денормализовать, но вы также можете сделать таблицу поиска. т.е. ваша вторая таблица может существовать только для возврата идентификатора пользователя. Затем вы можете выполнить второй запрос, чтобы получить информацию только для соответствующих разделов. Если вы ожидаете мало результатов, это может быть хорошо. Если нет, то вы столкнетесь с большим количеством разделов на многих узлах (что в зависимости от размера кластера и критериев избегания точек доступа может быть хорошим или плохим). Выполнение многих запросов ~1 мс обычно лучше, чем выполнение одного запроса ~1000 мс.
Вы можете сделать искусственное группирование и выполнить запросы n=bucketcount. Это имеет дополнительные издержки, но уменьшает количество запросов и может быть хорошим вариантом.
Ваш индекс может быть из первых нескольких символов имени. Или это может быть последовательный хэш в несколько блоков. Первый может дать вам "начинается с" семантики.
Это всего лишь несколько вариантов. Переход от логической модели данных к физической требует оценки того, какие компромиссы вы хотите сделать.
Существуют также материализованные представления с автоматическими обновлениями, которые разбивают данные на разные столбцы, поэтому ускорение чтения значительно ускоряется, а вторичные индексы полностью исключаются. Есть некоторые дополнительные преимущества сделать это самостоятельно.
Общая идея избегать горячих перегородок все еще остается.
И затем, есть также индекс SASI, если вы делаете много обновлений первичного ключа материализованного представления, чтобы избежать надгробий.