在上一篇的結(jié)尾,我們拋出了一個(gè)企業(yè)生產(chǎn)環(huán)境的建表語句肋乍,發(fā)現(xiàn)鹅颊,這個(gè)建表語句中包含的知識(shí)點(diǎn)實(shí)在是太多了敷存,如果面面俱到地去介紹墓造,顯然篇幅會(huì)過長。所以锚烦,本篇主要是對上一篇的建表語句中的知識(shí)點(diǎn)進(jìn)行詳細(xì)闡述觅闽。先把建表語句搬過來:
CREATE EXTERNAL TABLE mdm_corpus_yx_labeled (
`uid` string,
`serial` string,
`query` string COMMENT '問題',
`domain` string COMMENT '領(lǐng)域',
`intent` string COMMENT '意圖',
`slots` string COMMENT '分槽,實(shí)體詞',
`marked_domain` string COMMENT '標(biāo)記的領(lǐng)域',
`marked_intent` string COMMENT '標(biāo)記的意圖',
`marked_slots` string COMMENT '標(biāo)記的實(shí)體詞',
`sid` string COMMENT '機(jī)器人sn號',
`b_answer` string COMMENT '回答')
PARTITIONED BY (`dates` STRING)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
COLLECTION ITEMS TERMINATED BY ','
MAP KEYS TERMINATED BY ':'
STORED AS PARQUET
LOCATION 'hdfs://xxxx/usr/corpus/unit_yx/mdm/mdm_corpus_yx_labeled';
外部表 外部表(EXTERNAL)指向已經(jīng)在HDFS中存在的數(shù)據(jù)涮俄。它和內(nèi)部表在元數(shù)據(jù)的組織上是相同的蛉拙,而實(shí)際數(shù)據(jù)的存儲(chǔ)則有較大的差異。內(nèi)部表的創(chuàng)建過程和數(shù)據(jù)加載過程這兩個(gè)過程可以分別獨(dú)立完成彻亲,也可以在一個(gè)語句中完成孕锄,在加載數(shù)據(jù)的過程中吮廉,實(shí)際數(shù)據(jù)會(huì)被移動(dòng)到數(shù)據(jù)倉庫目錄中;之后對數(shù)據(jù)的訪問將會(huì)直接在數(shù)據(jù)倉庫目錄中完成畸肆。刪除內(nèi)部表時(shí)宦芦,表中的數(shù)據(jù)和元數(shù)據(jù)將被同時(shí)刪除。而外部表只有一個(gè)過程轴脐,加載表和創(chuàng)建表同時(shí)完成(CREATE EXTERNAL TABLE …… LOCATION)调卑,實(shí)際數(shù)據(jù)存儲(chǔ)在 LOCATION 后面指定的 HDFS 路徑中,并不會(huì)移動(dòng)到數(shù)據(jù)倉庫目錄中大咱。當(dāng)刪除一個(gè)外部表時(shí)恬涧,其實(shí)只是刪除該鏈接。
mdm_corpus_yx_labeled 表名是按照業(yè)務(wù)進(jìn)行數(shù)據(jù)分層規(guī)范碴巾。那有的小伙伴就會(huì)問了溯捆,“什么是數(shù)據(jù)分層,為什么要進(jìn)行數(shù)據(jù)分層厦瓢?” 這是因?yàn)槲覀冎卫頂?shù)據(jù)的時(shí)候现使,希望可以對數(shù)據(jù)有一個(gè)更加清晰的把控。詳細(xì)來講旷痕,為什么要進(jìn)行數(shù)據(jù)分層有以下幾個(gè)方面的原因:
- 清晰數(shù)據(jù)結(jié)構(gòu):數(shù)據(jù)的每一個(gè)分層都有其特點(diǎn)以及使用范圍碳锈,這樣我們在使用表的時(shí)候能更方便地定位和理解業(yè)務(wù)邏輯。
- 數(shù)據(jù)血緣追蹤:通過數(shù)據(jù)分層欺抗,我們可以知道售碳,頂層的表是依賴于底層的哪張表或者哪幾張表。如果頂層的表一旦出現(xiàn)問題绞呈,我們可以迅速定位到底層的表贸人;同樣,如果底層的表出現(xiàn)了問題佃声,我們同樣可以快速定位到影響到哪幾張頂層的業(yè)務(wù)表艺智。
- 減少重復(fù)工作:規(guī)范數(shù)據(jù)分層,開發(fā)一些通用的中間層表圾亏,可以極大的減少重復(fù)計(jì)算十拣。沒有規(guī)范的數(shù)據(jù)分層時(shí),我們每個(gè)需求任務(wù)都是從最原始的表中解析志鹃,獲得相應(yīng)的字段夭问,然后再聚合分析輸出。如果我們將數(shù)據(jù)規(guī)范按照業(yè)務(wù)線模塊等進(jìn)行分塊曹铃,產(chǎn)生中間層表缰趋。那么我們再處理類似的需求時(shí),就可以直接依賴于中間層表,而不需要每次都用原始表開始解析秘血。
- 把復(fù)雜的問題簡單化:將一個(gè)負(fù)責(zé)的任務(wù)分解成多個(gè)步驟來完成味抖,每一層只處理單一的步驟,簡化了問題灰粮。
對于數(shù)據(jù)分層的重要性非竿,業(yè)界往往拿下面兩張圖做比喻。數(shù)據(jù)體系中的各個(gè)表的依賴就像是電線一樣谋竖,我們都希望它是很規(guī)整红柱,便于管理的。但是蓖乘,大部分公司的數(shù)據(jù)往往是第一幅圖锤悄,而非第二幅圖。
那既然數(shù)據(jù)分層在數(shù)據(jù)倉庫建設(shè)中有如此重要的地位嘉抒,業(yè)界有沒有一套統(tǒng)一的數(shù)據(jù)分層模型供大家參考呢零聚?這里我們介紹一下獵豹移動(dòng)的數(shù)據(jù)倉庫建設(shè):
在經(jīng)過長時(shí)間的數(shù)據(jù)倉庫迭代建設(shè)中,獵豹移動(dòng)建成了適合自己業(yè)務(wù)的高可用數(shù)據(jù)倉庫些侍,其主要分為 ODM 層隶症、MDM 層、IDM 層和 TDM 層四層數(shù)據(jù)倉庫模型岗宣。
- ODM 層 源數(shù)據(jù)層(Original Data Model)存儲(chǔ)源數(shù)據(jù)蚂会,面向業(yè)務(wù)應(yīng)用。
- MDM 層 集市數(shù)據(jù)層(Market Data Model)存儲(chǔ)基礎(chǔ)集市耗式,面向主題和業(yè)務(wù)線胁住,提供相對中性,具有業(yè)務(wù)意義的初級加工數(shù)據(jù)刊咳。
- IDM 層 接口數(shù)據(jù)層(Interface Data Model)存儲(chǔ)的是接口數(shù)據(jù)彪见,面向具體應(yīng)用,按需定制娱挨,提供對外數(shù)據(jù)服務(wù)或接口余指。
- TDM 層 臨時(shí)數(shù)據(jù)層(Temp Data Model)存儲(chǔ)業(yè)務(wù)處理過程中的臨時(shí)數(shù)據(jù)。
-
PARTITIONED BY Partition 對應(yīng)于關(guān)系數(shù)據(jù)庫中的 Partition 列的密集索引跷坝,但是 Hive 中 Partition 的組織方式和數(shù)據(jù)庫中的很不相同酵镜。在 Hive 中,表中的一個(gè) Partition 對應(yīng)于表下的一個(gè)目錄探孝,所有的 Partition 的數(shù)據(jù)都存儲(chǔ)在對應(yīng)的目錄中笋婿。例如誉裆,
mdm_corpus_yx_labeled
表中包含dates
分區(qū)顿颅,則對應(yīng)于dates = 2019-10-28
的 HDFS 子目錄為:/usr/corpus/unit_bhp/mdm/mdm_corpus_yx_labeled/2019-10-28
ROW FORMAT DELIMITED 是用來設(shè)置創(chuàng)建的表在加載數(shù)據(jù)的時(shí)候,支持的列分隔符足丢,在表
mdm_corpus_yx_labeled
中粱腻,列分隔符為\t
庇配。COLLECTION ITEMS TERMINATED BY 一個(gè)字段的各個(gè)
item
的分隔符,在表mdm_corpus_yx_labeled
中绍些,字段中各個(gè)item
分隔符為,
捞慌。MAP KEYS TERMINATED BY Map集合中,
key
和value
之間的分隔符柬批,在表mdm_corpus_yx_labeled
中啸澡,集合中,key
和value
的分隔符為:
氮帐。STORED AS Hive 支持 TextFile嗅虏、RCFile、SequenceFile上沐、AVRO皮服、ORC 和 Parquet 等存儲(chǔ)格式。那我們在建表的時(shí)候参咙,到底要采用哪種格式呢龄广?下面,我們來介紹一下各個(gè)存儲(chǔ)格式的特點(diǎn)和適用場景:
- TextFile 每一行表示一條記錄蕴侧,每行都以換行符結(jié)尾择同。數(shù)據(jù)不做壓縮,磁盤開銷大净宵,數(shù)據(jù)解析開銷大奠衔。可以結(jié)合 gzip塘娶,bzip2 使用(系統(tǒng)自動(dòng)會(huì)檢查是否使用了上述2種壓縮方式归斤,并在執(zhí)行查詢時(shí)自動(dòng)解壓),但是采用這種方式刁岸,Hive 不會(huì)對數(shù)據(jù)進(jìn)行切分脏里,從而無法對數(shù)據(jù)進(jìn)行并行操作。
- SequenceFile 是一種二進(jìn)制文件存儲(chǔ)方式虹曙,其具有使用方便迫横、可分割、可壓縮的特點(diǎn)酝碳,并支持三種壓縮等級:NONE矾踱,RECORD,BLOCK疏哗,使用中一般建議采用 BLOCK 壓縮呛讲。
- RCFile 是一種行列存儲(chǔ)結(jié)合的存儲(chǔ)方式。首先將數(shù)據(jù)按行分開,保證了同一條記錄在一個(gè)快上贝搁,避免了讀一條記錄需要讀取多個(gè) BLOCK吗氏。其次,對于每個(gè) BLOCK 列式存儲(chǔ)雷逆,有利于數(shù)據(jù)的壓縮和快速的列存取弦讽。
- ORC 提供了一種將數(shù)據(jù)存儲(chǔ)在 Hive 表中的高效方法,其原理同樣是將數(shù)據(jù)進(jìn)行按行分塊膀哲,每塊按照列存儲(chǔ)往产。但其效率要優(yōu)于 RCFile,可以看做是 RCFile 的強(qiáng)化版某宪。另外 ORC 還支持 ACID捂齐,支持單條記錄的 update 和 delete。
- Parquet 也是一種列式存儲(chǔ)的格式缩抡,相對于 ORC奠宜,Parquet 壓縮比較低,且不支持單條記錄的 update 和 delete瞻想,也不支持 ACID压真,但是 Parquet 支持 Impala 查詢引擎,所以更推薦使用該存儲(chǔ)格式蘑险。
下圖為各個(gè)存儲(chǔ)格式數(shù)據(jù)壓縮比較:
- LOCATION 是外部表實(shí)際數(shù)據(jù)的存儲(chǔ)路徑滴肿。
其他常用命令匯總
- 創(chuàng)建視圖,包含
query
和domain
字段:
hive> create view v_yx_labeled as select query,domain from mdm_corpus_yx_labeled;
- 查看數(shù)據(jù)庫佃迄、表和視圖:
hive> show databases;
hive> show databases like 'c.*'; # 以 c 開頭的所有數(shù)據(jù)庫
hive> use corpus;
hive> show tables;
- 向表中裝載本地文件系統(tǒng)數(shù)據(jù)泼差,并覆蓋表中原有數(shù)據(jù):
hive> load data local inpath '/user/liushaodong/unit_yx/data' overwrite into table mdm_corpus_yx_labeled_copy;
# 如果不覆蓋表中原有數(shù)據(jù),則去掉 overwrite 關(guān)鍵字
- 將分布式文件系統(tǒng)中的數(shù)據(jù)裝載到表中呵俏,并覆蓋表中原有數(shù)據(jù):
hive> load data inpath 'hdfs://xxxx/usr/corpus/unit_yx/mdm/mdm_corpus_yx_labeled overwrite into table mdm_corpus_yx_labeled_copy;
# 去掉 local 關(guān)鍵字堆缘,即默認(rèn)加載分布式文件系統(tǒng)中的數(shù)據(jù)
- 向表中插入數(shù)據(jù),覆蓋原有數(shù)據(jù):
hive> insert overwrite table mdm_corpus_yx_labeled_copy select * from mdm_corpus_yx_labeled where dates = '2020-01-20';
- 向表中追加插入數(shù)據(jù):
insert into table mdm_corpus_yx_labeled_copy select * from mdm_corpus_yx_labeled where dates = '2020-01-20';
# 追加數(shù)據(jù)即是將 overwrite 換成 into
OK普碎,本篇到這里就要結(jié)束了吼肥,想了解更多有關(guān)于數(shù)據(jù)科學(xué)的小伙伴們,可以關(guān)注我哦麻车!