Hive零基础从入门到实战 入门篇(七)HiveQL:表操作(上)

目录

前言

1. 最简单的建表语句

2. 查看表结构

3. 删除表

4. 建表时为字段添加注释

5. 建表可选项IF NOT EXITS

6. 建表可选项 EXTERNAL

6.1 内部表

6.2 外部表

7. 建分区表

8. 其余建表可选项

9. 查询既有表的建表语句


 

前言

熟悉了Hive的库操作后,本文来介绍Hive中的的建表、删表操作。

 

1. 最简单的建表语句

Hive建表的全部建表语法如下:

CREATE [EXTERNAL] TABLE [IF NOT EXISTS] 表名
(列名 data_type [COMMENT 列注释], ...)
[COMMENT 表注释]
[PARTITIONED BY (列名 data_type [COMMENT 列注释], ...)]
[CLUSTERED BY (列名, 列名, ...) 
[SORTED ,BY (列名 [ASC|DESC], ...)] INTO num_buckets BUCKETS]
[ROW FORMAT row_format]
[STORED AS file_format]
[LOCATION hdfs_path]

所有[ ]中的内容都是可选项,即可有可无,下面我们分别详细介绍。

其中

CREATE [EXTERNAL] TABLE [IF NOT EXISTS] 表名
(列名 data_type)

是建表语句必须有的,举个栗子,这是后续实战篇要用到的第一个表,用户启动表:

CREATE TABLE t_od_use_cnt (
      date_8 INT
      ,platform string
      ,app_version string
      ,user_id BIGINT
      ,use_cnt INT
      ,is_active TINYINT
      );

首先我们建一个库app,然后使用并在其中建表,执行效果如下:

hive> create database app;
OK
Time taken: 0.899 seconds
hive> use app;
OK
Time taken: 0.03 seconds
hive> create table t_od_use_cnt(
    >       date_8 int
    >       ,platform string
    >       ,app_version string
    >       ,user_id bigint
    >       ,use_cnt int
    >       ,is_active tinyint
    >       );
OK
Time taken: 0.389 seconds
hive> 

ps:Hive中的关键字大小写是不区分的,所有关键字均可使用小写。

 

2. 查看表结构

DESC 表名;

 查询上一步新建表的字段及字段对应的数据类型,运行效果如下:

hive> desc t_od_use_cnt;
OK
date_8              	int                 	                
platform            	string              	    
app_version         	string              	              
user_id             	bigint              	               
use_cnt             	int                 	            
is_active           	tinyint             	                
Time taken: 0.28 seconds, Fetched: 6 row(s)
hive> 

 

3. 删除表

删除表的语句和删除库的类似,只是把database换成了table,都是使用drop关键字进行删除操作。

DROP TABLE 表名;

 

4. 建表时为字段添加注释

这里我们先删去刚才新建的表t_od_use_cnt,重新建一个有字段注释的表,因为Hive中是不允许有同名表存在的。

使用刚学的删表语句:

DROP TABLE t_od_use_cnt;

执行效果如下:

hive> drop table t_od_use_cnt;
OK
Time taken: 0.898 seconds
hive> 

重新建表,为字段添加中文注释,注意需要Xshell编码格式已修改为UTF-8。

CREATE TABLE t_od_use_cnt (
      date_8 INT comment '日期'
      ,platform string comment '平台 android,ios'
      ,app_version string comment 'app版本'
      ,user_id BIGINT comment '用户id'
      ,use_cnt INT comment '当日使用次数'
      ,is_active TINYINT comment '是否活跃'
      );

查询上一步新建的表,执行效果如下:

hive> desc t_od_use_cnt;
OK
date_8              	int                 	??                  
platform            	string              	?? android?ios      
app_version         	string              	APP??               
user_id             	bigint              	??id                
use_cnt             	int                 	??????              
is_active           	tinyint             	????                
Time taken: 0.28 seconds, Fetched: 6 row(s)
hive> 

此时字段注释里的中文显示是乱码,英文可以正常显示,在工作中这种情况我们是不会遇到的,运维的同事会帮我们搞定,如果是使用我提供的虚拟机的同学,此时会遇到这种情况,按如下操作即可:

  • 首先复制此时的窗口,右键单击New Session,点击Duplicate

Hive零基础从入门到实战 入门篇(七)HiveQL:表操作(上)_第1张图片

  • 登陆Hive的元数据库mysql,输入 mysql -uroot -proot,运行效果如下:
[root@hadoop ~]# mysql -uroot -proot
Warning: Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 122
Server version: 5.6.25-log MySQL Community Server (GPL)

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 
  • 使用hive库,修改字符编码为utf8,命令如下:
use hive;
alter table COLUMNS_V2 modify column comment varchar(256) character set utf8;
alter table TABLE_PARAMS modify column PARAM_VALUE varchar(4000) character set utf8;
alter table PARTITION_KEYS modify column PKEY_COMMENT varchar(4000) character set utf8;
alter table PARTITION_PARAMS  modify column PARAM_VALUE varchar(4000) character set utf8;

运行效果如下:

mysql> use hive;
Database changed

mysql> alter table COLUMNS_V2 modify column comment varchar(256) character set utf8;
Query OK, 25 rows affected (0.75 sec)
Records: 25  Duplicates: 0  Warnings: 0

mysql> alter table TABLE_PARAMS modify column PARAM_VALUE varchar(4000) character set utf8;
Query OK, 7 rows affected (0.28 sec)
Records: 7  Duplicates: 0  Warnings: 0

