Hive SQL基本使用詳解

一:簡介

Hive是一個數據倉庫基礎的應用工具,在Hadoop中用來處理結構化數據,它架構在Hadoop之上,通過SQL來對數據進行操作。

Hive 查詢操作過程嚴格遵守Hadoop MapReduce 的作業執行模型,Hive 將用戶的Hive SQL 語句通過解釋器轉換為MapReduce 作業提交到Hadoop 集群上,Hadoop 監控作業執行過程,然後返回作業執行結果給用戶。Hive 並非為聯機事務處理而設計,Hive 並不提供實時的查詢和基於行級的數據更新操作。Hive 的最佳使用場合是大數據集的批處理作業。

Hive SQL 與 SQL的區別:
  1. HQL不支持行級別的增(insert into table values)、改、刪,所有數據在加載時就已經確定,不可更改。
  2. 不支持事務
  3. 支持分區存儲

二:Hive數據類型

  • 基礎數據類型:boolean、tinyint、smallint、int、bigint、float、double、deicimal、String(字符串,不需要指定字符串長度)、varchar(需要指定字符串長度)、char、binary(字節數組)、timestamp(時間戳,納秒精度)、date(日期YYYY-MM-DD)
  • 複合數據類型:array:可通過下標獲取指定索引對應的值map:可通過key來獲取valuestruct:可以通過點.語法獲取union

三:常用Hive SQL

<code>-- 創建數據庫
create database ;

-- 切換數據庫
use ;

-- 複製一個表的表結構(不包含數據)
create table like
-- 創建表包含數據
create table as select * from

-- 列出所有數據庫
show databases;

-- 顯示所有的表
show tables;

-- 顯示所有分區
show partitions;
show partitions ;

-- 顯示所有函數
show functions;

-- 更改表明
ALTER TABLE RENAME TO ;

-- 增加列
alter table ADD COLUMNS ( COMMENT [列註釋]);

-- 查看錶結構
describe extended ;

-- 清空表數據
truncate table ;

-- 刪除表
drop table ;

-- 刪除視圖
drop view ;
/<code>

四:示例

struct和array都屬於collection, map中也使用collection分隔符分隔每個entry,常用的字段分隔符有"," 、"\\t"。

<code>>hive create database test;
>hive use test;

>hive create table if not exists employee(
id bigint,
username string,
age tinyint,
weight decimal(10, 2),
create_time timestamp,
is_test boolean,
tags array<string>,
ext map<string> comment '擴展字段',
address struct<string>
)
comment '員工表'
row format delimited
fields terminated by ','
collection items terminated by '#'
map keys terminated by ':'
lines terminated by '\\n';
/<string>/<string>/<string>/<code>

/data/employee.txt

<code>1,zhangsan,28,60.66,2020-02-01 10:00:00,true,eat#drink,k1:v1#k2:20,s1#c1#s1#1
2,lisi,29,60.66,2020-02-01 11:00:00,false,play#drink,k3:v3#k4:30,s2#c2#s1#2
/<code>
<code># 加載數據到hive
hive > load data local inpath '/data/employee.txt' into table employee;

# 查詢數據
hive > seleict * from employee;
hive > select username, tags[0], address.city, ext['k1'] from employee;

# stack(記錄總行數,記錄數據)
hive > insert into table employee
select stack(
1,
3, "wangwu", 30, 70.00, current_timestamp, true, array('eat','play','happy'), map("k5", 5, "key6", "value6"), named_struct("street", "street3", "city", "city3", "state", "state3", "zip", 3)

) from employee
limit 1;
/<code>

執行insert into select的時候可能會報錯,在hive-site.xml中配置以下兩個參數。有的時候還會報錯不知道為什麼,這裡先load data兩條數據,然後insert into select 一條數據就插入成功了。hive3.1.2中自己使用insert into values這種語法沒有插入成功。

<code><property>
<name>hive.enforce.bucketing/<name>
<value>true/<value>
/<property>
<property>
<name>hive.exec.dynamic.partition.mode/<name>
<value>nonstrict/<value>
/<property>
/<code>
Hive SQL基本使用詳解

五:Hive中文註釋亂碼

創建數據庫時我們一般使用utf8編碼,安裝數據庫一般也選擇utf8編碼,數據庫連接url通常也會使用characterEncoding=UTF-8參數,Hive中文註釋亂碼大部分原因都是因為hive在初始化數據庫時使用的SQL腳本中設定的編碼是latin1編碼。因此只需要修改數據庫表的字段的編碼即可。

