1. 通过 select 数据集创建表语法格式 ( 只能是内部表,不支持分区,分桶 )

create table table_name [stored as orc]
as
select ...

--如果通过select一个分区表中的数据创建表,则创建的新表的字段没有分区字段,只是把select的表的分区字段看成正常字段保存数据,因此新表不是分区表

2. 复制一个空表

--只复制表结构,不复制表数据
--如果复制的表是分区表,则新创建的表也是分区表,表结构统一
create table table_name like table_name;

3. 显示表列表

--显示所有表
show tables;
--最通用的写法
show tables like '*user*';
--显示函数
show functions like '*count*';
--以user开头的
show tables like 'user*';
--以other结尾的
show tables like '*other';

4. 删除表

drop table [if exists] table_name [purge];
--对于内部表来说,删除表的操作本质上是先删除表的元数据,然后再把表对应的HDFS上的数据放到回收站(hadoop fs -rm ),hadoop是配了回收站,加了purge相当于表对应在HDFS上的数据直接删除,不进回收站,且不能恢复,一般不用它。
--对于外部表来说,删除表操作只删除元数据,不会删除在HDFS上的存储数据,加purge也不会删除。

--回收站路径
/user/hadoop/.Trash/Current

5. 清除表

truncate table table_name [partition partition_spec];
--可以删除表和删除分区数据,和drop的区别是不删除元数据(表结构),只删除数据,外部表是不能truncate操作的。

6. 修改表名

--改表名
alter table table_name rename to new_table_name;
--说明:
内部表修改了表名后,表对应的存储文件地址也跟着改变,相当于做了HDFS的目录重命名
外部表不会改对应的location地址

7. 添加表分区

内部表添加表分区,自动创建目录。

外部表添加表分区,自动创建目录。

--创建分区表外部表
create external table ext_task(
word string,
num int
)partitioned by (taskname string)
row format delimited fields terminated by '\t'
location '/user/cz/ext_task';
--创建分区表内部表
create table inner_task(
word string,
num int
)partitioned by (taskname string)
row format delimited fields terminated by '\t';

--分区表外部表添加分区
alter table ext_task add if not exists partition(taskname='wordcount') location 'wordcount';
alter table ext_task add if not exists partition(taskname='maxword') location 'maxword';
alter table ext_task add if not exists partition(taskname='sortword') location 'sortword';
--分区表内部表添加分区
alter table inner_task add if not exists partition(taskname='wordcount') location 'wordcount';
alter table inner_task add if not exists partition(taskname='maxword') location 'maxword';
alter table inner_task add if not exists partition(taskname='sortword') location 'sortword';

8. 删除表分区

--删除表分区的语法
alter table table_name drop if exists partition partition_spec[,partition partition_spec,...]
--说明:
内部表删除分区,同时删除分区对应的目录
外部表删除分区不删除分区对应的目录

--内部表删除分区
alter table inner_task drop if exists partition(taskname='sortword');
--外部表删除分区
alter table ext_task drop if exists partition(taskname='sortword');

9. 修改分区路径

--修改表或分区路径的语法
alter table table_name [partition partition_spec] set location "new location";
--说明
内部表/外部表 修改分区路径,元数据修改,但hdfs目录没有创建,等导入数据时创建,或者自己主动创建
insert into table inner_task partition(taskname='wordcount') select word,num from word_avro;

10. 分区重命名

--分区重命名语法:
alter table table_name partition partition_spec rename to partition partition_spec;
--说明:
如果是内部表,分区重命名,分区对应的地址也会跟着改变,外部表不会。

--内部表分区重命名会改变分区对应的hdfs的目录
alter table inner_task partition (taskname='maxword') rename to partition (taskname='maxword01');
--外部表分区重命名不会改变分区对应的hdfs的目录
alter table ext_task partition (taskname='maxword') rename to partition
(taskname='maxword01');

11. 添加和修改字段

