簡單說說列式存儲數(shù)據(jù)庫

隨著業(yè)務(wù)越來越看重數(shù)據(jù)的重要性顿乒,相信大家也做了很多多維分析的需求刷允,在調(diào)研技術(shù)選型時候,會發(fā)現(xiàn)很多olap恩掷,如druid倡鲸、clickhouse馋袜、starRocks都是列式存儲數(shù)據(jù)庫闽坡,今天我們來通過對比行存儲簡單說下列存儲

舉個栗子來說下列存儲和行存儲

要過年回家了,今天做了核酸檢測泊窘,我們就以存儲核酸檢測為業(yè)務(wù)場景

栗子

核酸檢測表
  • 就以應(yīng)用頁面為主逼争,存儲核酸記錄需要存儲以下幾個字段
  • 姓名优床、身份證號檢測機構(gòu)誓焦、檢測時間羔巢、結(jié)果價格

行存儲

  • 在行存儲下(如mysql等)罩阵,大家都比較熟悉,就不多說了启摄,每條記錄都是表中的每一行稿壁,表存儲如下
    | 姓名 | 身份證號 | 檢測機構(gòu) | 檢測時間 | 結(jié)果 | 價格 |
    |-----|-----|--|----------|-----|-----|
    | 彥祖 | 123512387 | 北京 | 2021-12-24 12:12:45 | 陰性 |35|
    | 德華 | 213124157 | 上海 | 2021-12-22 12:12:45 | 陰性 |20|
    | 路人甲 | 213123145 | 河南 | 2021-12-21 12:12:45 | 陰性 | 8 |
    | 德華 | 213124157 | 廣州 | 2021-12-29 12:12:45 | 陰性 | 23|
    | 彥祖 | 123512387 | 上海 | 2021-12-30 12:12:45 | 陰性 | 20|

  • 因為數(shù)據(jù)都是按行方式存儲,所以在物理存儲中歉备,會以連續(xù)空間來存儲數(shù)據(jù)傅是,物理存儲中,這些數(shù)據(jù)存儲方式如下:


    行存儲物理結(jié)構(gòu)
行存儲優(yōu)點分析
  • 在這樣的物理結(jié)構(gòu)下蕾羊,因為是連續(xù)空間喧笔,所以插入一條數(shù)據(jù)只需要追加到當前數(shù)據(jù)之后即可,很方便
  • 對于按記錄查詢也很方便龟再,例如:我們要查詢彥祖的所有核酸記錄书闸,頁面應(yīng)用的話應(yīng)該是通過彥祖的身份證號
  • 對應(yīng)的sql如下:
select * from 核酸記錄表 where 身份證號='彥祖的身份證號'
  • 這個sql的執(zhí)行流程比較清晰
1.先從索引查詢出來彥祖的記錄存儲的物理地址
2.在通過物理地址去表的物理存儲中查詢對應(yīng)地址中的數(shù)據(jù)
  • 這樣就可以快速得到彥祖的核酸記錄
行存儲缺點分析
  • 這時候,業(yè)務(wù)方提了一個需求利凑,他要統(tǒng)計彥祖做核酸總共花了多少錢
  • 對于這個需求浆劲,sql實現(xiàn)也很簡單,通過對價格sum就可以實現(xiàn)哀澈,sql如下:
select sum(價格) from 核酸記錄表 where 身份證號='彥祖的身份證號'
  • 這個sql的執(zhí)行流程也比較清晰
1.先從索引查詢出來彥祖的記錄存儲的物理地址
2.在通過物理地址去表的物理存儲中查詢對應(yīng)地址中的數(shù)據(jù)
3.拿到所有數(shù)據(jù)時候牌借,在通過對于價格列sun聚合得到結(jié)果
  • 分析下,因為行存儲使用的是連續(xù)空間割按,即使需求里面只需要select sum(價格)膨报,但是讀取物理存儲時候,還是讀取出來了所有的字段
行存儲優(yōu)缺點總結(jié)
  • 通過上面的分析,總結(jié)一下行存儲的優(yōu)缺點
  • 優(yōu)點
1.連續(xù)空間對于插入/更新很方便
2.對于記錄查詢很方便
  • 缺點
1.會查詢出來很多不需要的列

列存儲