初始化數據庫時是通過命令./schematool -dbType mysql -initSchema來初始化的,此命令會執行 /libexec/scripts/metastore/upgrade/mysql/hive-schema-3.0.0.mysql.sql這個SQL腳本,我們只需要修改這個腳本對應的表對應的字段的編碼即可(注意:不可將所有字段及表的編碼都改成utf8, 只需要修該某幾個字段對應的編碼即可,如果修改表的編碼可能會報錯)。

方式一:修改sql腳本,刪除數據庫,重新初始化

修改hive-schema-3.0.0.mysql.sql腳本中的COLUMNSV2. COMMENT、TABLEPARAMS. PARAMVALUE、PARTITIONKEYS. PKEY_COMMENT字段對應的編碼為utf8, 其它字段不需要修改,表的編碼也不需要修改,只需要修改這3個字段的編碼即可。SQL腳本修改後把數據庫刪掉再重新初始化(./schematool -dbType mysql -initSchema)。如果數據庫裡的數據不重要,可以刪掉數據庫重新初始化。

  • 列的註釋是存放到COLUMNS_V2表COMMENT字段上,需要將COMMENT字段字符集修改為utf-8
  • 表的註釋是存放到TABLEPARAMS表PARAMVALUE字段上,需要將PARAM_VALUE字段字符集修改為utf-8
  • 分區註釋是存放到PARTITIONKEYS表PKEYCOMMENT字段上,需要將PKEY_COMMENT字段字符集修改為utf-8

修改COLUMNS_V2表COMMENT字段的編碼為utf8

<code>CREATE TABLE IF NOT EXISTS `COLUMNS_V2` (
`CD_ID` bigint(20) NOT NULL,

`COMMENT` varchar(256) CHARACTER SET utf8 DEFAULT NULL,

`COLUMN_NAME` varchar(767) CHARACTER SET SET latin1 COLLATE latin1_bin NOT NULL,
`TYPE_NAME` MEDIUMTEXT DEFAULT NULL,
`INTEGER_IDX` int(11) NOT NULL,
PRIMARY KEY (`CD_ID`,`COLUMN_NAME`),
KEY `COLUMNS_V2_N49` (`CD_ID`),
CONSTRAINT `COLUMNS_V2_FK1` FOREIGN KEY (`CD_ID`) REFERENCES `CDS` (`CD_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/<code>

修改TABLEPARAMS表PARAMVALUE字段的編碼為utf8

<code>CREATE TABLE IF NOT EXISTS `TABLE_PARAMS` (
`TBL_ID` bigint(20) NOT NULL,
`PARAM_KEY` varchar(256) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,

`PARAM_VALUE` MEDIUMTEXT CHARACTER SET utf8 DEFAULT NULL,

PRIMARY KEY (`TBL_ID`,`PARAM_KEY`),
KEY `TABLE_PARAMS_N49` (`TBL_ID`),
CONSTRAINT `TABLE_PARAMS_FK1` FOREIGN KEY (`TBL_ID`) REFERENCES `TBLS` (`TBL_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/<code>

修改PARTITIONKEYS表PKEYCOMMENT字段的編碼為utf8

<code>CREATE TABLE IF NOT EXISTS `PARTITION_KEYS` (
`TBL_ID` bigint(20) NOT NULL,

`PKEY_COMMENT` varchar(4000) CHARACTER SET utf8 DEFAULT NULL,

`PKEY_NAME` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,

`PKEY_TYPE` varchar(767) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
`INTEGER_IDX` int(11) NOT NULL,
PRIMARY KEY (`TBL_ID`,`PKEY_NAME`),
KEY `PARTITION_KEYS_N49` (`TBL_ID`),
CONSTRAINT `PARTITION_KEYS_FK1` FOREIGN KEY (`TBL_ID`) REFERENCES `TBLS` (`TBL_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/<code>
方式二:直接修改現有數據庫表的字段的編碼

如果數據庫中的數據重要不能刪除,則直接修改字段的編碼即可。

<code>mysql> alter table COLUMNS_V2 modify column `COMMENT` varchar(256) character set utf8;
mysql> alter table TABLE_PARAMS modify column PARAM_VALUE varchar(4000) character set utf8;
mysql> alter table PARTITION_KEYS modify column PKEY_COMMENT varchar(4000) character set utf8;
/<code>
<code>hive> create table tbl_test (id bigint, username string comment "用戶名")
comment "測試表"
partitioned by (city string comment "城市")
row format delimited
fields terminated by ","
lines terminated by "\\n"
stored as textfile;

-- 查看錶結構
hive> describe extended tbl_test;
/<code>
Hive SQL基本使用詳解


分享到:


相關文章: