數(shù)據(jù)科學(xué)之路(6)Hive使用細(xì)節(jié)再深入

在上一篇的結(jié)尾,我們拋出了一個企業(yè)生產(chǎn)環(huán)境的建表語句,發(fā)現(xiàn),這個建表語句中包含的知識點(diǎn)實(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';
  1. 外部表 外部表(EXTERNAL)指向已經(jīng)在HDFS中存在的數(shù)據(jù)。它和內(nèi)部表在元數(shù)據(jù)的組織上是相同的,而實(shí)際數(shù)據(jù)的存儲則有較大的差異。內(nèi)部表的創(chuàng)建過程和數(shù)據(jù)加載過程這兩個過程可以分別獨(dú)立完成,也可以在一個語句中完成,在加載數(shù)據(jù)的過程中,實(shí)際數(shù)據(jù)會被移動到數(shù)據(jù)倉庫目錄中;之后對數(shù)據(jù)的訪問將會直接在數(shù)據(jù)倉庫目錄中完成。刪除內(nèi)部表時,表中的數(shù)據(jù)和元數(shù)據(jù)將被同時刪除。而外部表只有一個過程,加載表和創(chuàng)建表同時完成(CREATE EXTERNAL TABLE …… LOCATION),實(shí)際數(shù)據(jù)存儲在 LOCATION 后面指定的 HDFS 路徑中,并不會移動到數(shù)據(jù)倉庫目錄中。當(dāng)刪除一個外部表時,其實(shí)只是刪除該鏈接。

  2. mdm_corpus_yx_labeled 表名是按照業(yè)務(wù)進(jìn)行數(shù)據(jù)分層規(guī)范。那有的小伙伴就會問了,“什么是數(shù)據(jù)分層,為什么要進(jìn)行數(shù)據(jù)分層?” 這是因?yàn)槲覀冎卫頂?shù)據(jù)的時候,希望可以對數(shù)據(jù)有一個更加清晰的把控。詳細(xì)來講,為什么要進(jìn)行數(shù)據(jù)分層有以下幾個方面的原因:

  • 清晰數(shù)據(jù)結(jié)構(gòu):數(shù)據(jù)的每一個分層都有其特點(diǎn)以及使用范圍,這樣我們在使用表的時候能更方便地定位和理解業(yè)務(wù)邏輯。
  • 數(shù)據(jù)血緣追蹤:通過數(shù)據(jù)分層,我們可以知道,頂層的表是依賴于底層的哪張表或者哪幾張表。如果頂層的表一旦出現(xiàn)問題,我們可以迅速定位到底層的表;同樣,如果底層的表出現(xiàn)了問題,我們同樣可以快速定位到影響到哪幾張頂層的業(yè)務(wù)表。
  • 減少重復(fù)工作:規(guī)范數(shù)據(jù)分層,開發(fā)一些通用的中間層表,可以極大的減少重復(fù)計算。沒有規(guī)范的數(shù)據(jù)分層時,我們每個需求任務(wù)都是從最原始的表中解析,獲得相應(yīng)的字段,然后再聚合分析輸出。如果我們將數(shù)據(jù)規(guī)范按照業(yè)務(wù)線模塊等進(jìn)行分塊,產(chǎn)生中間層表。那么我們再處理類似的需求時,就可以直接依賴于中間層表,而不需要每次都用原始表開始解析。
  • 把復(fù)雜的問題簡單化:將一個負(fù)責(zé)的任務(wù)分解成多個步驟來完成,每一層只處理單一的步驟,簡化了問題。

對于數(shù)據(jù)分層的重要性,業(yè)界往往拿下面兩張圖做比喻。數(shù)據(jù)體系中的各個表的依賴就像是電線一樣,我們都希望它是很規(guī)整,便于管理的。但是,大部分公司的數(shù)據(jù)往往是第一幅圖,而非第二幅圖。

那既然數(shù)據(jù)分層在數(shù)據(jù)倉庫建設(shè)中有如此重要的地位,業(yè)界有沒有一套統(tǒng)一的數(shù)據(jù)分層模型供大家參考呢?這里我們介紹一下獵豹移動的數(shù)據(jù)倉庫建設(shè):

