2016-05-31 35 views
1

我有一個擁有數百億記錄的巨大表格,我的意思是在這張表中添加一個字段,其中相同的值將爲數百萬條記錄重複。我不知道如何有效地在cassandra中建模。請允許我闡述:如何建模cassandra上多條記錄的重複信息

我有一個通用的表:

CREATE TABLE readings (
    key int, 
    key2 int, 
    time timestamp, 
    name text, 
    PRIMARY KEY ((key, key2) time) 
) 

此表有700.000.000+記錄。 我想在此表中創建一個名爲source的字段。該字段指示記錄的來源(因爲該軟件有許多方法可以接收reading表中的信息)。這個字段的一個可能的值是"XML: path\to\file.xml""Direct import from the X database"或甚至"Manually added",我希望這是一個描述性字段,專門用於在數據庫中進行後期維護,我們只想操作來自給定源的記錄。

我想運行,我不能現在的疑問:

  • readings表,記錄是從給定源得到?
  • 給定記錄的來源是什麼?

一個解決方案是爲我創建一個表,如:

CREATE TABLE readings_per_source(
    source text, 
    key int, 
    key2 int, 
    time timestamp, 
    PRIMARY KEY (source, key, key2, time) 
) 

這將允許我執行第一查詢,但也意味着我將創建700.000.000+新紀錄在我的數據庫中有很多信息,這會佔用大量不必要的存儲空間,因爲數以百萬計的這些記錄具有相同的值source

如果這是一個關係型的環境,我會在readings表和sourceid (PK)name領域創造source_id場,這將意味着存儲有關readings表的每一行和新表只是一個額外的整數有不同來源的記錄數量很多。

我們如何在cassandra中對此進行建模?

回答

2

你的架構

CREATE TABLE readings_per_source(
    source text, 
    key int, 
    key2 int, 
    time timestamp, 
    PRIMARY KEY (source, key, key2, time) 
) 

是一個非常糟糕的主意,因爲source是分區鍵,你可以有百萬條記錄例如共享相同源具有非常非常寬的分區 - >熱點

對於你第二查詢,What is the source of a given record?是它相當微不足道如果訪問使用該記錄的主鍵(鍵,KEY2)中的數據。 source列可以作爲正常列添加到表中

對於第一個查詢Which records on the readings table were gotten from a given source?它是更棘手的。這裏的想法是獲取所有具有相同來源的記錄。

您是否意識到此查詢可能會返回數千萬條記錄

如果這是你想要做什麼,有一個解決方案,使用新的SASI二級索引(讀我blog post所有細節),並創建了source列的索引

CREATE TABLE readings (
    key int, 
    key2 int, 
    time timestamp, 
    name text, 
    source text, 
    PRIMARY KEY ((key, key2), time) 
) 

CREATE CUSTOM INDEX source_idx ON readings(source) 
USING 'org.apache.cassandra.index.sasi.SASIIndex' 
WITH OPTIONS = { 
    'mode': 'PREFIX', 
    'analyzer_class': 'org.apache.cassandra.index.sasi.analyzer.NonTokenizingAnalyzer', 
    'case_sensitive': 'false' 
}; 

然後讀取所有具有相同源記錄,使用Java驅動程序(或任何其他Datastax驅動程序)

+0

是的,我知道這個查詢可能會返回很多記錄,而這也是一種目的。它可能是一個問題嗎?我的意思是用單個查詢返回數百萬條記錄。此外,我曾想過創建某種索引,但不知道如何去做,您的答案會有很大幫助。但有一個問題仍然存在:簡單地添加列並以非標準化的方式重複該值,是否會導致過度使用存儲? –

+0

此外,我使用python驅動程序,並且我發現驅動程序已經對大量查詢的結果進行了分頁,是否需要配置與它已有的內容不同的內容? –

+0

「一個問題仍然存在:只需添加列並以非標準化的方式重複該值,是否不會導致過度使用存儲? - >理論上是的,在實踐中,如果啓用了磁盤壓縮(默認情況下),它應該有助於節省空間。 – doanduyhai

1

http://www.datastax.com/2015/03/how-to-do-joins-in-apache-cassandra-and-datastax-enterprise是一篇關於如何在Cassandra中加入表格的不錯文章。

規格化的數據總是佔用比非標準化(平面)數據更少的存儲空間(假定相關數據大於用於將表連接在一起的鍵),但需要在查詢期間需要更多功能的連接。

總是有一個權衡。還有一種與完全標準化的數據有關的狀態的折衷,其中一個例子是改變地址的客戶。在完全標準化的模式中,一旦地址發生變化,客戶,過去和現在的所有發票都會顯示新地址。這並不總是可取的。

通常需要進行部分規範化處理,以在記錄中提供歷史狀態,以便在給定時間顯示數據的狀態,例如在發票上。在這種情況下,您需要在發票創建時在發票上存儲客戶地址數據的副本。

這對定價和稅收也特別重要。您希望發票上存儲的價格/稅額可以顯示客戶在創建發票時支付了什麼,因此,當會計每月運行一次,每年和超出一個給定發票上的價格對於發票,即使產品的價格可能已經改變。否則,你有一個會計噩夢!

在決定如何規範化/規範化模式時,還有很多需要考慮的事情比簡單的存儲空間還要多。

對不起,散漫......

+0

其實我並不想尋找一種方法來連接表的server-side paging功能是我想要的東西,而無需重複模式的問題到其他資源如spark或ODBC conn ectors。我的問題確實有一些理論基調,所以你的散漫已經被原諒。非常翔實的你的答案,我會考慮到它。謝謝! –

相關問題