mysql> alter table PARTITION_KEYS modify column PKEY_COMMENT varchar(4000) character set utf8;
Query OK, 0 rows affected (0.32 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> alter table PARTITION_PARAMS  modify column PARAM_VALUE varchar(4000) character set utf8;
Query OK, 0 rows affected (0.16 sec)
Records: 0  Duplicates: 0  Warnings: 0
  • 返回Hive窗口,删除t_od_use_cnt,重新建表并查询表结构,运行效果如下:
hive> drop table t_od_use_cnt;
OK
Time taken: 0.456 seconds
hive> CREATE TABLE t_od_use_cnt(
    >       date_8 INT COMMENT '日期'
    >       ,platform STRING COMMENT '平台 android,ios'
    >       ,app_version STRING COMMENT 'APP版本'
    >       ,user_id BIGINT COMMENT '用户id'
    >       ,use_cnt INT COMMENT '当日使用次数'
    >       ,is_active TINYINT COMMENT '是否活跃'
    >       );
OK
Time taken: 0.106 seconds
hive> desc t_od_use_cnt;
OK
date_8              	int                 	日期                  
platform            	string              	平台 android,ios      
app_version         	string              	APP版本               
user_id             	bigint              	用户id                
use_cnt             	int                 	当日使用次数              
is_active           	tinyint             	是否活跃                
Time taken: 0.115 seconds, Fetched: 6 row(s)
hive> 

 

5. 建表可选项IF NOT EXITS

如果用户增加上可选项 IF NOT EXITS,那么若表已经存在了,Hive就会忽略掉后面的执行语句,而且不会有任何提示。在那些第一次执行时需要创建表的脚本中,这么写是非常有用的。不过工作中基本用不到,可以忽略。
 

6. 建表可选项 EXTERNAL

 

6.1 内部表

在Hive中,我们把在建表时建表语句中没有加 [EXTERNAL]的表称为内部表或者管理表,代表着Hive可以控制这个表的生命周期,如果drop掉这个表,那么这个表的元数据和数据会被一起删掉。默认情况下,Hive会给数据指定一个默认的HDFS中的存储目录,上面的表所在的目录是hdfs://hadoop:9000/usr/hive/warehouse/app.db/t_od_use_cnt,/usr/hive/warehouse是默认的数据仓库路径地址,app.db是数据库目录,t_od_use_cnt是表目录。

通过以下语句可以查询到目录信息及很多其他表的信息,后续我们会经常用到这个语句:

DESC formatted 表名;

运行效果如下:

hive> desc formatted t_od_use_cnt;
OK
# col_name            	data_type           	comment             
	 	 
date_8              	int                 	日期                  
platform            	string              	平台 android,ios      
app_version         	string              	app版本               
user_id             	bigint              	用户id                
use_cnt             	int                 	当日使用次数              
is_active           	tinyint             	是否活跃                
	 	 
# Detailed Table Information	 	 
Database:           	app                 	 
Owner:              	root                	 
CreateTime:         	Thu Apr 18 17:29:21 CST 2019	 
LastAccessTime:     	UNKNOWN             	 
Protect Mode:       	None                	 
Retention:          	0                   	 
Location:           	hdfs://hadoop:9000/usr/hive/warehouse/app.db/t_od_use_cnt	 
Table Type:         	MANAGED_TABLE       	 
Table Parameters:	 	 
	transient_lastDdlTime	1555579761          
	 	 
# Storage Information	 	 
SerDe Library:      	org.apache.hadoop.hive.serde2.lazy.LazySimpleSerD 
InputFormat:        	org.apache.hadoop.mapred.TextInputFormat	 
OutputFormat:       	org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat	 
Compressed:         	No                  	 
Num Buckets:        	-1                  	 
Bucket Columns:     	[]                  	 
Sort Columns:       	[]                  	 
Storage Desc Params:	 	 
	serialization.format	1                   
Time taken: 0.157 seconds, Fetched: 31 row(s)
hive> 

可以看到内部表的Table Type:             MANAGED_TABLE 

 

6.2 外部表

在Hive中,我们把在建表时建表语句中加 [EXTERNAL]的表称为外部表,与内部表不同,Hive只能拥有外部表的元数据(描述表的信息),删除表时并不会删掉数据本身,同时通过[LOCATION] 关键字自定义数据路径。

不过建外部表的操作在数据分析师的工作中基本用不到。建表语句如下:

CREATE EXTERNAL TABLE t_od_use_cnt (
      date_8 INT comment '日期'
      ,platform string comment '平台 android,ios'
      ,app_version string comment 'app版本'
      ,user_id BIGINT comment '用户id'
      ,use_cnt INT comment '当日使用次数'
      ,is_active TINYINT comment '是否活跃'
      ) location '/data/test';

建表后使用 desc formatted t_od_use_cnt; 查询表信息如下:

hive> create database test;
OK
Time taken: 0.144 seconds
hive> use test;
OK
Time taken: 0.027 seconds
hive> create external table t_od_use_cnt(
    >       date_8 int comment '日期'
    >       ,platform string comment '平台 android,ios'
    >       ,app_version string comment 'app版本'
    >       ,user_id bigint comment '用户id'
    >       ,use_cnt int comment '当日使用次数'
    >       ,is_active tinyint comment '是否活跃'
    >       )
    > location '/data/test';
OK
Time taken: 0.187 seconds
hive> desc formatted t_od_use_cnt;
OK
# col_name            	data_type           	comment             
	 	 
date_8              	int                 	日期                  
platform            	string              	平台 android,ios      
app_version         	string              	app版本               
user_id             	bigint              	用户id                
use_cnt             	int                 	当日使用次数              
is_active           	tinyint             	是否活跃                
	 	 
# Detailed Table Information	 	 
Database:           	test                	 
Owner:              	root                	 
CreateTime:         	Fri Apr 19 07:37:34 CST 2019	 
LastAccessTime:     	UNKNOWN             	 
Protect Mode:       	None                	 
Retention:          	0                   	 
Location:           	hdfs://hadoop:9000/data/test	 
Table Type:         	EXTERNAL_TABLE      	 
Table Parameters:	 	 
	EXTERNAL            	TRUE                
	transient_lastDdlTime	1555630654          
	 	 
# Storage Information	 	 
SerDe Library:      	org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe	 
InputFormat:        	org.apache.hadoop.mapred.TextInputFormat	 
OutputFormat:       	org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat	 
Compressed:         	No                  	 
Num Buckets:        	-1                  	 
Bucket Columns:     	[]                  	 
Sort Columns:       	[]                  	 
Storage Desc Params:	 	 
	serialization.format	1                   
Time taken: 0.134 seconds, Fetched: 32 row(s)
hive> 

可以看到外部表的Table Type:             EXTERNAL_TABLE           

 

7. 建分区表

Hive中有分区表的概念,分区表改变了Hive对数据存储的组织方式,提高了查询速度。上面我们已经介绍过,如果我们在app数据库中建表,数据存储路径是hdfs://hadoop:9000/usr/hive/warehouse/app.db/t_od_use_cnt,如果我们以日期date_8作为分区字段,那么数据存储路径会反映出分区结构的子目录,例如:

/usr/hive/warehouse/app.db/t_od_use_cnt/date_8=20190401

/usr/hive/warehouse/app.db/t_od_use_cnt/date_8=20190402

/usr/hive/warehouse/app.db/t_od_use_cnt/date_8=20190403

/usr/hive/warehouse/app.db/t_od_use_cnt/date_8=20190404

/usr/hive/warehouse/app.db/t_od_use_cnt/date_8=20190405

......

这样查询时如果我们限定了分区范围,Hive就可以直接去相应的目录下查询数据,而不需要扫描整个表,所以当数据量很大时可以显著提高查询性能。

建立分区表要使用关键字[PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)] ,注意分区的字段不可在普通字段中重复出现。分区表在工作中十分常见,一般来说公司所有的表都会以日期进行分区,以便提高查询效率。

