文章目錄
一、Hive數據定義
1.1 基本數據類型
Hive數據類型 | Java數據類型 | 長度 |
---|---|---|
TINYINT | byte | 1byte有符號整數 |
SMALINT | short | 2byte有符號整數 |
INT | int | 4byte有符號整數 |
BIGINT | long | 8byte有符號整數 |
BOOLEAN | boolean | 布爾類型,true或者false |
FLOAT | float | 單精度浮點數 |
DOUBLE | double | 雙精度浮點數 |
STRING | string | 字符系列。可以指定字符集。可以使用單引號或者雙引號。 |
TIMESTAMP | 時間類型 | |
BINARY | 字節數組 |
對於Hive
的String
類型相當於數據庫的varchar
類型,該類型是一個可變的字符串,不過它不能聲明其中最多能存儲多少個字符,理論上它可以存儲2GB的字符數。
1.2 集合數據類型
數據類型 | 描述 | 語法示例 |
---|---|---|
STRUCT | 和c語言中的struct類似,都可以通過“點”符號訪問元素內容。例如,如果某個列的數據類型是STRUCT{first STRING, last STRING},那麼第1個元素可以通過字段.first來引用。 | struct() 例如struct<street:string, city:string> |
MAP | MAP是一組鍵-值對元組集合,使用數組表示法可以訪問數據。例如,如果某個列的數據類型是MAP,其中鍵->值對是’first’->’John’和’last’->’Doe’,那麼可以通過字段名[‘last’]獲取最後一個元素 | map() 例如map<string, int> |
ARRAY | 數組是一組具有相同類型和名稱的變量的集合。這些變量稱爲數組的元素,每個數組元素都有一個編號,編號從零開始。例如,數組值爲[‘John’, ‘Doe’],那麼第2個元素可以通過數組名[1]進行引用。 | Array() 例如array |
Hive
有三種複雜數據類型ARRAY
、MAP
和STRUCT
。ARRAY
和MAP
與Java
中的Array
和Map
類似,而STRUCT
與C
語言中的Struct
類似,它封裝了一個命名字段集合,複雜數據類型允許任意層次的嵌套。
1.3 複雜數據類型案例實操
① 假設某表有如下一行,我們用JSON
格式來表示其數據結構。在Hive
下訪問的格式爲
{
"name": "songsong",
"friends": ["bingbing" , "lili"] , //列表Array,
"children": { //鍵值Map,
"xiao song": 18 ,
"xiaoxiao song": 19
}
"address": { //結構Struct,
"street": "hui long guan" ,
"city": "beijing"
}
}
② 基於上述數據結構,我們在Hive
裏創建對應的表,並導入數據。 創建本地測試文件test.txt
songsong,bingbing_lili,xiao song:18_xiaoxiao song:19,hui long guan_beijing
yangyang,caicai_susu,xiao yang:18_xiaoxiao yang:19,chao yang_beijing
③ Hive
上創建測試表test
create table test(
name string,
friends array<string>,
children map<string, int>,
address struct<street:string, city:string>
)
row format delimited fields terminated by ','
collection items terminated by '_'
map keys terminated by ':'
lines terminated by '\n';
字段解釋:
row format delimited fields terminated by ','
:列分隔符
collection items terminated by '_'
:MAP STRUCT
和ARRAY
的分隔符(數據分割符號)
map keys terminated by ':'
:MAP
中的key
與value
的分隔符
lines terminated by '\n';
:行分隔符
1.4 類型轉化
Hive
的原子數據類型是可以進行隱式轉換的,類似於Java
的類型轉換,例如某表達式使用INT
類型,TINYINT
會自動轉換爲INT
類型,但是Hive
不會進行反向轉化,例如,某表達式使用TINYINT
類型,INT
不會自動轉換爲TINYINT
類型,它會返回錯誤,除非使用CAST
操作。
隱式類型轉換規則:
- 任何整數類型都可以隱式地轉換爲一個範圍更廣的類型,如
TINYINT
可以轉換成INT
,INT
可以轉換成BIGINT
- 所有整數類型、
FLOAT
和STRING
類型都可以隱式地轉換成DOUBLE
TINYINT
、SMALLINT
、INT
都可以轉換爲FLOAT
BOOLEAN
類型不可以轉換爲任何其它的類型
可以使用CAST
操作顯示進行數據類型轉換
例如CAST('1' AS INT)
將把字符串’1’ 轉換成整數1;如果強制類型轉換失敗,表達式返回空值NULL
。
0: jdbc:hive2://hadoop102:10000> select '1'+2, cast('1'as int) + 2;
二、DDL數據定義
2.1 數據庫相關操作
創建數據庫:
CREATE DATABASE [IF NOT EXISTS] database_name
[COMMENT database_comment]
[LOCATION hdfs_path]
[WITH DBPROPERTIES (property_name=property_value, ...)];
字段解釋:
[IF NOT EXISTS]
:數據庫如果存在,則不新增
[COMMENT database_comment]
:添加數據庫相關注釋
[LOCATION hdfs_path]
:指定數據庫在HDFS
上存儲的位置,默認位置爲/user/hive/warehouse/*.db
顯示數據庫: show databases;
過濾顯示查詢的數據庫:show databases like 'db_hive*';
顯示數據庫信息: desc database db_hive;
切換當前數據庫: use db_hive;
修改數據庫:
數據庫的其他元數據信息都是不可更改的,包括數據庫名和數據庫所在的目錄位置。
hive (default)> alter database db_hive set dbproperties('createtime'='20170830');
刪除數據庫: drop database db_hive2;
刪除非空數據庫: drop database db_hive cascade;
2.2表操作
①創建表
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]
[STORED AS file_format]
[LOCATION hdfs_path]
[TBLPROPERTIES (property_name=property_value, ...)]
[AS select_statement]
字段解釋:
- CREATE TABLE:創建一個指定名字的表。如果相同名字的表已經存在,則拋出異常;用戶可以用
IF NOT EXISTS
選項來忽略這個異常 - EXTERNAL:讓用戶創建一個外部表,在建表的同時可以指定一個指向實際數據的路徑(
LOCATION
)。在刪除表的時候,內部表的元數據和數據會被一起刪除,而外部表只刪除元數據,不刪除數據 - COMMENT:爲表和列添加註釋
- PARTITIONED BY:創建分區表
- CLUSTERED BY:創建分桶表
- SORTED BY:不常用,對桶中的一個或多個列另外排序
- ROW FORMAT :爲表初始化數據
- STORED AS:指定存儲文件類型。常用的存儲文件類型:
SEQUENCEFILE
(二進制序列文件)、TEXTFILE
(文本)、RCFILE
(列式存儲格式文件)。如果文件數據是純文本,可以使用STORED AS TEXTFILE
。如果數據需要壓縮,使用STORED AS SEQUENCEFILE
。 - LOCATION :指定表在
HDFS
上的存儲位置 - AS:後跟查詢語句,根據查詢結果創建表
- LIKE:允許用戶複製現有的表結構,但是不復制數據
②管理表(內部表)和外部表
內部表:
默認創建的表都是所謂的管理表,有時也被稱爲內部表,Hive
會控制着數據的生命週期。Hive
默認情況下會將這些表的數據存儲在由配置項hive.metastore.warehouse.dir
所定義的目錄的子目錄下。當我們刪除一個管理表時,Hive
也會刪除這個表中數據。管理表不適合和其他工具共享數據。
普通創建表:create table if not exists student( id int, name string)
查詢表的類型:
hive (default)> desc formatted student;
Table Type: MANAGED_TABLE
外部表:
因爲表是外部表,所以Hive
並非認爲其完全擁有這份數據。刪除該表並不會刪除掉這份數據,不過描述表的元數據信息會被刪除掉。
創建外部表:create external table if not exists student( id int, name string)
查詢表的類型:
hive (default)> desc formatted student;
Table Type: EXTERNAL_TABLE
管理表和外部表的使用場景:
每天將收集到的網站日誌定期流入HDFS
文本文件。在外部表(原始日誌表)的基礎上做大量的統計分析,用到的中間表、結果表使用內部表存儲,數據通過SELECT+INSERT
進入內部表。
管理表與外部表的互相轉換:
修改表爲外部表:alter table student set tblproperties('EXTERNAL'='TRUE');
修改表爲管理表:alter table student set tblproperties('EXTERNAL'='FALSE');
③分區表
分區表實際上就是對應一個HDFS
文件系統上的獨立的文件夾,該文件夾下是該分區所有的數據文件。Hive
中的分區就是分目錄,把一個大的數據集根據業務需要分割成小的數據集。在查詢時通過WHERE
子句中的表達式選擇查詢所需要的指定的分區,這樣的查詢效率會提高很多。
創建分區表:
hive (default)> create table dept_partition(
deptno int, dname string, loc string
)
partitioned by (month string)
row format delimited fields terminated by '\t';
注意:分區字段不能是表中已經存在的數據,可以將分區字段看作表的僞列。
加載數據到分區表中:
hive (default)> load data local inpath '/opt/module/datas/dept.txt' into table default.dept_partition partition(month='201709');
查詢分區表中數據:hive (default)> select * from dept_partition where month='201709';
增加分區:hive (default)> alter table dept_partition add partition(month='201706') ;
刪除分區:hive (default)> alter table dept_partition drop partition (month='201704');
查看分區表有多少分區:hive> show partitions dept_partition;
查看分區表結構:
hive> desc formatted dept_partition;
# Partition Information
# col_name data_type comment
month string
④修改、刪除表
重命名錶:ALTER TABLE table_name RENAME TO new_table_name
添加列:hive (default)> alter table dept_partition add columns(deptdesc string);
更新列:hive (default)> alter table dept_partition change column deptdesc desc int;
刪除表:hive (default)> drop table dept_partition;
清除表數據:hive (default)> truncate table student;
三、DML數據操作
3.1 數據導出
①Insert導出
將查詢的結果導出到本地:
hive (default)> insert overwrite local directory '/opt/module/datas/export/student'
select * from student;
將查詢的結果格式化導出到本地:
hive(default)>insert overwrite local directory '/opt/module/datas/export/student1'
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' select * from student;
將查詢的結果格式化導出到本地:
hive(default)>insert overwrite local directory '/opt/module/datas/export/student1'
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' select * from student;
②Hadoop命令導出到本地
hive (default)> dfs -get /user/hive/warehouse/student/month=201709/000000_0
/opt/module/datas/export/student3.txt;
③Hive Shell 命令導出
[root@hadoop100 hive]$ bin/hive -e 'select * from default.student;' >
/opt/module/datas/export/student4.txt;
④Export導出到HDFS上
(defahiveult)> export table default.student to
'/user/hive/warehouse/export/student';
⑤Sqoop導出
3.2 數據導入
①向表中裝載數據(Load)
語法:
hive> load data [local] inpath '/opt/module/datas/student.txt' [overwrite] into table student
[partition (partcol1=val1,…)];
- load data:表示加載數據
- local:表示從本地加載數據到
Hive
表;否則從HDFS
加載數據到Hive
表 - inpath:表示加載數據的路徑
- overwrite:表示覆蓋表中已有數據,否則表示追加
- into table:表示加載到哪張表
- student:表示具體的表
- partition:表示上傳到指定分區
②通過查詢語句向表中插入數據(Insert)
hive (default)> insert overwrite table student partition(month='201708')
select id, name from student where month='201709';
insert into
:以追加數據的方式插入到表或分區,原有數據不會刪除
insert overwrite
:會覆蓋表或分區中已存在的數據
③查詢語句中創建表並加載數據(As Select)
create table if not exists student3
as select id, name from student;
④創建表時通過Location指定加載數據路徑
hive (default)> create external table if not exists student5(
id int, name string
)
row format delimited fields terminated by '\t'
location '/student;
⑤Import數據到指定Hive表中
hive (default)> import table student2 partition(month='201709') from
'/user/hive/warehouse/export/student';