2015-07-22 2 views
2

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

Теперь я не уверен, что если у меня есть несколько keys (или составных клавиш), это комбинация ключей, используемых для разделения данных, или это будет первый первичный ключ?

В качестве примера, для одной семьи ключа столбца, такие как:

CREATE TABLE IF NOT EXISTS users (
    userid uuid, 
    emailaddress text, 
    birthday timestamp, 
    PRIMARY KEY (userid) 
); 

Я знаю, что userid используется для того, чтобы определить, в какой узел (ы) строка типа users должна быть разделена.

Если изменить эту таблицу, чтобы

CREATE TABLE IF NOT EXISTS users (
    userid uuid, 
    emailaddress text, 
    birthday timestamp, 
    PRIMARY KEY (userid, emailaddress) 
); 

Означает ли это, что теперь userid и emailaddress собираются быть использованы вместе для того, чтобы определить разделы?

Возможно ли, чтобы две строки имели одинаковые userid, но разные emailaddress выделялись в двух отдельных узлах или всегда были бы в одном узле?

Большое спасибо,

ответ

5

На самом деле в вашем примере

CREATE TABLE IF NOT EXISTS users (
    userid uuid, 
    emailaddress text, 
    birthday timestamp, 
    PRIMARY KEY (userid, emailaddress) 
); 

идент раздел ключевой частью и EMAILADDRESS является кластеризация столбец и в cqlsh

cqlsh:rw> CREATE TABLE users (userid INT, email TEXT, data TEXT, PRIMARY KEY (userid, email)); 
cqlsh:rw> SELECT * FROM users WHERE userid = 0; 

userid | email | data  

Partition ключевая часть определяется внутренним скобы()

CREATE TABLE IF NOT EXISTS users (
    userid uuid, 
    emailaddress text, 
    birthday timestamp, 
    PRIMARY KEY ((userid, emailaddress)) 
); 

теперь вы будете иметь ключ, состоящий из разделов ID_пользователя и EMAILADDRESS и cqlsh снова

cqlsh:rw> CREATE TABLE users (userid INT, email TEXT, data TEXT, PRIMARY KEY ((userid, email)));                                          
cqlsh:rw> SELECT * FROM users WHERE userid = 0; 
code=2200 [Invalid query] message="Partition key part email must be restricted since preceding part is"  

Теперь Ваш вопрос -> да, это возможно потому, что у вас есть композитный ключ раздела ключевую роль только в качестве идентификатора пользователя.

Интересный источник информации: http://docs.datastax.com/en/cql/3.1/cql/cql_reference/refCompositePk.html

Хороший инструмент для попыток является cqlsh - это поможет вам испытать много вещей.Например, в cqlsh вывода разделов ключевых столбцов красный, кластеризация столбцы Cyan/синий и столбцы данных фиолетовый - очень полезно

Обновление для комментария Продолжаем втором случае запроса

cqlsh:rw> SELECT * FROM users WHERE userid = 0 AND email = ''; 

userid | email | data 
--------+-------+------ 

будет успешным, так как результат вы должны всегда указывать USERID и адрес электронной почты

для запроса одного пользователя и много электронной почты адреса вы можете использовать

SELECT * FROM users WHERE userid = 0 AND email IN ('a', '4'); 

userid | email | data 
--------+-------+------ 

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

В первом случае

CREATE TABLE users (userid INT, email TEXT, data TEXT, PRIMARY KEY (userid, email)); 
INSERT INTO users (userid, email , data) VALUES(0, '[email protected]', 'ddd'); 
INSERT INTO users (userid, email , data) VALUES(0, '[email protected]', 'ddd1111'); 

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

cqlsh:rw> SELECT * FROM users WHERE userid = 0; 

userid | email  | data 
--------+-------------+--------- 
     0 | [email protected] | ddd1111 
     0 | [email protected] |  ddd 
+0

Большое вам спасибо за это. У меня есть еще один вопрос. Если я сделаю это по-своему, т. Е. У меня есть '((userid, emailaddress))' в качестве моего ключа раздела, я все еще смогу выполнить поиск ТОЛЬКО с помощью идентификатора пользователя, не указав адрес электронной почты? В моем примере я бы мог, но я не уверен, что смогу это сделать, если оба они являются ключами разделов. – kha

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