hive基礎數據庫操作以及分區、動態分區、分桶


一、hive基礎概念

1、Hive是什么

  Hive 是建立在 Hadoop  上的數據倉庫基礎構架。它提供了一系列的工具,可以用來進行數據提取轉化加載(ETL ),這是一種可以存儲、查詢和分析存儲在 Hadoop  中的大規模數據的機制。Hive 定義了簡單的類 SQL  查詢語言,稱為 HQL ,它允許熟悉 SQL  的用戶查      詢數據。同時,這個語言也允許熟悉 MapReduce  開發者的開發自定義的 mapper  和 reducer  來處理內建的 mapper 和 reducer  無法完成的復雜的分析工作。

  Hive是SQL解析引擎,它將SQL語句轉譯成M/R Job然后在Hadoop執行。

  Hive的表其實就是HDFS的目錄,按表名把文件夾分開。如果是分區表,則分區值是子文件夾,可以直接在M/R Job里使用這些數據。

  Hive相當於hadoop的客戶端工具,部署時不一定放在集群管理節點中,可以放在某個節點上

 

2、hive與傳統數據庫比較

 

3、Hive的存儲格式

  Hive的數據存儲基於Hadoop HDFS。

  Hive沒有專門的數據文件格式,常見的有以下幾種。 TEXTFILE SEQUENCEFILE AVRO RCFILE ORCFILE PARQUET

 

 

 

 

 

 4、Hive操作客戶端

 

二、hive基礎語法(hive基礎語法與MySQL差不多)

1、建庫,刪庫;

  create database 庫名;

切換test1數據庫:

  use test1;

刪庫

  DROP DATABASE IF EXISTS ycc ;(刪除空數據庫)

  DROP DATABASE IF EXISTS ycc CASCADE;(刪除庫之前清空庫中表)

 

 

2、建表;

create [EXTERNAL] table students
(
    id bigint,
    name string,
    age int comment,
    gender string,
    clazz string
)
PARTITIONED BY ( 非必選;創建分區表
  dt string)
