-- 内部表转外部表 altertable t1 set tblproperties('EXTERNAL'='TRUE');-- 外部表转内部表。EXTERNAL 大写,false 不区分大小 altertable t1 set tblproperties('EXTERNAL'='FALSE');
1.5 分区表
-- 创建分区表createtableifnotexists t3(
id int,
name string ,
hobby array<string>,
addr map<String,string>)
partitioned by(dt string)row format delimited
fieldsterminatedby';'
collection items terminatedby','
map keysterminatedby':';-- 加载数据到分区表loaddatalocal inpath "/home/hadoop/data/t1.dat"intotable t3 partition(dt="2020-06-01");loaddatalocal inpath "/home/hadoop/data/t1.dat"intotable t3 partition(dt="2020-06-02");-- ### 备注:分区字段不是表中已经存在的数据,可以将分区字段看成伪列-- 查看分区show partitions t3;-- 增加一个分区,不加载数据 altertable t3 addpartition(dt='2020-06-03');-- 增加多个分区,不加载数据 altertable t3 addpartition(dt='2020-06-05')partition(dt='2020-06-06');-- 增加多个分区。准备数据
hdfs dfs -cp /user/hive/warehouse/mydb.db/t3/dt=2020-06-01/user/hive/warehouse/mydb.db/t3/dt=2020-06-07
hdfs dfs -cp /user/hive/warehouse/mydb.db/t3/dt=2020-06-01/user/hive/warehouse/mydb.db/t3/dt=2020-06-08-- 增加多个分区。加载数据 altertable t3 addpartition(dt='2020-06-07') location '/user/hive/warehouse/mydb.db/t3/dt=2020-06-07'partition(dt='2020-06-08') location '/user/hive/warehouse/mydb.db/t3/dt=2020-06-08';-- 查询数据 select*from t3;-- 修改分区的hdfs的路径altertable t3 partition(dt='2020-06-01')set location '/user/hive/warehouse/t3/dt=2020-06-03';-- 删除分区 可以删除一个或多个分区,用逗号隔开altertable t3 droppartition(dt='2020-06-03'),partition(dt='2020-06-04');
1.6 分桶表
-- Hive中:分桶字段.hashCode % 分桶个数-- 测试数据1 java 901 c 781 python 911 hadoop 802 java 752 c 762 python 802 hadoop 933 java 983 c 743 python 893 hadoop 915 java 936 c 767 python 878 hadoop 88-- 创建分桶表createtable course(
id int,
name string,
score int)clusteredby(id)into3 buckets
row format delimited
fieldsterminatedby"\t";-- 创建普通表 createtable course_common(
id int,
name string,
score int)row format delimited
fieldsterminatedby"\t";-- 普通表加载数据 loaddatalocal inpath '/home/hadoop/data/course.dat'intotable course_common;-- 通过 insert ... select ... 给桶表加载数据 insertintotable course select*from course_common;-- 查询分区表数据select*from course;-- 观察分桶数据。数据按照:(分区字段.hashCode) % (分桶数) 进行分区
1.7 修改表,删除表
-- 修改表名。rename altertable course_common renameto course_common1;-- 修改列名。change column altertable course_common1 change column id cid int;-- 修改字段类型。change columnaltertable course_common1 change column cid cid string;-- The following columns have types incompatible with the existing columns in their respective positions -- 修改字段数据类型时,要满足数据类型转换的要求。如int可以转为string,但是 string不能转为int-- 增加字段。add columnsaltertable course_common1 addcolumns(common string);-- 删除字段:replace columns -- 这里仅仅只是在元数据中删除了字段,并没有改动hdfs上的数据文件 altertable course_common1 replacecolumns( id string, cname string, score int);-- 删除表 droptable course_common1;
二、数据导入导出
2.1 数据导入
-- load装载## 基本语法:LOADDATA[LOCAL] INPATH 'filepath'[OVERWRITE]INTOTABLE tablename [PARTITION(partcol1=val1, partcol2=val2 ...)]### LOAD DATA LOCAL ... 从本地文件系统加载数据到Hive表中。本地文件会拷贝到Hive表指定的位置### LOAD DATA ... 从HDFS加载数据到Hive表中。HDFS文件移动到Hive表指定的位置### INPATH:加载数据的路径### OVERWRITE:覆盖表中已有数据;否则表示追加数据### PARTITION:将数据加载到指定的分区
2.2 数据插入
-- 插入数据insertintotable xx partition(dt='20211012')values(),(),(),...;-- 插入查询的结果数据insertintotable xx partition(dt='20211012')select id, name, area from xx where dt='20211011';-- 多表(多分区)插入模式 from tabC
insert overwrite table tabC partition(month='202003')select id, name, area wheremonth='202002'insert overwrite table tabC partition(month='202004')select id, name, area wheremonth='202002';-- 创建表并插入数据 根据查询结果创建表createtableifnotexists tabD asselect*from tabC;-- import导入数据importtable student2 partition(month='201709')from'/user/hive/warehouse/export/student';
2.3 数据导出
-- 将查询结果导出到本地 insert overwrite local directory '/home/hadoop/data/tabC'select*from tabC;-- 将查询结果格式化输出到本地 insert overwrite local directory '/home/hadoop/data/tabC2'row format delimited fieldsterminatedby' 'select*from tabC;-- 将查询结果导出到HDFS insert overwrite directory '/user/hadoop/data/tabC3'row format delimited fieldsterminatedby' 'select*from tabC;-- dfs 命令导出数据到本地。本质是执行数据文件的拷贝
dfs -get /user/hive/warehouse/mydb.db/tabc/month=202001/home/hadoop/data/tabC4
-- hive 命令导出数据到本地。执行查询将查询结果重定向到文件
hive -e "select * from tabC"> a.log
-- export 导出数据到HDFS。使用export导出数据时,不仅有数还有表的元数据信息
export table tabC to'/user/hadoop/data/tabC4';-- export 导出的数据,可以使用 import 命令导入到 Hive 表中 -- 使用 like tname创建的表结构与原表一致。create ... as select ... 结构可能不一致 createtable tabE like tabc;importtable tabE from''/user/hadoop/data/tabC4';-- 截断表,清空数据。(注意:仅能操作内部表) 外部表不能执行 truncate 操作truncatetable tabE;
三、DQL - 排序
3.1 每个MR内部排序 [sort by]
-- 对于大规模数据而言order by效率低;-- 在很多业务场景,我们并不需要全局有序的数据,此时可以使用sort by;-- sort by为每个reduce产生一个排序文件,在reduce内部进行排序,得到局部有序的结果;sort by的数据只能保证在同一个reduce中的数据可以按指定字段排序;-- 设置reduce个数 set mapreduce.job.reduces=2;-- 按照工资降序查看员工信息 select*from emp sort by sal desc;-- 将查询结果导入到文件中(按照工资降序)。生成两个输出文件,每个文件内部数据 按工资降序排列 insert overwrite local directory '/home/hadoop/output/sortsal'select*from emp sort by sal desc;
3.2 分区排序 [distribute by]
-- distribute by 将特定的行发送到特定的reducer中,便于后继的聚合与排序操作;-- distribute by 类似于MR中的分区操作,可以结合sort by操作,使分区数据有序;-- distribute by 要写在sort by之前;-- 启动2个reducer task;先按 deptno 分区,在分区内按 sal+comm 排序 set mapreduce.job.reduces=2;-- 将结果输出到文件,观察输出结果 insert overwrite local directory '/home/hadoop/output/distBy'select empno, ename, job, deptno, sal + nvl(comm,0) salcomm
from emp distribute by deptno sort by salcomm desc;-- 上例中,数据被分到了统一区,看不出分区的结果-- 将数据分到3个区中,每个分区都有数据set mapreduce.job.reduces=3;insert overwrite local directory '/home/hadoop/output/distBy1'select empno, ename, job, deptno, sal + nvl(comm,0) salcomm
from emp distribute by deptno sort by salcomm desc;
3.3 cluster by
-- 当distribute by 与 sort by是同一个字段时,可使用cluster by简化语法;-- 语法上是等价的 select*from emp distribute by deptno sort by deptno;select*from emp cluster by deptno;
四、函数*
4.1 查看系统内置函数
-- 查看系统自带函数 show functions;-- 显示自带函数的用法 descfunction upper;descfunctionextended upper;
-- if (boolean testCondition, T valueTrue, T valueFalseOrNull) select sal,if(sal<1500,1,if(sal <3000,2,3))from emp;=>if(sal <1500)then1elseif sal <3000then2else3-- CASE WHEN a THEN b [WHEN c THEN d]* [ELSE e] ENDselect sal,casewhen sal<=1500then1when sal<=3000then2else3end sallevel
from emp;-- 下面两个等价:select ename, deptno,case deptno when10then'accounting'when20then'research'when30then'sales'else'unknown'end deptname
from emp;select ename, deptno,casewhen deptno=10then'accounting'when deptno=20then'research'when deptno=30then'sales'else'unknown'end deptname
from emp;
-- explode 炸裂函数 就是将一行中复杂的 array 或者 map 结构拆分成多行select explode(array('A','B','C'))as col;
col
A
B
C
select explode(map('a',8,'b',88,'c',888));keyvalue
a 8
b 88
c 888-- lateral view用于和split、explode等UDTF一起使用的,-- 能将一行数据拆分成多行数据,在此基础上可以对拆分的数据进行聚合,-- lateral view首先为原始表的每行调用UDTF,UDTF会把一行拆分成一行或者多行,-- lateral view再把结果组合,产生一个支持别名表的虚拟表。-- lateral view的基本使用:with t1 as(select'OK' cola, split('www.lagou.com','\\.') colb )select cola, colc from t1 lateral view explode(colb) t2 as colc;
cola colc
OK www
OK lagou
OK com
-- UDTF函数的用例: -- 用例1:11,2,322,331,2==》
11121322233132-- sql:select uid, tag from t1lateral view explode(split(tags,",")) t2 as tag;-- 用例2:
lisi|Chinese:90,Math:80,English:70
wangwu|Chinese:88,Math:90,English:96
maliu|Chinese:99,Math:65,English:60-- 创建表 createtable studscore(
name string ,
score map<String,string>)row format delimited
fieldsterminatedby'|'
collection items terminatedby','
map keysterminatedby':';-- 需求:找到每个学员的最好成绩 -- 第一步,使用 explode 函数将map结构拆分为多行 select explode(score)as(subject, socre)from studscore;-- 但是这里缺少了学员姓名,加上学员姓名后出错。下面的语句有是错的 select name, explode(score)as(subject, socre)from studscore;-- 第二步:explode常与 lateral view 函数联用,这两个函数结合在一起能关 联其他字段 select name, subject, score1 as score
from studscore lateral view explode(score) t1 as subject, score1;-- 第三步:找到每个学员的最好成绩 select name,max(mark) maxscore
from(select name, subject, mark
from studscore lateral view explode(score) t1 as subject, mark
) t1
groupby name;with tmp as(select name, subject, mark
from studscore
lateral view explode(score) t1 as subject, mark
)select name,max(mark) maxscore from tmp groupby name;
-- 在over窗口中进行分区,对某一列进行分区统计,窗口的大小就是分区的大小;-- 查询员工姓名、薪水、部门薪水总和 select ename, sal,sum(sal)over(partitionby deptno) salsum from emp;
4.7.3 order by 子句
-- order by 子句对输入的数据进行排序-- 增加了order by子句;sum:从分组的第一行到当前行求和 select ename, sal, deptno,sum(sal)over(partitionby deptno orderby sal) salsum
from emp;
4.7.4 Window 子句
rowsbetween...and...-- 对窗口的结果做更细粒度的划分,使用window子句,有如下的几个选项:-- unbounded preceding。组内第一行数据-- n preceding。组内当前行的前n行数据-- current row。当前行数据-- n following。组内当前行的后n行数据-- unbounded following。组内最后一行数据