在經(jīng)過長時間的數(shù)據(jù)倉庫迭代建設(shè)中,獵豹移動建成了適合自己業(yè)務(wù)的高可用數(shù)據(jù)倉庫,其主要分為 ODM 層、MDM 層、IDM 層和 TDM 層四層數(shù)據(jù)倉庫模型。

  • ODM 層 源數(shù)據(jù)層(Original Data Model)存儲源數(shù)據(jù),面向業(yè)務(wù)應(yīng)用。
  • MDM 層 集市數(shù)據(jù)層(Market Data Model)存儲基礎(chǔ)集市,面向主題和業(yè)務(wù)線,提供相對中性,具有業(yè)務(wù)意義的初級加工數(shù)據(jù)。
  • IDM 層 接口數(shù)據(jù)層(Interface Data Model)存儲的是接口數(shù)據(jù),面向具體應(yīng)用,按需定制,提供對外數(shù)據(jù)服務(wù)或接口。
  • TDM 層 臨時數(shù)據(jù)層(Temp Data Model)存儲業(yè)務(wù)處理過程中的臨時數(shù)據(jù)。
  1. PARTITIONED BY Partition 對應(yīng)于關(guān)系數(shù)據(jù)庫中的 Partition 列的密集索引,但是 Hive 中 Partition 的組織方式和數(shù)據(jù)庫中的很不相同。在 Hive 中,表中的一個 Partition 對應(yīng)于表下的一個目錄,所有的 Partition 的數(shù)據(jù)都存儲在對應(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
  1. ROW FORMAT DELIMITED 是用來設(shè)置創(chuàng)建的表在加載數(shù)據(jù)的時候,支持的列分隔符,在表 mdm_corpus_yx_labeled 中,列分隔符為 \t。

  2. COLLECTION ITEMS TERMINATED BY 一個字段的各個 item 的分隔符,在表 mdm_corpus_yx_labeled 中,字段中各個 item 分隔符為 ,。

  3. MAP KEYS TERMINATED BY Map集合中,keyvalue 之間的分隔符,在表 mdm_corpus_yx_labeled 中,集合中,keyvalue 的分隔符為 :。

  4. STORED AS Hive 支持 TextFile、RCFile、SequenceFile、AVRO、ORC 和 Parquet 等存儲格式。那我們在建表的時候,到底要采用哪種格式呢?下面,我們來介紹一下各個存儲格式的特點(diǎn)和適用場景:

  • TextFile 每一行表示一條記錄,每行都以換行符結(jié)尾。數(shù)據(jù)不做壓縮,磁盤開銷大,數(shù)據(jù)解析開銷大。可以結(jié)合 gzip,bzip2 使用(系統(tǒng)自動會檢查是否使用了上述2種壓縮方式,并在執(zhí)行查詢時自動解壓),但是采用這種方式,Hive 不會對數(shù)據(jù)進(jìn)行切分,從而無法對數(shù)據(jù)進(jìn)行并行操作。
  • SequenceFile 是一種二進(jìn)制文件存儲方式,其具有使用方便、可分割、可壓縮的特點(diǎn),并支持三種壓縮等級:NONE,RECORD,BLOCK,使用中一般建議采用 BLOCK 壓縮。
  • RCFile 是一種行列存儲結(jié)合的存儲方式。首先將數(shù)據(jù)按行分開,保證了同一條記錄在一個快上,避免了讀一條記錄需要讀取多個 BLOCK。其次,對于每個 BLOCK 列式存儲,有利于數(shù)據(jù)的壓縮和快速的列存取。
  • ORC 提供了一種將數(shù)據(jù)存儲在 Hive 表中的高效方法,其原理同樣是將數(shù)據(jù)進(jìn)行按行分塊,每塊按照列存儲。但其效率要優(yōu)于 RCFile,可以看做是 RCFile 的強(qiáng)化版。另外 ORC 還支持 ACID,支持單條記錄的 update 和 delete。
  • Parquet 也是一種列式存儲的格式,相對于 ORC,Parquet 壓縮比較低,且不支持單條記錄的 update 和 delete,也不支持 ACID,但是 Parquet 支持 Impala 查詢引擎,所以更推薦使用該存儲格式。

下圖為各個存儲格式數(shù)據(jù)壓縮比較:

  1. LOCATION 是外部表實(shí)際數(shù)據(jù)的存儲路徑。

其他常用命令匯總

  1. 創(chuàng)建視圖,包含 querydomain 字段:
hive> create view v_yx_labeled as select query,domain from mdm_corpus_yx_labeled;
  1. 查看數(shù)據(jù)庫、表和視圖:
hive> show databases;
hive> show databases like 'c.*';   # 以 c 開頭的所有數(shù)據(jù)庫
hive> use corpus;
hive> show tables;
  1. 向表中裝載本地文件系統(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)鍵字
  1. 將分布式文件系統(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ù)
  1. 向表中插入數(shù)據(jù),覆蓋原有數(shù)據(jù):
hive> insert overwrite table mdm_corpus_yx_labeled_copy select * from mdm_corpus_yx_labeled where dates = '2020-01-20';
  1. 向表中追加插入數(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)注我哦!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容