Hive進階篇(三)創建表+表結構*(字段類型、文件格式、行格式、分區表)


Hive進階篇(三)創建表+表結構*(字段類型、文件格式、行格式、分區表)

一、創建表

 外部表的徹底刪除參考:https://www.cnblogs.com/liuxinrong/articles/14409076.html

二、字段類型

1、簡單的

2、復雜的

三、文件格式

1、文本

log(日志文件)、csv文件(逗號分隔的)、tsv(tab分隔的)

2、JSON(一行是一個JSON)

3、Binary(二進制格式的)效率較高

     行式的(SequenceFile-用的很少了)、

     列式的(使用最廣泛,Parquet(用的更多)ORC

 PARQUET舉例--將TXT表轉換為PARQUET表:

 (1)先建表結構

DROP TABLE IF EXISTS pq_access_logs;
CREATE TABLE pq_access_logs (
    ip STRING,
    request_time STRING,
    method STRING,
    url STRING,
    http_version STRING,
    code1 STRING,
    code2 STRING,
    dash STRING,
    user_agent STRING,
    `timestamp` int)
STORED AS PARQUET;

(2)再將TXT表中的數據加載到建好的表中

INSERT OVERWRITE TABLE pq_access_logs
SELECT 
  ip,
  from_unixtime(unix_timestamp(request_time, 'dd/MMM/yyyy:HH:mm:ss z'), 'yyyy-MM-dd HH:mm:ss z'),
  method,
  url,
  http_version,
  code1,
  code2,
  dash,
  user_agent,
  unix_timestamp(request_time, 'dd/MMM/yyyy:HH:mm:ss z')
FROM original_access_logs;

這里使用 from_unixtime 和 unix_timestamp函數將日/月/年的順序進行調整 變成年-月-日的形式。

Parquet-二進制存儲的查詢效率更高

三、行格式(Row Format)

1、標准分隔符

     DELIMETED-反序列化(前面有DE表反)

     

2、需要自定義序列化類來處理

     SERDE-序列化

      

四、分區表

1、按照日期進行分區

CREATE TABLE partitioned_access_log ( ip STRING,

) ...

PARTITIONED BY (request_date STRING) ...;

hdfs:///access_logs/ ...

— 2017_01_20

— 2017_01_21

— 2017_01_22 ...

— "today" 

2、.../年/月/日 式的分區

CREATE TABLE partitioned_access_log ( ip STRING,

) ...

PARTITIONED BY (year STRING, month STRING, day STRING) ...; 

hdfs:///access_logs/ ...

— 2017

—— 01

——— 20

——— 21

——— 22 ... 

3、分區表的作用

避免全表掃描

提升查詢性能 減少IO

方便數據按分區寫入(覆蓋)

方便管理

4、分區表的操作演示

1)創建分區表-PARTITIONED BY

DROP TABLE IF EXISTS partitioned_access_logs;
CREATE EXTERNAL TABLE partitioned_access_logs (
    ip STRING,
    request_time STRING,
    method STRING,
    url STRING,
    http_version STRING,
    code1 STRING,
    code2 STRING,
    dash STRING,
    user_agent STRING,
    `timestamp` int)
PARTITIONED BY (request_date STRING)
STORED AS PARQUET
;

STORED AS PARQUET --文件格式是列式的。

2)將日志表寫入分區表,使用動態分區插入

set hive.exec.dynamic.partition.mode=nonstrict;

INSERT OVERWRITE TABLE partitioned_access_logs 
PARTITION (request_date)
SELECT ip, request_time, method, url, http_version, code1, code2, dash, user_agent, `timestamp`, to_date(request_time) as request_date
FROM pq_access_logs 
;

解釋:

set hive.exec.dynamic.partition.mode=nonstrict; 是在設置環境變量,

nonstrict是將分區設置成不嚴格的(默認是嚴格的-strict),這樣就能開啟動態分區的插入模式了。

