Cassandra分割复合键

kha*_*kha 2 cassandra cassandra-2.0

据我所知,如果我们有一个主键,则使用此键来分区数据并将其存储在节点中(例如使用随机分区器).

现在我不确定的是,如果我有多个keys(也就是复合键),是用于分区数据的键的组合还是它将成为第一个主键?

例如,对于单个键列族,例如:

CREATE TABLE IF NOT EXISTS users (
    userid uuid,
    emailaddress text,
    birthday timestamp,
    PRIMARY KEY (userid)
);
Run Code Online (Sandbox Code Playgroud)

我知道这userid是用来确定应该对哪一类节点users进行分区.

如果我将此表更改为

CREATE TABLE IF NOT EXISTS users (
    userid uuid,
    emailaddress text,
    birthday timestamp,
    PRIMARY KEY (userid, emailaddress)
);
Run Code Online (Sandbox Code Playgroud)

这是否意味着现在useridemailaddress将要一起使用以确定分区?

是否有可能在两个单独的节点中分配具有相同userid但不同的两行,emailaddress或者它们是否总是在同一节点中?

非常感谢,

Rob*_*ski 5

实际上在你的例子中

CREATE TABLE IF NOT EXISTS users (
    userid uuid,
    emailaddress text,
    birthday timestamp,
    PRIMARY KEY (userid, emailaddress)
);
Run Code Online (Sandbox Code Playgroud)

userid是分区键部分,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       
Run Code Online (Sandbox Code Playgroud)

分区键部分由内括号()定义

CREATE TABLE IF NOT EXISTS users (
    userid uuid,
    emailaddress text,
    birthday timestamp,
    PRIMARY KEY ((userid, emailaddress))
);
Run Code Online (Sandbox Code Playgroud)

现在你将拥有由userid和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"     
Run Code Online (Sandbox Code Playgroud)

现在提出您的问题 - >是的,因为您只有复合键分区键部分作为用户ID.

有趣的信息来源:http: //docs.datastax.com/en/cql/3.1/cql/cql_reference/refCompositePk.html

尝试的好工具是cqlsh - 它可以帮助你测试很多东西.例如在cqlsh输出中,分区键列为红色,聚类列为青色/蓝色,数据列为紫色 - 非常有用

更新评论 继续第二种情况,查询

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

 userid | email | data
--------+-------+------
Run Code Online (Sandbox Code Playgroud)

将成功,因此您必须始终指定用户ID和电子邮件

要查询一个用户和许多电子邮件地址,您可以使用

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

 userid | email | data
--------+-------+------
Run Code Online (Sandbox Code Playgroud)

但是IN子句很昂贵,因为这意味着联系节点必须连接许多节点才能收集数据,因此最好使用并行查询,但您还必须指定电子邮件值.第一个选择的第二个案例以错误结束.但是从示例中,一个用户可以拥有许多电子邮件,因此第一种情况应该足够 - 取决于数据库的期望.在第二种情况下,没有电子邮件字段将无法工作.

在第一种情况下

CREATE TABLE users ( userid INT, email TEXT, data TEXT, PRIMARY KEY ( userid, email ) );
INSERT INTO users (userid, email , data ) VALUES( 0, 'email@a.pl', 'ddd');
INSERT INTO users (userid, email , data ) VALUES( 0, 'email1@a.pl', 'ddd1111');
Run Code Online (Sandbox Code Playgroud)

你将插入一些通过电子邮件地址聚集的数据,因此你将有一个用户关系 - >电子邮件中的许多数据至少你的评论中的问题建议这一点.这是结果

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

 userid | email       | data
--------+-------------+---------
      0 | email1@a.pl | ddd1111
      0 |  email@a.pl |     ddd
Run Code Online (Sandbox Code Playgroud)