姓名 身份證號 檢測機構(gòu) 檢測時間 結(jié)果 價格
彥祖 123512387 北京 2021-12-24 12:12:45 陰性 35
德華 213124157 上海 2021-12-22 12:12:45 陰性 20
路人甲 213123145 河南 2021-12-21 12:12:45 陰性 8
德華 213124157 廣州 2021-12-29 12:12:45 陰性 23
彥祖 123512387 上海 2021-12-30 12:12:45 陰性 20
  • 在列存儲中现柠,對于同樣的核酸記錄表院领,存儲的物理結(jié)構(gòu)如下:
列物理結(jié)構(gòu)
  • 在列式存儲中,會把每一列存儲到一起晒旅,如姓名列栅盲,是把所有記錄中的姓名這列的值使用連續(xù)空間存放到一起
  • 而對于各個列之間,是沒有必要使用連續(xù)空間存放到一起的废恋,所以很多列式數(shù)據(jù)庫都使用了分布式存儲的方式谈秫,存儲各個列
  • 下面我們來分析下列存儲的數(shù)據(jù)壓縮查詢執(zhí)行流程
列存儲的數(shù)據(jù)壓縮
  • 很多列式數(shù)據(jù)庫都是通過字典表的方式進行數(shù)據(jù)壓縮
  • 因為是把每一列存放到一起的,所以很容易通過對于每一列進行去重鱼鼓,來構(gòu)建一個字典表拟烫,例如:
  • 對于姓名列,這列的所有數(shù)據(jù)如下:
彥祖|德華|路人甲|德華|彥祖
  • 對這列值去重以后迄本,構(gòu)建一張姓名字典表硕淑,構(gòu)建算法忽略,就使用自增id的方式,如下:
    | id | 姓名列 |
    |-----|-----|
    |1| 彥祖 |
    |2| 德華 |
    |3| 路人甲 |
  • 這樣構(gòu)建字典表嘉赎,對于列存儲的物理存儲結(jié)構(gòu)置媳,就可以執(zhí)行存儲字典表中的id,而不用存儲具體的值,有了字典表以后姓名列存儲如下:
1|2|3|2|1
  • 同樣對于價格列公条,這列的所有數(shù)據(jù)如下:
35|20|8|23|20
  • 對這列值去重以后拇囊,構(gòu)建一張價格字典表,構(gòu)建算法忽略靶橱,就使用自增id的方式,如下:
    | id | 價格列 |
    |-----|-----|
    |1| 35 |
    |2| 20 |
    |3| 8 |
    |4|23|

  • 有了字典表以后價格列存儲如下:

1|2|3|4|2
  • 這樣通過一些數(shù)據(jù)壓縮算法等寥袭,可以對數(shù)據(jù)存儲進行壓縮
列存儲的查詢執(zhí)行過程
  • 有字典表以后,我們來看下关霸,列存儲一般是如何進行查詢的
  • 業(yè)務(wù)需求查詢彥祖传黄,20塊錢做的核酸記錄:
select * from 核酸記錄表 where 姓名=彥祖 and 價格=20
  • 對于該sql,執(zhí)行過程如下:
1.對于where 姓名=彥祖
首先查詢姓名字典表队寇,查詢到彥祖的id=1
id 姓名列
1 彥祖
2 德華
3 路人甲
2.通過查詢到彥祖的id膘掰,對于性名列進行對比,構(gòu)建一個bitmap佳遣,把匹配的要的列的索引位設(shè)置為1炭序,否則為0
姓名列
3.對于where 價格=20
和上面一樣的操作,先查詢價格字段表苍日,20的id=2
id 價格列
1 35
2 20
3 8
4 23
4.通過查詢到價格20的id惭聂,對于價格列進行對比,構(gòu)建一個bitmap相恃,把匹配的要的列的索引位設(shè)置為1辜纲,否則為0
價格列
5.對于兩個where條件的結(jié)果bitmap做與運算,bitmap中,位為1的索引就是要查詢數(shù)據(jù)的所有列的索引,如該栗子中耕腾,兩個結(jié)果bitmap與運算后的結(jié)果是00001见剩,所以所有列的第5個值,拼接起來就是我們要查詢的數(shù)據(jù)
與運算
6.所以我們把所有列的第五個值拿出來組裝后就是我們需要的數(shù)據(jù)
列存儲優(yōu)點分析
  • 上面講了列存儲的數(shù)據(jù)壓縮,在數(shù)據(jù)壓縮上列存儲有一定的優(yōu)勢
  • 每一列都可以天然做索引扫俺,不需要額外的數(shù)據(jù)結(jié)構(gòu)來對各個列構(gòu)建索引苍苞,所以不用在意每一列的數(shù)據(jù)類型,都可以做索引
  • 對于統(tǒng)計彥祖做核酸總共花了多少錢這種需求
select sum(價格) from 核酸記錄表 where 身份證號='彥祖的身份證號'
  • 因為列是分開存儲的狼纬,按照上面講的查詢流程羹呵,其實最后我們得到的結(jié)果bitmap拿到位=1的索引后疗琉,我們不需要查詢所有的列冈欢,只需要拿著索引去價格列中獲取相應(yīng)位置的值,然后在進行sum聚合
列存儲缺點分析
  • 因為各個列是分開存儲的盈简,所以在插入凑耻、更新時,需要對于每一個列進行操作柠贤,沒有行存儲連續(xù)空間那么方便
  • 還是看上面說的查詢過程香浩,每次查詢過后,都需要對查詢到的需要的列進行一個數(shù)據(jù)組裝
列存儲優(yōu)缺點總結(jié)
  • 通過上面的分析臼勉,總結(jié)一下列存儲的優(yōu)缺點
  • 優(yōu)點
1.數(shù)據(jù)壓縮比較有優(yōu)勢
2.任何列都可以做索引
3.查詢時只有涉及到的列會被讀取
  • 缺點
1.每次查詢時邻吭,都需要對查詢到的列進行數(shù)據(jù)重新組裝
2.插入/更新操作比較困難

列式存儲數(shù)據(jù)庫就說到這里,歡迎大家來交流坚俗,指出文中一些說錯的地方,讓我加深認識岸裙,愿大家沒有bug猖败,謝謝!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末降允,一起剝皮案震驚了整個濱河市恩闻,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌剧董,老刑警劉巖幢尚,帶你破解...
    沈念sama閱讀 222,000評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異翅楼,居然都是意外死亡尉剩,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評論 3 399
  • 文/潘曉璐 我一進店門毅臊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來理茎,“玉大人,你說我怎么就攤上這事≡砹郑” “怎么了朗鸠?”我有些...
    開封第一講書人閱讀 168,561評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長础倍。 經(jīng)常有香客問我烛占,道長,這世上最難降的妖魔是什么沟启? 我笑而不...
    開封第一講書人閱讀 59,782評論 1 298
  • 正文 為了忘掉前任忆家,我火速辦了婚禮,結(jié)果婚禮上美浦,老公的妹妹穿的比我還像新娘弦赖。我一直安慰自己,他們只是感情好浦辨,可當我...
    茶點故事閱讀 68,798評論 6 397
  • 文/花漫 我一把揭開白布蹬竖。 她就那樣靜靜地躺著,像睡著了一般流酬。 火紅的嫁衣襯著肌膚如雪币厕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,394評論 1 310
  • 那天芽腾,我揣著相機與錄音旦装,去河邊找鬼。 笑死摊滔,一個胖子當著我的面吹牛阴绢,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播艰躺,決...
    沈念sama閱讀 40,952評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼呻袭,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了腺兴?” 一聲冷哼從身側(cè)響起左电,我...
    開封第一講書人閱讀 39,852評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎页响,沒想到半個月后篓足,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,409評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡闰蚕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,483評論 3 341
  • 正文 我和宋清朗相戀三年栈拖,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片没陡。...
    茶點故事閱讀 40,615評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡辱魁,死狀恐怖烟瞧,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情染簇,我是刑警寧澤参滴,帶...
    沈念sama閱讀 36,303評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站锻弓,受9級特大地震影響砾赔,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜青灼,卻給世界環(huán)境...
    茶點故事閱讀 41,979評論 3 334
  • 文/蒙蒙 一暴心、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧杂拨,春花似錦专普、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至策橘,卻和暖如春炸渡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背丽已。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評論 1 272
  • 我被黑心中介騙來泰國打工蚌堵, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人沛婴。 一個月前我還...
    沈念sama閱讀 49,041評論 3 377
  • 正文 我出身青樓吼畏,卻偏偏與公主長得像,于是被迫代替她去往敵國和親嘁灯。 傳聞我的和親對象是個殘疾皇子泻蚊,可洞房花燭夜當晚...
    茶點故事閱讀 45,630評論 2 359

推薦閱讀更多精彩內(nèi)容