關係表結構是被人們普遍接受的資料模型,通常一行資料由多個屬性組成,每個屬性是一列。但是磁碟是一維的,檔案只能順序寫,那麼先寫誰後寫誰呢?不同的寫檔案順序就對應了不同的儲存模型。傳統資料庫通常採用行式儲存,即先存一行資料,再存下一行資料。
在大資料時代,乙個常見分析型場景是在資料倉儲中進行分析,如商店的商品資訊,有商品號,進貨日期,**等包含多個屬性,這就是乙個很常見的資料模型。而查詢很多時候是計算某個屬性上的聚合值,比如計算乙個地區的平均身高,所有人的平均年齡等。列式儲存通常將不同資料的同乙個屬性值存在一起,在查詢時只遍歷需要的資料。因為每乙個屬性在表中就是一列,所以很直觀的就叫列式儲存。(東哥曾經很流氓的跟我說,你把表轉過來看,其實行式儲存也是列式儲存。。。)
針對這種場景,但不僅限於這種場景,出現了很多列式儲存的檔案格式和儲存系統,比如 parquet,carbondata,cassandra等。並且在大資料時代的分析型場景下碾壓了傳統的關係型資料庫,於是提出了新名詞 nosql,not only sql,不僅僅是sql,本意是去掉關聯式資料庫中對事務的支援,在大資料場景事務的概念太重了。
採用行式儲存時,資料在磁碟上的組織結構是:
有啥好處呢,假如你想查乙個人的所有屬性,可以通過一次磁碟 seek 加順序讀取就可以了。但是當我只想查所有人的年齡時,需要不停的seek、seek,或者將所有資料掃瞄一遍,遍歷了很多沒用的資料。
採用列式儲存時,資料在磁碟上的組織結構是:
這時,當我想查所有人的年齡,這樣我只用一次磁碟 seek 加順序讀取所有人的年齡欄位就可以了。
列式儲存只是乙個很寬泛的概念,將各個屬性維度的資料存在一起,這只是一種儲存格式,或者說檔案的組織方式。但是僅僅有儲存格式是不足以實現乙個列存系統的。為了繼續細化到執行層面,將其豐富成乙個系統。還需要有相應的寫入流程和查詢流程與之對應,在這個過程中就大有可為了。
壓縮在定義表的時候,每一列都是一種資料型別,這樣就可以使用針對資料型別的壓縮方法將資料壓縮,壓縮可以達到乙個數量級的效能提公升。當某一列被排序之後,可以達到更高的壓縮比。壓縮的意義不僅在於降低磁碟占用,畢竟磁碟越來越便宜,這個意義會越來越小。壓縮的意義更多在於加速查詢,如減少了磁碟io,或者直接操作壓縮後的資料來降低 cpu 代價。
拼接這個剛開始不能說是優點,應該是必須解決的問題。將資料按列儲存是很好,但是有乙個必須要解決的問題,那就是乙個資料項的多個屬性被分開存放在不同地方了,乙個查詢也會同時訪問多個屬性,並且 jdbc 等介面還是以一行為單位返回結果的。因此,多列資料拼接在列式儲存中是乙個必不可少的操作。
第乙個問題是,怎麼拼接?
乙個資料項的各個屬性分開放了,我怎麼知道誰對應誰?一般來說,是按順序拼接的。比如,第乙個資料項的三個屬性在三個列的位置都是1,以此類推。
讀的時候可以根據下標將各屬性拼接起來。
第二個問題是,什麼時候拼接?
如果說拼接剛開始只是列式儲存不得不解決的問題,那麼延遲拼接則應該是列式儲存為了解決拼接問題而發掘出來的優勢了。
假如乙個表裡有100列,有乙個查詢 select c3 from table1 where c1>10 and c2>5
第一種方式是行式過濾的思想,先將c1,c2,c3 三列讀出來,拼接成乙個乙個資料項,再對每行資料項的 c1,c2 的值進行 c1>10 and c2>5 的過濾。這個暫且叫預先拼接。
第二種方式是延遲拼接,將謂詞下推至各個列,先記錄 c1 列中滿足 c1>10 的所有資料下標 a,再記錄 c2 列中滿足 c2>5 的所有資料下標 b,將 a 和 b 合併成 c,並用 c 去讀 c3 列。實踐證明這種方式更能發揮列式儲存的優勢。
sql語句中的謂詞就是where語句後的過濾條件,如等於,小於,大於等於。
塊遍歷這個比較底層了,涉及cpu的指令執行優化等(其實我也不太了解,有個概念就行了~)。行式儲存的查詢中,需要將每行資料進行需要過濾的屬性抽取,並進行過濾操作,負載很重。列式儲存中不需要屬性抽取,可以直接將一列的一段資料當做乙個陣列交給乙個 filter,遍歷陣列的代價比對每個物件進行遍歷負載要輕,並且可以利用cpu的並行能力。
行存和列存只是不同的維度而已,沒有天生的優劣(打自己臉:列存天生適合壓縮)。大資料時代大部分的查詢模式決定了列式儲存優於行式儲存。一般來說,列式儲存不僅包括資料是按列存在磁碟上的,還包括針對這種格式的儲存和查詢引擎。關於列式儲存就介紹這麼多,有興趣可以再去看看 parquet、carbondata。
列式儲存處理
下面以gbase 8a分析型資料庫為例,描述列儲存對資料儲存與管理的作用。面對海量資料分析的 i o 瓶頸,gbase 8a 把錶資料按列的方式儲存,其優勢體現在以下幾個方面。不讀取無效資料 降低 i o 開銷,同時提高每次 i o 的效率,從而大大提高查詢效能。查詢語句只從磁碟上讀取所需要的列,其...
列式儲存 一
最近做專案,客戶要求物件的屬性能夠動態新增,於是採用了列式儲存。1.傳統關係型資料庫的行式儲存方法為 資料庫表的字段表示物件屬性,一行資料完整的表示物件的所有屬性。如果要新增乙個屬性,如 聯絡郵箱 那麼就要重新設計表,增加一欄 email 相應的後台 也需要變動。2.關係型資料庫的行式儲存方法為 將...
行式儲存與列式儲存
行式儲存與列式儲存 行式儲存 資料儲存以行為單位,儲存完一行就會跳到第二行 row based store。維護大量的索引,儲存成本比較高,不能做到線性擴充套件,對於隨機讀的效率高。最大的特點就是對事務的處理能力支援的非常好。行式儲存最大的優點是關係之間的解決方案,行式儲存實現了關係型資料庫,如果表...