2016-09-19 56 views
2

輸入:表格數據文件:每個文件具有可變列數,並且這些列名對文件和/或其他文件(事先未知)可能是唯一的。這些數據預計不會改變,所以插入會很頻繁,但更新很少。列和它們的參數值可以是文本的或數字的。Cassandra中的地圖冗餘

請求的能力:能夠通過身份或範圍查詢給定列名和值來檢索數據的行。

數據模型:在CQL我可以模擬使用表示一個文件的一個特定的單元格值的單個表(在這種情況下的文本,但也可構造成用於數字數據的類似的表)

create table mytable(
    colname text, 
    value text, 
    filename text, 
    rowid int, 
    data map<text,text>, 
    primary key (colname , value, filename, rowid)#partitioning on colname may not be ideal here, but will be dealt with in ways unrelated to this question 
); 

例如,一個文件的內容可能是:

A B C D E 
i1 i2 i3 i4 i5 

插入是:

insert into mytable(colname, value, data, filename, rowid) values ('A', 'i1', {'A':'i1', 'B':'i2', 'C':'i3', 'D':'i4', 'E':'i5', 'F':'i5'}, 'F1', 1); 
insert into mytable(colname, value, data, filename, rowid) values ('B', 'i2', {'A':'i1', 'B':'i2', 'C':'i3', 'D':'i4', 'E':'i5', 'F':'i5'}, 'F1', 2); 
insert into mytable(colname, value, data, filename, rowid) values ('C', 'i3', {'A':'i1', 'B':'i2', 'C':'i3', 'D':'i4', 'E':'i5', 'F':'i5'}, 'F1', 3); 
insert into mytable(colname, value, data, filename, rowid) values ('D', 'i4', {'A':'i1', 'B':'i2', 'C':'i3', 'D':'i4', 'E':'i5', 'F':'i5'}, 'F1', 4); 
insert into mytable(colname, value, data, filename, rowid) values ('E', 'i5', {'A':'i1', 'B':'i2', 'C':'i3', 'D':'i4', 'E':'i5', 'F':'i5'}, 'F1', 5); 
... 

SELECT data from mytable where colname=? and value=? 

問題:我們確實有數據存儲限制 - 在此模型中的數據值是一個行的每個列的值是相同的,從而導致大量過度的數據重複的(這是一個簡單的例子,但列數能超過100個 - 意味着地圖可以重複數百次)。

問題:(通過指針到例如數據或以某種方式定義地圖作爲不同)是否有卡桑德拉任何方式,以避免這種類型的數據複製的,而無需創建/查詢第二表?或者,另一種方法可以使用相同的查詢功能和結果對數據進行建模?

+0

你有沒有考慮過使用Solr來解決這個問題呢? – Sreekar

+0

感謝您的建議@Sreekar會研究它......尤其是Solr與文本或數字數據的性能(我們的數據可能是,我們正在尋找後者有效的範圍查詢) – copeg

回答

1

如果您的設計受益於C *內置壓縮,我不會感到驚訝,您的存儲需求可能會低於您的預期。

順便說一句,如果你想要一個完全不同的模型,你可以嘗試:

  • 一個表輸入數據
  • 每個表都有一個分區鍵時,你的價值的每一列尋找沿着這些路線

東西:

CREATE TABLE colname_A (
    value text, 
    data map<text,text>, 
    ..., 
    PRYMARY KEY (value) 
); 

CREATE TABLE colname_B (
    value text, 
    data map<text,text>, 
    ..., 
    PRYMARY KEY (value) 
); 
.... 
CREATE TABLE colname_xxx (...); 

然後,您可以發通過發行選出你的數據:

SELECT * FROM colname_A WHERE value = 'i5'; 
SELECT * FROM colname_A WHERE value IN ('i4', 'i5') 

小心與分區鍵的IN clausole查詢,因​​爲你想避免像this問題,當你把數據加載到您的集羣。

該模型以不同方式組織數據,並受益於列間數據重複而不是行間數據重複。如果你有不平衡的列(例如一些列中的大量記錄),這個數據組織提供的壓縮可能是一個巨大的勝利。

+0

謝謝你的想法。我已經考慮過一個類似於你描述的模型,但是我不完全清楚這將如何解決我最初的問題:a)數據重複的膨脹和b)需要從單個查詢中提取行數據(除非'數據'這裏指的是行值)?對於它的價值,這些文件中的行數是列數的幾倍。 – copeg

+1

事實上,你有更多的行比列看起來很正常。您應該根據數據的組織方式選擇模型,或者堅持使用更好的壓縮比的模型。 ** a)**在擔心數據重複之前,您應該嘗試加載一堆數據。 ** b)**我不明白你的意思,是你提取地圖字段的要求,是嗎? – xmas79

+0

用** a **釘住它。替代模型之間的磁盤使用情況表明,在有或沒有數據重複的情況下,磁盤使用情況非常相似(當然,我很驚訝)。如果你在答案中包含了這一點(以及關於數據組織建模的前一句話),我會將其標記爲已解決。 – copeg