日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

靜態列(static column)實戰

場景

需要 Cassandra 中使用一張表記錄用戶基本信息(比如 email、密碼等)以及用戶狀態更新。通常來說,用戶的基本信息一般很少會變動,但是用戶狀態會經常變化,如果每次狀態更新都把用戶基本信息都加進去,將浪費大量的存儲空間。

為了解決這種問題,Cassandra 引入了 static column。同一個 partition key 中被聲明為 static 的列只有一個值的,也就是只存儲一份。

定義靜態列

在表中將某個列定義為 STATIC 很簡單,只需要在列的最后面加上 STATIC 關鍵字,具體如下:

CREATE TABLE "iteblog_users_with_status_updates" (
  "username" text,
  "id" timeuuid,
  "email" text STATIC,
  "encrypted_password" blob STATIC,
  "body" text,
  PRIMARY KEY ("username", "id")
);
                        

上述命令將表中的 email 和 encrypted_password 兩個字段設置為 STATIC。這意味著同一個 username 只會有一個 email 和 encrypted_password 。

靜態列限制

不是任何表都支持為列加上 STATIC 關鍵字的,靜態列有以下限制:

  • 表沒有定義 Clustering columns(又稱 Clustering key),例如:

cqlsh:iteblog_keyspace> CREATE TABLE "iteblog_users_with_status_updates_invalid" (
                    ...   "username" text,
                    ...   "id" timeuuid,
                    ...   "email" text STATIC,
                    ...   "encrypted_password" blob STATIC,
                    ...   "body" text,
                    ...   PRIMARY KEY ("username")
                    ... );
InvalidRequest: Error from server: code=2200 [Invalid query] message="Static columns are only useful (and thus allowed) if the table has at least one clustering column"
                        

iteblog_users_with_status_updates_invalid 表只有 PRIMARY KEY,沒有定義 clustering column,不支持創建 Static columns。這是因為靜態列在同一個 partition key 存在多行的情況下才能達到最優情況,而且行數越多效果也好。但是如果沒有定義 clustering column,相同 PRIMARY KEY 的數據在同一個分區里面只存在一行數據,本質上就是靜態的,所以沒必要支持靜態列。

  • 建表的時候指定了 COMPACT STORAGE,例如:

cqlsh:iteblog_keyspace> CREATE TABLE "iteblog_users_with_status_updates_invalid" (
                    ...   "username" text,
                    ...   "id" timeuuid,
                    ...   "email" text STATIC,
                    ...   "encrypted_password" blob STATIC,
                    ...   "body" text,
                    ...   PRIMARY KEY ("username", "id")
                    ... )WITH COMPACT STORAGE;
InvalidRequest: Error from server: code=2200 [Invalid query] message="Static columns are not supported in COMPACT STORAGE tables"
                        
  • 列是 partition key/Clustering columns 的一部分,例如:

cqlsh:iteblog_keyspace> CREATE TABLE "iteblog_users_with_status_updates_invalid" (
                    ...   "username" text,
                    ...   "id" timeuuid STATIC,
                    ...   "email" text STATIC,
                    ...   "encrypted_password" blob STATIC,
                    ...   "body" text,
                    ...   PRIMARY KEY ("username", "id")
                    ... );
InvalidRequest: Error from server: code=2200 [Invalid query] message="Static column id cannot be part of the PRIMARY KEY"
cqlsh:iteblog_keyspace> CREATE TABLE "iteblog_users_with_status_updates_invalid" (
                    ...   "username" text,
                    ...   "id" timeuuid,
                    ...   "email" text STATIC,
                    ...   "encrypted_password" blob STATIC,
                    ...   "body" text,
                    ...   PRIMARY KEY (("username", "id"), email)
                    ... );
InvalidRequest: Error from server: code=2200 [Invalid query] message="Static column email cannot be part of the PRIMARY KEY"
                        

為靜態列的表插入數據

含有靜態列的表插入數據和正常表類似,例如往 iteblog_users_with_status_updates 導入數據:

cqlsh:iteblog_keyspace> INSERT INTO "iteblog_users_with_status_updates"
                    ... ("username", "id", "email", "encrypted_password", "body")
                    ... VALUES (
                    ...   'iteblog',
                    ...   NOW(),
                    ...   'iteblog_hadoop@iteblog.com',
                    ...   0x877E8C36EFA827DBD4CAFBC92DD90D76,
                    ...   'Learning Cassandra!'
                    ... );