to_date(request_time)是將 年月日時分秒 轉換成 日期的格式了。

如果是靜態的話,可以看下面這個例子:

set hive.exec.dynamic.partition.mode=nonstrict;

INSERT OVERWRITE TABLE partitioned_access_logs 
PARTITION (request_date = '2020-08-10') SELECT ip, request_time, method, url, http_version, code1, code2, dash, user_agent, `timestamp`, to_date(request_time) as request_date FROM pq_access_logs 
where request_time >= '2020-08-10' and requset_time < '2020-08-11'
;

將2020年8月10號-2020年8月11號之間的數據全部插入到2020-08-10的分區中。

當然因為一年有365天左右,這樣靜態的話就得寫好多遍這段demo了,所以還是采用動態的更高效。

當然,動態分區和靜態分區也是可以混用的-混合分區:

set hive.exec.dynamic.partition.mode=nonstrict;

INSERT OVERWRITE TABLE partitioned_access_logs 
PARTITION (year = '2020', month = '06', day) SELECT ip, request_time, method, url, http_version, code1, code2, dash, user_agent, `timestamp`, to_date(request_time) as request_date
FROM pq_access_logs 
;

3)查看分區表的分區情況

  • show partitions + 分區表表名

  (直接通過元數據進行查詢,效率最高。有的時候分區多的話,結果的時間會是無序的了)

  • 還有一種是select distinct + 分區根據的屬性名 + from + 分區表表名

  (需要從HDFS將文件讀一遍才可得到結果,較慢)

0: jdbc:hive2://localhost:10000> show partitions partitioned_access_logs;

結果:

+--------------------------+--+

|        partition         |

+--------------------------+--+

| request_date=2014-06-14  |

| request_date=2014-06-15  |

+--------------------------+--+

2 rows selected (0.277 seconds)

有兩個分區創建出來了-兩天的日志信息

4)看分區表的目錄形式

[root@cdh alternatives]# hdfs dfs -ls /user/hive/warehouse/partitioned_access_logs/

Found 2 items

drwxrwxrwt   - hive hive          0 2021-02-17 14:55 /user/hive/warehouse/partitioned_access_logs/request_date=2014-06-14

drwxrwxrwt   - hive hive          0 2021-02-17 14:55 /user/hive/warehouse/partitioned_access_logs/request_date=2014-06-15

可以看到該分區表的各分區之間是並列的形式

Hive的分區目錄名結尾是一種key(分區字段)=value(日期)的形式,不僅僅只有日期

每個分區目錄下面存的就是分區內的結果文件,文件的命名會以編號的形式按順序拍好.

5) 分區表加字段

alter table + 分區表名 + add columns (要增加的分區字段名 + 數據類型);

下面的寫法也可以:

alter table + 分區表名(也可以是數據庫.表名的形式) + add + partition  (分區字段名 = '指定的分區名中的日期')

注:分區表新加入的字段並不能真正插入數據,

     因為老的分區結構是在表結構剛建好之后就保存在元數據中的,是不會因為新字段的加入就改變的.

     如果要增加分區並且真正地可以插入數據的話,

  • 對於內部表:就需要刪除分區表,然后再創建一個新的分區表. 因為刪除個別分區之后里面的數據也會被刪除.
  • 對於外部表:可先刪除掉新加的分區字段所在的分區(刪掉的僅僅是表結構),再將其重建即可顯示出來了.   

6) 讀取個別分區

select * from + 分區表的表名+ where + 分區字段名 = '指定的分區名中的日期'

也可以在后面加上 limit+行數 進行打印行數的限制

7) 刪除個別分區字段

alter table + 分區表名(也可以是數據庫.表名的形式) + drop + partition  (分區字段名 = '指定的分區名中的日期')

 五、Storage Handler

通過創建一個外部表 Create External Table to Export Data

將數據導入到不同的數據庫中 像:

1.HBase

2.ElasticSearch

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM