簡體   English   中英

對於我的方案,Cassandra(CQL)模式/表與RDBMS相同

[英]Cassandra (CQL) schema/tables look the same as RDBMS for my scenario

我看過特維桑德拉的例子。 幾天前,我對此也提出了類似的問題,並收到了一些我在此處實施的技巧。 但是,通過查看表(列族),我幾乎看不到該數據庫與關系數據庫之間的任何區別。

我的場景:一個簡單的通訊錄,用戶可以在其中創建自己的聯系人並將其分組(一個聯系人可以分為多個組,一組可以包含多個聯系人)。 一個聯系人可能有多個地址。

我想檢索居住在地址x中並位於y組中的所有聯系人。 因此,我做了以下工作:

CREATE TABLE if not exists User (user_id uuid, contact_id uuid, type varchar, email varchar, PRIMARY KEY(id));
CREATE TABLE if not exists Contact (contact_id uuid, firstname varchar,lastname varchar, photo blob, imagelength int, note varchar, PRIMARY KEY (id));
CREATE TABLE if not exists Address (address_id uuid, contact_id uuid, street varchar, number int, zipcode varchar, country varchar, PRIMARY KEY(address_id));
CREATE TABLE if not exists Group (group_id uuid, user_id, groupname varchar, PRIMARY KEY(group_id));
CREATE TABLE if not exists Group_Contact (group_id uuid, contact_id, PRIMARY KEY(id, contact_id));

但是,基於此,它實際上與關系數據庫完全相同,只是我相信Cassandra會以與RDBMS磁盤不同的方式來放置此數據。 我看不到如何在Cassandra中更好地做到這一點,以及我是否以正確的方式建模。 感覺就像一個普通的關系數據庫。 我覺得我做錯了,因為我必須使用應用程序級別的連接來獲取聯系人的地址。 我真的不知道如何將其反規范化以允許多個地址(甚至電話,電子郵件)。

任何改善這種情況的建議將不勝感激!

正如jny所指出的那樣,數據復制,反規范化和基於查詢的建模是構建良好的Cassandra數據模型的關鍵。 如果我想把您的表格放在上面,並建立一個表格來支持基於國家/地區的地址/聯系方式查詢,我可以這樣做:

首先,我將為聯系人的地址創建一個用戶定義的類型

aploetz@cqlsh:stackoverflow> CREATE TYPE contactAddress (
             ...   street varchar, 
             ...   city varchar,
             ...   zip_code varchar,
             ...   country varchar);

接下來,我將創建一個名為UserContactsByCountry的表來存儲用戶聯系信息以及所有用戶聯系地址:

aploetz@cqlsh:stackoverflow> CREATE TABLE UserContactsByCountry (
             ...   country varchar,
             ...   user_id uuid,
             ...   type varchar,
             ...   email varchar,
             ...   firstname varchar,
             ...   lastname varchar,
             ...   photo blob,
             ...   imagelength int,
             ...   note varchar,
             ...   addresses map<text, frozen <contactAddress>>,
             ...   PRIMARY KEY ((country),user_id));

這里需要注意幾件事:

  • 我使用country作為查詢的分區鍵,並將user_id為唯一性的群集鍵。
  • 從技術上講, country在每行中存儲多個。 一次作為分區密鑰,再一次與每個地址有關。 請注意, country分區鍵是允許我們運行查詢的鍵。
  • 我假設用戶聯系人可以有多個地址,所以我將它們存儲在文本類型(varchar),contactAddress(上面創建的類型)的映射中。

接下來,我將插入三個用戶聯系人,每個聯系人都有兩個地址,兩個來自美國,一個來自英國。

aploetz@cqlsh:stackoverflow> INSERT INTO usercontactsbycountry (country, user_id, type, email, firstname, lastname, note, addresses)
VALUES ('USA',uuid(),'Tech','brycelynch@network23.com','Bryce','Lynch','Head of R&D at Network 23',{'work':{street:'101 Big Network Drive',city:'New York',zip_code:'10023',country:'USA'},'home':{street:'8192 N. 42nd St.',city:'New York',zip_code:'10025',country:'USA'}});
aploetz@cqlsh:stackoverflow> INSERT INTO usercontactsbycountry (country, user_id, type, email, firstname, lastname, note, addresses)
VALUES ('USA',uuid(),'Reporter','edisoncarter@network23.com','Edison','Carter','Reporter at Network 23',{'work':{street:'101 Big Network Drive',city:'New York',zip_code:'10023',country:'USA'},'home':{street:'76534 N. 62nd St.',city:'New York',zip_code:'10024',country:'USA'}});
aploetz@cqlsh:stackoverflow> INSERT INTO usercontactsbycountry (country, user_id, type, email, firstname, lastname, note, addresses)
VALUES ('GBR',uuid(),'Reporter','theorajones@network23.com','Theora','Jones','Controller at Network 23',{'work':{street:'101 Big Network Drive',city:'New York',zip_code:'10023',country:'USA'},'home':{street:'821 Wembley St.',city:'London',zip_code:'W11 2BQ',country:'GBR'}});

現在,我可以查詢該表以查找美國的所有用戶聯系人:

aploetz@cqlsh:stackoverflow> SELECT * FROM usercontactsbycountry WHERE country ='USA';
 country | user_id                              | addresses                                                                                                                                                                                    | email                      | firstname | imagelength | lastname | note                      | photo | type
---------+--------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------+-----------+-------------+----------+---------------------------+-------+----------
     USA | 2dee94e2-4887-4988-8cf5-9aee5fd0ea1e |  {'home': {street: '8192 N. 42nd St.', city: 'New York', zip_code: '10025', country: 'USA'}, 'work': {street: '101 Big Network Drive', city: 'New York', zip_code: '10023', country: 'USA'}} |   brycelynch@network23.com |     Bryce |        null |    Lynch | Head of R&D at Network 23 |  null |     Tech
     USA | b92612dd-dbaa-42f2-8ff2-d36b6c601aeb | {'home': {street: '76534 N. 62nd St.', city: 'New York', zip_code: '10024', country: 'USA'}, 'work': {street: '101 Big Network Drive', city: 'New York', zip_code: '10023', country: 'USA'}} | edisoncarter@network23.com |    Edison |        null |   Carter |    Reporter at Network 23 |  null | Reporter

(2 rows)

可能還有其他方法可以建模,但這是我希望用來幫助您了解一些可用技術的方法。

從關系數據庫建模切換到Cassandra建模很困難,因為它們看起來是如此相似:查詢語言看起來幾乎相同。 但是,Cassandra的第一個規則是為您的查詢建模,而在關系數據庫中,我們為數據建模。 這意味着:

  • 考慮一下您最查詢的內容
  • 了解分區鍵和集群鍵
  • 不要擔心數據重復

在Cassandra中有一個很好的數據建模示例: https : //www.datastax.com/documentation/cql/3.1/cql/ddl/ddl_music_service_c.html

暫無
暫無

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

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