--增加表字段,使用新列集合替换现有数据列的语法
alter table table_name add | replace columns (col_name data_type [comment col_comment],...)
说明:
add columns 可以在表列的最后和分区字段前面增加字段
示例:
alter table ext_test add columns(test_col string);

--修改表字段
--语法:
alter table table_name change [column] col_old_name col_new_name column_type [comment col_comment] [first | after column_name]
--示例:
alter table ext_test_c change column test_col test_col_new string;

12. 数据加载

(1)load加载数据

向表中添加数据除了可以使用insert语法 (不推荐),还可以用hadoop fs -put的方式向表中添加数据。还有一种比较简单的用法就是可以直接通过load的方式加载数据。

DBeaver hive插入列数据 hive表添加字段sql_分区表

--load数据加载语法格式
load data [local] inpath 'filepath' [overwrite] into table tablename [partition(partcol1=val1, partcol2=val2 ...)]

说明:

(1)Hive的数据加载不会对本地数据文件做任何处理,只是将文件或目录中的所有文件拷贝到表定义的数据目录,分桶表使用load加载数据会生成mapreduce任务,将数据分到多个桶文件进行存放

(2)指定local 本地文件上传,如果没有指定local,则是从HDFS上传数据。

(3)文件加载Hive没有做严格校验,文件格式和压缩选项等匹配需要用户自己保证。

(4)分区表要指定具体加载数据分区

(5)如果指定overwrite会覆盖相应表数据或分区数据,相当于rm原有目录数据,然后上传新数据文件

示例一:将HDFS中的文件load到表中

示例二:将本地文件load到表中

-- 分区表外部表
create external table ext_task1(
word string,
num int
) partitioned by (taskname string)
row format delimited fields terminated by '\t'
location '/user/cz/ext_task1';

--创建分区wordcount1
alter table ext_task1 add if not exists partition(taskname='wordcount') location 'wordcount';
--再load数据到表分区wordcount中
--①将数据放到hdfs中
hadoop fs -put word /user/cz
hadoop fs -ls /user/cz|grep word
load data inpath '/user/cz/word' into table ext_task1 partition(taskname='wordcount');
--②linux本地上传
scp word hadoop@nn2:/home/hadoop
load data local inpath '/home/hadoop/word' into table ext_task1 partition (taskname='wordcount');

--使用overwrite,通过linux本地覆盖上传数据,之前的分区就失效了,以新的分区为主,即taskname=word
load data local inpath '/home/hadoop/word' overwrite into table ext_task1 partition(taskname='wordcount')
--因此推荐使用从hdfs方式导入数据

--上传数据的时候如果没有分区,这个分区会自动创建
load data local inpath '/home/hadoop/word' into table ext_task1 partition(taskname='wordcount01')

--Hive新特性,3.0会对load更新会生成一个mapreduce,以分桶的方式把数据分到六个文件中
--旧版本是没有办法通过load直接往分桶表中加载数据的
create table teacher(id int,name string) clustered by (name) into 6 buckets;
load data local inpath '/home/hadoop/teacher' into table teacher;

(2)select 加载数据到hive表

--通过select,将select数据覆盖表或分区的语法
insert overwrite table tablename1 [partition (partcol1=val1,partcol2=val2 ... )] [if not exists]] 
select_statement1 from from_statement;
--通过select,将select数据追加到表或分区的语法
insert into table tablename1 [partition (partcol=val1,partcol2=val2...)]
select_statement1 from from_statement;

--示例:
--添加分区
--alter table ext_task1 add if not exists partition(taskname='wordcount02') location 'wordcount02';
--加载数据
insert into table ext_task1 partition(taskname='wordcount02') select word,num from word_avro;

13. 动态分区

如果有这样一个需求,从一张不是分区表中查询数据导入到分区表中。如果分区的个数比较多的时候,就需要多次查询导入,比如:

--学生表
create table student(
id int,
name string,
age int
)
row format delimited fields terminated by '\t';
--学生表数据
1    name1    12
2    name2    12
3    name3    13
4    name4    13
5    name5    14
6    name6    14
7    name7    15
8    name8    15
load data local inpath '/home/hadoop/student' into table student;
--学生分区表
create table student_dyna(
id int,
name string
)partitioned by (age int)
row format delimited fields terminated by '\t';
--把学生表里的数据按照年龄导入到学生分区表里
--需要动态分区不用执行太多次
--1. 开启动态分区(hive默认是不开启的,因此正常是静态分区)
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
--2.直接一条insert创建四个分区
insert overwrite table student_dyna partition(age) select id,name,age from student;

Hive默认是静态分区,在插入数据的时候要手动设置分区,如果源数据量很大的时候,那么针对一个分区就要写一个insert,比如有很多日志数据,要按日期作为分区字段,在插入数据的时候手动去添加分区太麻烦。因此,hive提供了动态分区,动态分区简化了插入数据时的繁琐操作。

14. Hive表数据导出

查询表数据导出到某个文件( linux本地/hdfs )

--语法(只能用overwrite,不加local会将select数据写入到hdfs文件)
insert overwrite [local] directory directory1
[row format row_format] [stored as file_format] select ... from ...
--示例
--将select的数据写入到linux本地文件中,多层目录会自动创建
select * from ext_task1 where taskname='wordcount01';
insert overwrite local directory '/home/hadoop/hive_test/output1' row format delimited fields terminated by '|' stored as orc select * from ext_task1 where taskname='workcount01';
--注: 指定存储格式为orc,则指定的分隔符会失效,因为orc有自己的分隔符

15. Hive表多文件导出数据(普通表和分区表都可以)

--语法:
from from_statement
insert overwrite [local] directory directory1 row_format
select_statement1 where
insert overwrite [local] directory directory1 row_format
select_statement2 where 

--示例: 从ext_task1分区表查询不同分区中的数据,分别导入到不同的文件系统,一个是linux本地,一个是hdfs
from ext_task1
insert overwrite directory 'hdfs://ns1/user/cz/output_avro5' stored as orc
select word,num where taskname='wordcount01'
insert overwrite local directory '/home/hadoop/hive_test/output_avro4' stored as orc
select word,num where taskname='wordcount02';

说明:

(1)如果不指定文件存储格式,则导出到文件系统的数据都序列化成默认的textfile,普通字段会进行正常的读取,非原始类型字段(复杂字段map、array)会序列化成json,导出文件以^A(\001)分隔 \n结尾的文本数据。

(2)insert overwrite到hdfs目录,可以通过MR Job实现并行写入,这样在集群上抽取数据不仅速度块,而且还很方便。

(3)批量导入多个文件,需要导出文件的类型一致,如果一个是avro,一个是textfile,则会报错

16. Hive -e -f 参数使用

在单独执行hive脚本的时候,会启动hive的一个客户端,在hive客户端里边执行hql语句。但有时候不想打开hive的客户端执行,想在linux的bash环境下执行相关的一些hql语法,就需要通过hive -e或者hive -f这种方式执行

--本质上启动了hive客户端,然后执行多条sql语句,把结果放到文件中
hive -e "use yae; select * from ext_task1 where taskname='wordcount01'" > ext_task.out

--想在后台运行,正确结果放到output.log文件,标准错误输出放大err.log,&代表后台运行
nohup hive -e "use yae; select * from ext_task1 where taskname='wordcount01'" 1> output.log 2> err.log &
--查看后台,是否有程序在运行
jobs -l

--如果hql语句较多的情况下,在字符串中放不下或者看起来乱,就可以把它写入在文件中
vi hql.log
use yae;
select * from student where age=15;

hive -f hql.log >student.out
--本质相同,启动了hive客户端,然后执行文件中多条sql语句,将标准输出写入到student.out