Модель данных Кассандры

Я новичок в cassandra, пытаясь понять, как я могу смоделировать наши текущие данные sql в cassandra. В базе данных хранятся метаданные документов, в том числе document_id, last_modified_time, size_in_bytes среди множества других данных, а количество документов может быть сколь угодно большим, поэтому мы ищем масштабируемое решение для хранения и запросов.

Требуется 2 запроса диапазона

  1. выберите все документы, где last_modified_time>=x и last_modified_time
  2. выберите все документы, где размер >= x и размер ‹= y

А также набор запросов, в которых документы должны быть сгруппированы по определенным метаданным, например.

  1. выбрать все документы, в которых пользователь находится (x, y, z)

Как лучше всего разрабатывать модель данных на основе этих запросов?

Моя первоначальная мысль заключалась в том, чтобы иметь таблицу (в Cassandra 2.0, CQL 3.0) с last_mod_time в качестве вторичного индекса следующим образом.

создать таблицу t_document (document_id bigint,
last_mod_time bigint, размер bigint, пользовательский текст, .... первичный ключ (document_id, last_mod_time) }

Это должно позаботиться о запросе 1.

Нужно ли мне создавать другую таблицу с первичным ключом (document_id, size) для запроса 2? Или я могу просто добавить размер в качестве третьего элемента в первичный ключ той же таблицы, например. (document_id, last_mod_time, размер). Но в этом случае второй запрос будет работать без использования last_mod_time в предложении where?

Для запроса 3, который представляет собой все документы для одного или нескольких пользователей, лучше всего создать таблицу t_user_doc, где первичный ключ (пользователь, doc_id)? Или лучше создать вторичный индекс для пользователя в той же таблице t_document?

Спасибо за любую помощь.


person ssen    schedule 08.04.2014    source источник


Ответы (1)


Когда дело доходит до неравенства, в Cassandra у вас не так много вариантов. Они должны быть ведущими столбцами кластеризации (или вторичными индексами). Таким образом, модель данных может выглядеть так:

CREATE TABLE docs_by_time (
dummy int,
last_modified_time timestamp,
document_id bigint,
size_in_bytes bigint,
PRIMARY KEY ((dummy),last_modified_time,document_id));

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

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

Вы можете создать вторичные индексы для таблицы:

CREATE TABLE docs (
document_id bigint,
last_modified_time timestamp,    
size_in_bytes bigint,
PRIMARY KEY ((dummy),last_modified_time,document_id));

CREATE INDEX docs_last_modified on docs(last_modified);

Однако вторичные индексы имеют важные недостатки (http://www.slideshare.net/edanuff/indexing-in-cassandra) и не рекомендуются для данных с большим количеством элементов. Вы можете несколько смягчить проблему кардинальности, уменьшив точность last_modified_time, скажем, сохранив только компонент дня.

person Marc Fielding    schedule 03.02.2015