2016-02-01 4 views
1

Предположит, у меня есть таблица со следующей структурой create table tasks ( user_id uuid, name text, task_id uuid, description text, primary key ((user_id), name, task_id) ); Как правильно выбрать структуру таблиц в кассандре?

Это позволяет мне получить все задачи для отсортированного по name возрастанию пользователя. Также я добавил task_id в первичный ключ, чтобы избежать воссоздания. Следующий запрос имеет select * from tasks where user_id = ? , а также select * from tasks where user_id = ? and name > ?

Однако, я не могу получить задание с конкретным task_id. Например, после запроса аварий select * from tasks where user_id = ? and task_id = ? с этой ошибкой PRIMARY KEY column "task_id" cannot be restricted as preceding column "name" is not restricted Это требует name столбца должны быть указано, но на данный момент у меня есть только task_id (из URL, например) и user_id (от сессии).

Как создать эту таблицу для выполнения обоих запросов? Или мне нужна отдельная таблица для второго случая? Какова общая картина в этой ситуации?

ответ

1

Вы можете просто добавить еще один избыточный столбец taskId с тем же значением, что и task_id, и создать вторичный индекс для taskId. Тогда вы можете запросить user_id=? and tsakId=?

+0

Я рассматривал этот вариант, на самом деле он работает.Но я думаю, что это может быть неуместным в случае столбцов с высокой мощностью. В этом случае мы сужим запрос user_id, и кажется, что количество задач для пользователя невелико. Таким образом, индекс может помочь. Но что, если у меня есть сотни тысяч строк, и мне нужно найти конкретный. Индекс может быть неэффективным? – AskhatOmarov

0
PRIMARY KEY column "task_id" cannot be restricted as preceding 
    column "name" is not restricted 

Вы видите эту ошибку, потому что CQL не разрешает запросы пропустить первичные ключевые компоненты.

Как создать эту таблицу для выполнения обоих запросов? Или мне нужна отдельная таблица для второго случая? Какова общая картина в этой ситуации?

Как вы подозреваете, типичный способ решения таких проблем с помощью Cassandra заключается в том, что для каждого запроса создается дополнительная таблица. В этом случае, воссоздавая таблицу с первичным ключом разработан, чтобы соответствовать вашему дополнительному образцу запроса будет просто выглядеть следующим образом:

create table tasks_by_user_and_task (
    user_id uuid, 
    name text, 
    task_id uuid, 
    description text, 
    primary key ((user_id), task_id) 
); 

Вы можете просто добавить еще один избыточный столбец TaskId с таким же значением, как TASK_ID и создать вторичный индекс на taskId.

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

Возможно, неплохо было бы моделировать и тестировать оба решения для производительности.

0

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

create table tasks_by_name (
    user_id uuid, 
    name text, 
    task_id uuid, 
    description text, 
    primary key ((user_id), name, task_id) 
); 

create table tasks_by_id (
    user_id uuid, 
    name text, 
    task_id uuid, 
    description text, 
    primary key ((user_id), task_id) 
); 
Смежные вопросы