我们还是以t_od_use_cnt为例,建表语句如下:

CREATE TABLE t_od_use_cnt (
      platform string comment '平台 android,ios'
      ,app_version string comment 'app版本'
      ,user_id BIGINT comment '用户id'
      ,use_cnt INT comment '当日使用次数'
      ,is_active TINYINT comment '是否活跃'
      ) partitioned BY (date_8 INT comment '日期');

我们先使用set hive.cli.print.current.db=true;命令来显示当前库名,然后使用show tables;命令来查询当前库有哪些表,建表成功后,再使用desc命令查询表结构。执行效果如下:

hive> set hive.cli.print.current.db=true;
hive (default)> use app;
OK
Time taken: 0.619 seconds
hive (app)> show tables;
OK
t_od_use_cnt
Time taken: 0.262 seconds, Fetched: 1 row(s)
hive (app)> drop table t_od_use_cnt;
OK
Time taken: 1.303 seconds
hive (app)> create table t_od_use_cnt(
          >        platform string comment '平台 android,ios'
          >       ,app_version string comment 'app版本'
          >       ,user_id bigint comment '用户id'
          >       ,use_cnt int comment '当日使用次数'
          >       ,is_active tinyint comment '是否活跃'
          >       )
          > partitioned by (date_8 int comment '日期');
OK
Time taken: 0.921 seconds
hive (app)> desc t_od_use_cnt;
OK
platform            	string              	平台 android,ios      
app_version         	string              	app版本               
user_id             	bigint              	用户id                
use_cnt             	int                 	当日使用次数              
is_active           	tinyint             	是否活跃                
date_8              	int                 	日期                  
	 	 
# Partition Information	 	 
# col_name            	data_type           	comment             
	 	 
date_8              	int                 	日期                  
Time taken: 0.165 seconds, Fetched: 11 row(s)
hive (app)> 

可以看到date_8作为分区字段创建好后表现的和普通字段完全一样。

 

8. 其余建表可选项

[CLUSTERED BY (col_name, col_name, ...) [SORTED ,BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS] :

这个关键字是Hive中的分桶操作,数据分析师基本用不到,感兴趣的同学自行百度即可;

[ROW FORMAT row_format] :

这个关键字用于指定数据切分格式,一般使用 '\t' 作为列之间的切分格式。本博客中为了导入csv文件,统一使用逗号进行分割,建表语句如下:

CREATE TABLE t_od_use_cnt (
      platform string comment '平台 android,ios'
      ,app_version string comment 'app版本'
      ,user_id BIGINT comment '用户id'
      ,use_cnt INT comment '当日使用次数'
      ,is_active TINYINT comment '是否活跃'
      ) partitioned BY (date_8 INT comment '日期') row format delimited fields terminated BY ',';

执行后查看表信息,效果如下:

hive> create table t_od_use_cnt (
    >       platform string comment '平台 android,ios'
    >       ,app_version string comment 'app版本'
    >       ,user_id BIGINT comment '用户id'
    >       ,use_cnt INT comment '当日使用次数'
    >       ,is_active TINYINT comment '是否活跃'
    >       ) partitioned BY (date_8 INT comment '日期') row format delimid fields terminated BY ',';
OK
Time taken: 0.313 seconds
hive> desc formatted t_od_use_cnt;
OK
# col_name            	data_type           	comment             
	 	 
platform            	string              	平台 android,ios      
app_version         	string              	app版本               
user_id             	bigint              	用户id                
use_cnt             	int                 	当日使用次数              
is_active           	tinyint             	是否活跃                
	 	 
# Partition Information	 	 
# col_name            	data_type           	comment             
	 	 
date_8              	int                 	日期                  
	 	 
# Detailed Table Information	 	 
Database:           	default             	 
Owner:              	root                	 
CreateTime:         	Thu Apr 25 11:01:56 CST 2019	 
LastAccessTime:     	UNKNOWN             	 
Protect Mode:       	None                	 
Retention:          	0                   	 
Location:           	hdfs://hadoop:9000/usr/hive/warehouse/t_od_use_cn 
Table Type:         	MANAGED_TABLE       	 
Table Parameters:	 	 
	transient_lastDdlTime	1556161316          
	 	 
# Storage Information	 	 
SerDe Library:      	org.apache.hadoop.hive.serde2.lazy.LazySimpleSerD 
InputFormat:        	org.apache.hadoop.mapred.TextInputFormat	 
OutputFormat:       	org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat	 
Compressed:         	No                  	 
Num Buckets:        	-1                  	 
Bucket Columns:     	[]                  	 
Sort Columns:       	[]                  	 
Storage Desc Params:	 	 
	field.delim         	,                   
	serialization.format	,                   
Time taken: 0.244 seconds, Fetched: 36 row(s)

[STORED AS file_format] :

这个关键字用于设定数据在Hive中的存储格式,一般不指定,直接使用默认,或照公司其他表的存储格式即可。

 

9. 查询既有表的建表语句

在公司中需要查询既有表的建表格式时使用以下语句即可:

show create table tablename;

查询第六步所建外部表的建表语句,运行效果如下:

hive> show create table t_od_use_cnt;
OK
CREATE TABLE `t_od_use_cnt`(
  `platform` string COMMENT 's� android,ios', 
  `app_version` string COMMENT 'appH,', 
  `user_id` bigint COMMENT '(7id', 
  `use_cnt` int COMMENT 'S.(!p', 
  `is_active` tinyint COMMENT '/&;�')
PARTITIONED BY ( 
  `date_8` int COMMENT '�')
ROW FORMAT DELIMITED 
  FIELDS TERMINATED BY ',' 
STORED AS INPUTFORMAT 
  'org.apache.hadoop.mapred.TextInputFormat' 
OUTPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION
  'hdfs://hadoop:9000/usr/hive/warehouse/t_od_use_cnt'
TBLPROPERTIES (
  'transient_lastDdlTime'='1556161316')

结果中文注释会显示乱码,这个问题需要重新编译jar包才能解决,在此就不提供解决办法了,有兴趣的同学自行百度即可,在工作里中文注释会有运维同学帮搞定~

可以看到其中有很多我们建表时并没有输入的语句,这些都是系统默认的设置,有兴趣的同学逐项百度,这里就不一一介绍了,因为工作中真的用不到~

 


能看到这里的同学,就右上角点个赞顺便关注我吧,3Q~

 

你可能感兴趣的:(Hive零基础从入门到实战 入门篇(七)HiveQL:表操作(上))