前置說明
在開始練習前,先作個小小的說明,同時也補充之前沒有提到的東西。首先 cassandra 的預設設定檔中已經有定義預設的 keyspace 跟 coulmns families,預設有一個 keyspace 為「Ketspace1」有四個 colimn family 分別是「Standard1」、「Standard2」、「StandardByUUID1」跟「Super1」,這四個 colimn family 詳細的差異會在後面的文章再補充。所以之前所使用的 keyspace 跟 colimn family 都是真實存在於 cassandra 裡面的。
所有的紀錄都是以「key」來作識別,所以「key」不能重複。
Column
假設我們要在資料庫中產生以下的紀錄
ian:{ name: "Ian Wu"}john:{ name: "John Li"}
這兩筆紀錄很簡單,單純紀錄「key=ian」的紀錄,裡麵包含了「name=Ian Wu」
這時我們可以使用 set 指令來插入這兩筆紀錄。
set Keyspace1.Standard1['ian']['name']='Ian Wu'set Keyspace1.Standard1['john']['name']='John Li'
接著再利用 get 來讀取剛剛插入的兩筆紀錄
cassandra> get Keyspace1.Standard1['ian'] => (column=name, value=Ian Wu, timestamp=1270407235197)Returned 1 results.cassandra> get Keyspace1.Standard1['john']=> (column=name, value=John Li, timestamp=1270407563029)Returned 1 results.
再已存的紀錄中增加 column
接著如果我們的紀錄要變更成以下的狀態的話
ian:{ name: "Ian Wu"}john:{ name: "John Li" gender: "male"}
一樣使用 set 將「john」新增的「gender=male」column 插入到「john」的紀錄中
set Keyspace1.Standard1['john']['gender']='male'
一樣再利用 get 來讀取這兩筆紀錄
cassandra> get Keyspace1.Standard1['ian'] => (column=name, value=Ian Wu, timestamp=1270407235197)Returned 1 results.cassandra> get Keyspace1.Standard1['john'] => (column=name, value=John Li, timestamp=1270407830919)=> (column=gender, value=male, timestamp=1270407845754)Returned 2 results
我們可以看到「john」增加了「gender」這個 column,然而我們完全沒有修正任何的 schema 就可以達到增加欄位的功能,這可跟 RDBMS 有很大的不同。
Super Column
接著我們要來練習 super column,一樣,假設我們要在資料庫中產生以下的紀錄
ian:{ address: { city: "Taipei County" zip: "251" }}john:{ address: { city: "Taipei City" zip: "104" }}
一樣使用 set 指令來插入這兩筆紀錄,不過要注意的是 column family 要使用「Super1」才有支援 super column。
set Keyspace1.Super1['ian']['address']['zip']='251'set Keyspace1.Super1['ian']['address']['city']='Taipei County'set Keyspace1.Super1['john']['address']['zip']='104'set Keyspace1.Super1['john']['address']['city']='Taipei City'
接著再利用 get 來讀取剛剛插入的兩筆紀錄
cassandra> get Keyspace1.Super1['ian'] => (super_column=address, (column=city, value=Taipei County, timestamp=1270408441168) (column=zip, value=251, timestamp=1270408426438))Returned 1 results.cassandra> get Keyspace1.Super1['john']=> (super_column=address, (column=city, value=Taipei City, timestamp=1270408480625) (column=zip, value=104, timestamp=1270408459787))Returned 1 results.
在這裡可以看到 super colimn 顯示的格式略有不同,不過原則上還是大同小異。
Column Family 的注意事項
在上面的例子中,我們已經使用到兩個 column family 分別是「Standard1」跟「Super1」,差異就是「Standard1」儲存 column;「Super1」儲存 super column,這裡有一點要特別注意,就是在 column family 內儲存的型態不能混用,也就是說「Standard1」不能存 super column;「Super1」不能存 column。
像是在「Standard1」要加入 super column 就會出現以下的錯誤。
cassandra> set Keyspace1.Standard1['ian']['addrss']['zip']='251'Exception nullInvalidRequestException(why:supercolumn parameter is invalid for standard CF Standard1) at org.apache.cassandra.service.Cassandra$insert_result.read(Cassandra.java:9963) at org.apache.cassandra.service.Cassandra$Client.recv_insert(Cassandra.java:574) at org.apache.cassandra.service.Cassandra$Client.insert(Cassandra.java:547) at org.apache.cassandra.cli.CliClient.executeSet(CliClient.java:375) at org.apache.cassandra.cli.CliClient.executeCLIStmt(CliClient.java:63) at org.apache.cassandra.cli.CliMain.processCLIStmt(CliMain.java:131) at org.apache.cassandra.cli.CliMain.main(CliMain.java:172)
或是在「Super1」要加入 column 就會出現以下的錯誤。
cassandra> set Keyspace1.Super1['ian']['name'] = 'Ian Wu' Exception nullInvalidRequestException(why:supercolumn parameter is not optional for super CF Super1) at org.apache.cassandra.service.Cassandra$insert_result.read(Cassandra.java:9963) at org.apache.cassandra.service.Cassandra$Client.recv_insert(Cassandra.java:574) at org.apache.cassandra.service.Cassandra$Client.insert(Cassandra.java:547) at org.apache.cassandra.cli.CliClient.executeSet(CliClient.java:375) at org.apache.cassandra.cli.CliClient.executeCLIStmt(CliClient.java:63) at org.apache.cassandra.cli.CliMain.processCLIStmt(CliMain.java:131) at org.apache.cassandra.cli.CliMain.main(CliMain.java:172)
原文連結 http://wiki.cheyingwu.tw/Java/Cassandra/data-model-cli-exercise