赞
踩
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的方式加载数据。
- --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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。