cqlsh:iteblog_keyspace> select username, email, encrypted_password, body from iteblog_users_with_status_updates;
 username | email                      | encrypted_password                 | body
----------+----------------------------+------------------------------------+---------------------
  iteblog | iteblog_hadoop@iteblog.com | 0x877e8c36efa827dbd4cafbc92dd90d76 | Learning Cassandra!
(1 rows)
                        

可以看出,成功的插入一條數據了。上述語句做了兩件事:

  • 所有 username 為 iteblog 數據中的 email 和 encrypted_password 都被設置為 iteblog_hadoop@iteblog.com 和 0x877e8c36efa827dbd4cafbc92dd90d76。

  • 在 iteblog 所在的分區中新增了 body 內容為 Learning Cassandra! 的記錄。 再往表中插入一條數據,如下:

cqlsh:iteblog_keyspace> INSERT INTO "iteblog_users_with_status_updates"
                    ... ("username", "id", "body")
                    ... VALUES ('iteblog', NOW(), 'I love Cassandra!');
cqlsh:iteblog_keyspace> select username, email, encrypted_password, body from iteblog_users_with_status_updates;
 username | email                      | encrypted_password                 | body
----------+----------------------------+------------------------------------+---------------------
  iteblog | iteblog_hadoop@iteblog.com | 0x877e8c36efa827dbd4cafbc92dd90d76 | Learning Cassandra!
  iteblog | iteblog_hadoop@iteblog.com | 0x877e8c36efa827dbd4cafbc92dd90d76 |   I love Cassandra!
(2 rows)
cqlsh:iteblog_keyspace>
                        

可以看出,這次插入數據的時候,并沒有指定 email 和 encrypted_password。但是從查詢結果可以看出,新增加的行 email 和 encrypted_password 的值和之前是一樣的。

現在由于某些原因,用戶修改了自己的 email,例如:

cqlsh:iteblog_keyspace> UPDATE iteblog_users_with_status_updates SET email = 'iteblog@iteblog.com'
                    ... WHERE username = 'iteblog';
cqlsh:iteblog_keyspace> select username, email, encrypted_password, body from iteblog_users_with_status_updates;
 username | email               | encrypted_password                 | body
----------+---------------------+------------------------------------+---------------------
  iteblog | iteblog@iteblog.com | 0x877e8c36efa827dbd4cafbc92dd90d76 | Learning Cassandra!
  iteblog | iteblog@iteblog.com | 0x877e8c36efa827dbd4cafbc92dd90d76 |   I love Cassandra!
(2 rows)
                        

從上面查詢這輸出的結果可以看出, username 為 iteblog 的 email 全部修改成一樣的了,這就是靜態列的強大之處。

現在表中存在了用戶的郵箱和密碼等信息,如果在前端的頁面支持用戶修改自己的郵箱和密碼,這時后臺系統需要獲取到現有的郵箱和密碼,具體如下:

cqlsh:iteblog_keyspace> SELECT "username", "email", "encrypted_password"
                    ... FROM "iteblog_users_with_status_updates"
                    ... WHERE "username" = 'iteblog';
 username | email               | encrypted_password
----------+---------------------+------------------------------------
  iteblog | iteblog@iteblog.com | 0x877e8c36efa827dbd4cafbc92dd90d76
  iteblog | iteblog@iteblog.com | 0x877e8c36efa827dbd4cafbc92dd90d76
(2 rows)
                        

可以看出,表中有多少行 username 為 iteblog 的數據將會輸出多少行郵箱和密碼,這不是最終想要的數據。此時您可以在查詢的時候加上 DISTINCT 關鍵字,例如:

cqlsh:iteblog_keyspace> SELECT DISTINCT "username", "email", "encrypted_password"
                    ... FROM "iteblog_users_with_status_updates"
                    ... WHERE "username" = 'iteblog';
 username | email               | encrypted_password
----------+---------------------+------------------------------------
  iteblog | iteblog@iteblog.com | 0x877e8c36efa827dbd4cafbc92dd90d76
(1 rows)
                        

這樣無論表中有多少行 username 為 iteblog 的數據,最終都會顯示一行數據。

雖然加了 DISTINCT 關鍵字,但是 Cassandra 并不是將 username 為 iteblog 的數據全部拿出來,然后再去重的,因為靜態列本來在底層就存儲了一份,所以不需要再去重。