2016-02-29 5 views
7

Я новичок в базе данных NoSQL и только что начал использовать apache Cassandra. Я создал простую таблицу «emp» с первичным ключом на столбце «empno». Это простая таблица, так как мы всегда получаем схему Oracle scott по умолчанию.Где и заказ по статьям Cassandra CQL

Теперь я загрузил данные, используя команду COPY и выдается запрос Select * from emp order by empno, но я был удивлен, что CQL не позволяют упорядочить по empno на колонке (который является ПК). Также, когда я использовал условие Where, он не допустил никаких операций неравенства на столбце empno (он сказал, что разрешены только условия EQ или IN). Он также не разрешил «Куда» и «Заказ» в любой другой колонке, так как они не были использованы в ПК и не имели индекса.

Может кто-нибудь, пожалуйста, помогите мне, что мне делать, если я хочу сохранить empno уникальным в таблице и хочу, чтобы результаты запроса были отсортированы по порядку empno?

(Моя версия:

cqlsh:demodb> show version [cqlsh 5.0.1 | Cassandra 2.2.0 | CQL spec 3.3.0 | Native protocol v4] )

ответ

10

Есть две части первичного ключа в Кассандре:

  • ключа раздела (ов)
  • ключа кластеризации (ов)

PRIMARY KEY (partitionKey1,clusteringKey1,clusteringKey2)

или

PRIMARY KEY ((partitionKey1,partitionKey2),clusteringKey1,clusteringKey2)

Ключ раздел определяет, какой узел (ы) ваши данные, хранящиеся на. Клавиша кластеризации определяет порядок данных внутри вашего ключа раздела.

В CQL предложение ORDER BY действительно используется только для обратного определенного направления сортировки вашего кластерного заказа. Что касается самих столбцов, вы можете указать только определенные столбцы (и в этом точном порядке ... без пропусков) в своем предложении CLUSTERING ORDER BY во время создания таблицы. Таким образом, вы не можете выбрать произвольные столбцы, чтобы упорядочить набор результатов во время запроса.

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

Select * from emp order by empno; 

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

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

CREATE TABLE emp_by_dept (
    empno text, 
    dept text, 
    name text, 
    PRIMARY KEY (dept,empno) 
) WITH CLUSTERING ORDER BY (empno ASC); 

Теперь я могу запросить сотрудников по отделам, и они будут возвращены мне по заказу empno:

SELECT * FROM emp_by_dept WHERE dept='IT'; 

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

Приносим извинения за саморекламу, но в прошлом году я написал статью для DataStax под названием We Shall Have Order!, в которой я обратился к решению этих проблем. Дайте ему прочитать и посмотрите, поможет ли это.

Редактировать дополнительные вопросы:

Из вашего ответа я заключил 2 вещи о Кассандре:

(1) Там нет способа получения результирующего набора, который только упорядочить по столбцу, имеет , который определяется как уникальный.

(2) Когда мы определим PK (раздел ключа + кластерный ключ), то результаты всегда будут порядком по Кластеризации столбцов в любом ключе Отсечки (мы должны ограничить один раздел ключа значения), это означает, что нет необходимости в ORDER BY , поскольку он никогда не может изменить порядок строк (порядок в , которые фактически хранятся), то есть Order By бесполезен.

1) Все ОСНОВНЫЕ КЛЮЧИ в Кассандре уникальны. Невозможно заказать свой результирующий набор с помощью ключа раздела. В моем примере я заказываю empno (после разбиения по отделам). - Aaron 1 час назад

2) Не останавливаясь на том, что ORDER BY бесполезен, я скажу, что его единственное реальное использование - переключить направление сортировки между ASC и DESC.

Я создал индекс по колонке "Empno" таблицы "EMP", она до сих пор не позволяя ORDER BY EMPNO. Итак, для каких индексов? они предназначены только для для поиска записей для определенного значения ключа индекса?

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

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

Исправить.

Следовательно, для каждого нового требования нам необходимо создать новую таблицу. IT означает, что если у нас есть миллиард строк в таблице (например, таблица продаж) и , нам нужна сумма продаж (1) по продукту, (2) по регионам, то мы будем дублировать все эти миллиарды строк в 2 таблицы с одним в кластеризации заказ товара, другой в порядке кластеризации Region. и даже , если нам нужно суммировать продажи на Salesman_id, тогда мы построим 3-й стол, снова положив все эти миллиарды строк? это разумно?

Это действительно зависит от вас, чтобы решить, насколько это разумно. Но недостаток гибкости запросов является недостатком Cassandra. Чтобы обойти это, вы можете продолжать создавать таблицы запросов (I.E., торговый диск для повышения производительности). Но если это доходит до того, что становится неуправляемым или трудным для управления, тогда пришло время подумать о том, действительно ли Кассандра является правильным решением.

EDIT 20160321

Привет Аарон, вы сказали выше «доходя говорить, что ORDER BY бесполезно, я скажу, что его единственное реальное использование, переключив направление сортировки между ASC и DESC «.

Но я нашел, что это неверно. Cassandra разрешает ORDER только в том же направлении, который мы определяем в «CLUSTERING ORDER BY» для CREATE TABLE. Если в этом пункте мы определяем ASC, он допускает только порядок от ASC и наоборот.

Не просматривая сообщение об ошибке, сложно знать, что сказать об этом. Хотя я слышал о запросах с ORDER BY, если у вас слишком много строк, хранящихся в разделе.

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

InvalidRequest: code=2200 [Invalid query] message="Unsupported order by relation" 

Я думаю, что это связано с тем, как данные хранятся на диске. В противном случае у Кассандры будет больше работы по подготовке наборов результатов. Если для этого требуется либо совмещение, либо зеркальное отображение направлений (направлений), указанных в CLUSTERING ORDER BY, оно может просто передать последовательное чтение с диска. Поэтому лучше всего использовать только один столбец в вашем предложении ORDER BY для получения более предсказуемых результатов.

+0

Спасибо за подробный ответ! Я ценю. Из вашего ответа я сделал две вещи о Кассандре: (1) Нет способа получить набор результатов, который является только порядком по столбцу, который был определен как уникальный, и (2) Когда мы определяем PK (раздел-ключ + кластерный ключ), то результаты всегда будут упорядочиваться кластерами столбцов в любом фиксированном ключе раздела (мы должны ограничить одно значение ключа раздела), это означает, что нет необходимости в предложении ORDER BY, поскольку он никогда не может изменить порядок строк (порядок, в котором строки фактически хранятся), то есть Order By бесполезен. –

+0

Хорошо, еще раз спасибо. Еще одна вещь, я создал индекс на столбце «empno» таблицы «emp», он все еще не разрешает ORDER BY empno. Итак, для каких индексов? они предназначены только для поиска записей для определенного значения ключа индекса? –

+0

Хорошо, это просто означает, что одна таблица не может использоваться для получения разных наборов результатов с разными условиями и разными порядками сортировки. Следовательно, для каждого нового требования нам нужно создать новую таблицу. IT означает, что если у нас есть миллиард строк в таблице (например, таблица Sales), и нам нужна сумма продаж (1) Product-wise, (2) Region-wise, то мы будем дублировать все эти миллиарды строк в 2 таблицах с помощью одного в порядке кластеризации продукта, другой - в порядке кластеризации Region. и даже если нам нужно суммировать продажи в Salesman_id, то мы построим 3-ю таблицу, снова положив все эти миллиарды строк? это разумно? –

Смежные вопросы