clustered by (userid) into 3000 buckets // 非必選;分桶子
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'  // 必選;指定列之間的分隔符 
STORED AS rcfile   // 非必選;指定文件的讀取格式,默認textfile格式
location '/testdata/'; //非必選;指定文件在hdfs上的存儲路徑,如果已經有文件,會自動加載 ,默認在hive的warehouse下
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name
  // 定義字段名,字段類型
  [(col_name data_type [COMMENT col_comment], ...)]
  // 給表加上注解
  [COMMENT table_comment]
  // 分區
  [PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)]
  // 分桶
  [CLUSTERED BY (col_name, col_name, ...) 
  // 設置排序字段 升序、降序
  [SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS]
  [
      // 指定設置行、列分隔符 
   [ROW FORMAT row_format] 
   // 指定Hive儲存格式:textFile、rcFile、SequenceFile 默認為:textFile
   [STORED AS file_format]
   
   | STORED BY 'storage.handler.class.name' [ WITH SERDEPROPERTIES (...) ]  (Note:  only available starting with 0.6.0)
  ]
  // 指定儲存位置
  [LOCATION hdfs_path]
  // 跟外部表配合使用,比如:映射HBase表,然后可以使用HQL對hbase數據進行查詢,當然速度比較慢
  [TBLPROPERTIES (property_name=property_value, ...)]  (Note:  only available starting with 0.6.0)
  [AS select_statement]  (Note: this feature is only available starting with 0.5.0.)

  A、全部使用默認格式

create table students
(
    id bigint,
    name string,
    age int,
    gender string,
    clazz string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','; // 必選,指定列分隔符 

  B、指定location (這種方式也比較常用)

create table students2
(
    id bigint,
    name string,
    age int,
    gender string,
    clazz string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
LOCATION '/input1'; // 指定Hive表的數據的存儲位置,一般在數據已經上傳到HDFS,想要直接使用,會指定Location,通常Locaion會跟外部表一起使用,內部表一般使用默認的location

  C、指定存儲格式

create table students3
(
    id bigint,
    name string,
    age int,
    gender string,
    clazz string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
STORED AS rcfile; // 指定儲存格式為rcfile,inputFormat:RCFileInputFormat,outputFormat:RCFileOutputFormat,如果不指定,默認為textfile,注意:除textfile以外,其他的存儲格式的數據都不能直接加載,需要使用從表加載的方式。

   D、create table xxxx as select_statement(SQL語句) (這種方式比較常用)

create table students4 as select * from students2;
  E、create table xxxx like table_name 只想建表,不需要加載數據
create table students5 like students;

 

2.1、內部表:

  1、內部表基礎建表語句一:(默認指定文件類型為TextFile,HDFS路徑為/user/hive/warehouse/庫/下)
    格式:

create table 表名
(
字段名1 字段類型1,
字段名2 字段類型2,
...
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '分隔符'; // 必選指定列之間的分隔符

  2、內部表基礎建表語句二:(HDFS路徑為/user/hive/warehouse/庫/下)
    格式:

create table 表名
(
字段名1 字段類型1,
字段名2 字段類型2,
...
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '分隔符' // 必選指定列之間的分隔符
STORED AS file_format;

    概述:
    STORED AS:指定具體的從HDFS獲取數據的格式,格式不匹配無法獲取(默認為TextFile)

  3、內部表基礎建表語句三:(HDFS路徑為/user/hive/warehouse/庫/下)
  格式:

create table 表名
(
字段名1 字段類型1,
字段名2 字段類型2,
...
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '分隔符' // 必選指定列之間的分隔符
STORED AS file_format

  location 'HDFS路徑';
    概述:
      location:表示指定hive數據在hdfs的路徑, 如果路徑不存在會自動創建,存在就直接綁定,不能通過hdfs路徑判斷是否是hive表
    注意:
      默認情況下 刪除表會把數據也刪除

2.2、外部表external
  格式:

create external table 表名
(
字段名1 字段類型1,
字段名2 字段類型2,
...
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '分隔符' // 必選指定列之間的分隔符
STORED AS file_format

  location 'HDFS路徑';
    注意:
      刪除外部表不會刪除HDFS上的元數據

 2.3、內部表和外部表的區別

   hdfs上創建目錄,上傳數據文件

   指定創建的路徑建表

   刪除表以后元數據對比

    刪除表

drop table students_internal;

 

 

  可以看出,刪除內部表的時候,表中的數據(HDFS上的文件)會被同表的元數據一起刪除,刪除外部表的時候,只會刪除表的元數據,不會刪除表中的數據(HDFS上的文件)

一般在公司中,使用外部表多一點,因為數據可以需要被多個程序使用,避免誤刪,通常外部表會結合location一起使用外部表還可以將其他數據源中的數據映射到 hive中,比如說:hbase,ElasticSearch......

設計外部表的初衷就是讓表的元數據 與 數據 解耦

 

 

 

3、加載數據(上傳到hive表,以文件的方式上傳)

a、上傳數據方式1:
  格式:

hadoop dfs -put linux路徑 hdfs路徑

 

b、上傳數據方式2:(直接在hive命令行操作)
  格式:

    dfs -put linux路徑 hdfs路徑

  優點:比在hadoop操作hdfs快的多

c、上傳數據方式3:(直接在hive命令行操作)
  格式:

 load data inpath '/HDFS路徑' into 表名(自動找到hdfs的路徑)

  注意:對於hive來說是加載
     對於HDFS來說是移動

d、上傳數據方式4:(直接在hive命令行操作)
  格式:

    load data local inpath '/本地路徑' into 表名(自動找到本地的路徑)

  注意:從本地上傳數據

 

 4、加載數據(表對表,將數據轉換成與之對應的格式)

create table IF NOT EXISTS students_test1 as select * from students  //這種加載創建表不能指定格式

 

 

 

 

insert [overwrite] into table students_test2 select * from students;

 

 

 

 

 

 

 

 

 

 

打開查看students表中內容不能直接查看明文

 

 

overwrite和into的區別

 

 

 

 

 

 

5、分區(以目錄的形式對數據分割,避免全局掃描)

注意:分區字段和普通字段沒有什么區別,所以不能和普通字段名重復

 

 建表語句:

CREATE TABLE students_pt(id bigint,name string,age int comment,gender string,clazz string
) PARTITIONED BY (year STRING, month STRING) 
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ',';

用法:

select * from students_pt where year=“2021” and month =“01”

未分區前

 

 

 

 分區以后:

create external table studentsPation(
    id bigint,
    name string,
    age int,
    gender string,
    clazz string
) PARTITIONED BY (dt string) 
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
STORED AS rcfile;

添加分區:
  alter table 表名 add partition(分區字段='值');
刪除分區:
  alter table 表名 drop partition(分區字段='值');
查看分區:
  select DISTINCT 分區字段 from 表;//建議使用
  show partitions 表; 
插入數據:
  load data local inpath '路徑' into table 表名 partiton(分組字段='值');
  分區不存在自動創建

增加分區: 

 

向指定分區上傳數據

 

 

 

 6、動態分區

有的時候我們原始表中的數據里面包含了 ''日期字段 dt'',我們需要根據dt中不同的日期,分為不同的分區,將原始表改造成分區表。

> hive默認不開啟動態分區

> 動態分區:根據數據中某幾列的不同的取值 划分 不同的分區

# 表示開啟動態分區
hive> set hive.exec.dynamic.partition=true;
# 表示動態分區模式:strict(需要配合靜態分區一起使用)、nostrict
# strict: insert into table students_pt partition(dt='anhui',pt) select ......,pt from students;
hive> set hive.exec.dynamic.partition.mode=nostrict;
# 表示支持的最大的分區數量為1000,可以根據業務自己調整
hive> set hive.exec.max.dynamic.partitions.pernode=1000;

  建立原始表並加載數據

create  table students(
    id bigint,
    name string,
    age int,
    gender string,
    clazz string,
    dt string
) 
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';

 

  建立分區表並加載數據

create table students01

(

    id bigint,

    name string,

    age int,

    gender string,

    clazz string

)

PARTITIONED BY(dt string)

ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';

 

  使用動態分區插入數據

// 分區字段需要放在 select 的最后,如果有多個分區字段 同理,它是按位置匹配,不是按名字匹配
insert into table students01 partition(dt) select id,name,age,gender,clazz,dt from students_dt;(按時間分區)
// 比如下面這條語句會使用age作為分區字段,而不會使用student_dt中的dt作為分區字段
insert into table students01 partition(dt) select id,name,age,gender,dt,age from students_dt;(按年齡分區)

 

 

 

 7、多級分區(分區最多三級分區

案例:按年月進行的動態分區

create  table students2(
    id bigint,
    name string,
    age int,
    gender string,
    clazz string,
    year string,
    month string
) 
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';

 

 

 

 

 創建分區表:

create  table students02(
    id bigint,
    name string,
    age int,
    gender string,
    clazz string
) PARTITIONED BY (dt_year string,dt_month string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';

 

 

 

 

 

8、分桶(動態的,直接操作數據)

Hive會自動根據bucket個數自動分配Reduce task的個數 Reduce個數與bucket個數一致

 格式:
     create external table 表名
            (
                字段名1 字段類型1,
                字段名2 字段類型2,
                ...
            )clustered by (分桶字段) into 分桶數量 buckets
            ROW FORMAT DELIMITED FIELDS TERMINATED BY '分隔符'  // 必選指定列之間的分隔符 
  注意:
    分桶字段來源普通字段,分同數量是明確的

 

8.1、開啟分桶開關

hive>set hive.enforce.bucketing=true;

 

 8.2、創建分桶表

create  table students03(
    id bigint,
    name string,
    age int,
    gender string,
    clazz string
) clustered by (clazz) into 12 buckets
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';

 

 

8.3、加載數據

load:不會觸發分桶

insert into:自動觸發分桶

分析:發現有的分桶后有的文件是空,有的文件clazz占了幾個,這是為什么呢

  因為分桶機制是按key機制去區分,這里以clazz為key作為區分,正常來說每個reduce處理一個key,但是處理機制對key值進行取值取余處理,可能兩個班級的處理之后相同,就會進入到一個reduce中,那么就會有reduce為空

 

 

 

8.5、好處:

1、減少map端數據傾斜,資源平均處理,數據跑的快一點

2、方便數據抽樣,在每個分桶抽取數據

不常用,因為對文件進行切分產生過多的小文件

 


免責聲明!

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



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