簡體   English   中英

復合鍵的Cassandra分區

[英]Cassandra partitioning of composite keys

據我了解,如果我們只有一個主鍵,則可以使用該鍵對數據進行分區並將其存儲在一個節點中(例如,使用隨機分區程序)。

現在我不確定的是,如果我有多個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)
);

這是否意味着現在將useridemailaddress一起使用以確定分區?

是否可以在兩個單獨的節點中分配具有相同userid但具有不同emailaddress兩行,還是將它們始終位於同一節點中?

非常感謝,

實際上在您的示例中

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

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       

分區鍵部分由內括號()定義

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

現在您將擁有由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"     

現在,您的問題->是,因為您只能將復合鍵分區鍵部分用作用戶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
--------+-------+------

將成功執行,因此結果是您必須始終指定用戶名和電子郵件

要查詢一個用戶和許多電子郵件地址,您可以使用

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

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

但是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');

您將插入一些通過電子郵件地址聚類的數據,因此您將與一個用戶建立關系->通過電子郵件發送許多數據,至少您在評論中的問題建議這樣做。 這是結果

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

 userid | email       | data
--------+-------------+---------
      0 | email1@a.pl | ddd1111
      0 |  email@a.pl |     ddd

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM