创建数据库
create database if not exists myhive ;
创建数据库如果不存在myhive;
创建数据库并且指定存储位置
create database myhive3 location ‘/myhive3’;
创建数据库myhive3 本地 ‘/myhive3’;
修改数据库
可以修改一些数据库属性,但是数据库的元数据信息不可以改变,包括数据库的名称和数据库所在的位置。
alter database myhive3 set dbproperties(‘createtime’=‘20190501’);
修改数据库myhive3 设置 数据库属性(‘创建时间’=‘20190501’);
查看数据库详细信息
desc database myhive3;
查看数据库myhive3;
desc database extended myhive3;
查看数据库拓展myhive3;(查看拓展信息,可以清楚地看到附加属性。)
删除数据库操作
drop database myhive3;
删除数据库myhive3;(注意:如果数据库下面有表的话,会报错)
drop database myhive3 cascade;
删除数据库,hyhive3 级联(注意:这样强制删除了数据库和数据表,准备跑路)
内部表&外部表
未被external修饰的是内部表(managed table),被external修饰的为外部表(external table);
区别:
内部表数据由Hive自身管理,外部表数据由HDFS管理;
内部表数据存储的位置是hive.metastore.warehouse.dir(默认:/user/hive/warehouse),外部表数据的存储位置由自己制定;
删除内部表会直接删除元数据(metadata)及存储数据;删除外部表仅仅会删除元数据,HDFS上的文件并不会被删除;
对内部表的修改会将修改直接同步给元数据,而对外部表的表结构和分区进行修改,则需要修复(MSCK REPAIR TABLE table_name;)
创建数据表
1,use hive;
使用hive数据库;
2,create table stu(id int,name string);
创建数据表stu(名字 类型);
3,insert into stu values(1,“zhangsan”);
插入stu的属性(id,name);
4,select*from stu;
选择全部来自stu;
关于字段类型
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Types
创建表并指定字段之间的分隔符
create table stu2(id int,name string) row format delimited fields deminated by ‘\t’ stored as textfile location ‘/user/stu2’;
创建表stu2(名字 类型)行格式以\t分割字段结束 储存为文本文件到本地。。。
根据查询结果创建表
create table stu3 as select*from stu2;
创建表对于stu2的结果
根据已存在的表结构创建表
create table stu4 like stu2;
查询表的类型
desc formatted stu2;
查询格式(类型)stu2
创建表
create external table techer(id string, name string ) row format delimited fields teminated by ‘\t’;
external:外部
从本地文件系统向表中加载数据
load data local inpath‘/export/servers/hivedatas/student.csv’ into table techer;
加载数据本地地址。。。到表techer;
加载数据并覆盖已有数据
load data local inpath ‘…’ overwrite into table techer;
如果删掉student表,hdfs的数据仍然存在,并且重新创建表之后,表中就直接存在数据了,因为我们的student表使用的是外部表,drop table之后,表当中的数据依然保留在hdfs上面了
在大数据中,最常用的一种思想就是分治,我们可以把大的文件切割划分成一个个的小的文件,这样每次操作一个小的文件就会很容易了,同样的道理,在hive当中也是支持这种思想的,就是我们可以把大的数据,按照每天,或者每小时进行切分成一个个的小的文件,这样去操作小的文件就会容易得多了
创建分区表的语法
create table score4(s_id string ,c_id string,score_id int) partitioned by (month string ) row format delimited fields terminated by ’ \t ’ ;
创建一个表带多个分区
create table score5(s_id string ,c_id string,score_id int) partitioned by(year string,month string,day string ) row format delimited
fields terminated by ‘\t’ ;
加载数据到分区表中
load data local inpath ‘/export/servers/hivedatas/score.csv’ into table score4 partition(month=‘201905’);
加载数据到一个多分区表中
load data local inpath ‘/export/servers/hivedatas/score.csv’ into table score5 partition (year=‘2019’,month=‘05’,day=‘02’);
多分区联合查询 使用union all 实现
selectfrom score4 where month=‘201905’ union all selectfrom score4 where month=‘201905’ ;
查看分区
show patitions score4;
添加一个分区
alter table score4 add patition(month=‘201805’);
同时添加多个分区
alter table score4 add patition(month=‘201904’) partition(month=‘201603’);
删除分区
alter table score4 drop partition(month=‘201904’);
hive表中加载数据
直接向分区表中插入数据
create table score3 like score;
insert into table score3 partition(month =‘201807’) values (‘001’,‘002’,‘100’);
通过查询插入数据
通过load方式加载数据
load data local inpath ‘/export/servers/hivedatas/score.csv’ overwrite into table score partition(month=‘201806’);
通过查询方式加载数据
create table score4 like score;
insert overwrite table score4 partition(month = ‘201806’) select s_id,c_id,s_score from score;
多插入模式
常用于实际生产环境当中,将一张表拆开成两部分或者多部分
给score表加载数据
load data local inpath ‘/export/servers/hivedatas/score.csv’ overwrite into table score partition(month=‘201806’);
创建第一部分表:
create table score_first( s_id string,c_id string) partitioned by (month string) row format delimited fields terminated by ‘\t’ ;
创建第二部分表:
create table score_second(c_id string,s_score int) partitioned by (month string) row format delimited fields terminated by ‘\t’;
分别给第一部分与第二部分表加载数据
from score insert overwrite table score_first partition(month=‘201806’) select s_id,c_id insert overwrite table score_second partition(month = ‘201806’) select c_id,s_score;
查询语句中创建表并加载数据(as select)
将查询的结果保存到一张表当中去
create table score5 as select * from score;
创建表时通过location指定加载数据路径
1) 创建表,并指定在hdfs上的位置
create external table score6 (s_id string,c_id string,s_score int) row format delimited fields terminated by ‘\t’ location ‘/myscore6’;
2)上传数据到hdfs上
hdfs dfs -mkdir -p /myscore6
hdfs dfs -put score.csv /myscore6;
3)查询数据
select * from score6;
export导出与import 导入 hive表数据(内部表操作)
create table techer2 like techer;
export table techer to ‘/export/techer’;
import table techer2 from ‘/export/techer’;
hive表中的数据导出(了解)
将hive表中的数据导出到其他任意目录,例如linux本地磁盘,例如hdfs,例如mysql等等
insert导出
1) 将查询的结果导出到本地
insert overwrite local directory ‘/export/servers/exporthive’ select * from score;
2) 将查询的结果格式化导出到本地
insert overwrite local directory ‘/export/servers/exporthive’ row format delimited fields terminated by ‘\t’ collection items terminated by ‘#’ select * from student;
3) 将查询的结果导出到HDFS上(没有local)
insert overwrite directory ‘/export/servers/exporthive’ row format delimited fields terminated by ‘\t’ collection items terminated by ‘#’ select * from score;
Hadoop命令导出到本地
dfs -get /export/servers/exporthive/000000_0 /export/servers/exporthive/local.txt;
hive shell 命令导出
基本语法:(hive -f/-e 执行语句或者脚本 > file)
bin/hive -e “select * from myhive.score;” > /export/servers/exporthive/score.txt
export导出到HDFS上
export table score to ‘/export/exporthive/score’;
sqoop导出
后续单独讲。
清空表数据
只能清空管理表,也就是内部表
truncate table score6;
清空这个表会报错
3.2、 hive查询语法
3.2.1、SELECT
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Select
基本的Select操作
语法结构
SELECT [ALL | DISTINCT] select_expr, select_expr, …
FROM table_reference
[WHERE where_condition]
[GROUP BY col_list [HAVING condition]]
[CLUSTER BY col_list
| [DISTRIBUTE BY col_list] [SORT BY| ORDER BY col_list]
]
[LIMIT number]
注:1、order by 会对输入做全局排序,因此只有一个reducer,会导致当输入规模较大时,需要较长的计算时间。
2、sort by不是全局排序,其在数据进入reducer前完成排序。因此,如果用sort by进行排序,并且设置mapred.reduce.tasks>1,则sort by只保证每个reducer的输出有序,不保证全局有序。
3、distribute by(字段)根据指定的字段将数据分到不同的reducer,且分发算法是hash散列。
4、Cluster by(字段) 除了具有Distribute by的功能外,还会对该字段进行排序。
因此,如果分桶和sort字段是同一个时,此时,cluster by = distribute by + sort by
分桶表的作用:最大的作用是用来提高join操作的效率;
(思考这个问题:
select a.id,a.name,b.addr from a join b on a.id = b.id;
如果a表和b表已经是分桶表,而且分桶的字段是id字段
做这个join操作时,还需要全表做笛卡尔积吗?)
全表查询
select * from score;
选择特定列查询
select s_id ,c_id from score;
列别名
1)重命名一个列。
2)便于计算。
3)紧跟列名,也可以在列名和别名之间加入关键字‘AS’
select s_id as myid ,c_id from score;
3.2.2、常用函数
1)求总行数(count)
select count(1) from score;
2)求分数的最大值(max)
select max(s_score) from score;
3)求分数的最小值(min)
select min(s_score) from score;
4)求分数的总和(sum)
select sum(s_score) from score;
5)求分数的平均值(avg)
select avg(s_score) from score;
3.2.3、LIMIT语句
典型的查询会返回多行数据。LIMIT子句用于限制返回的行数。
select * from score limit 3;
3.2.4、WHERE语句
1)使用WHERE 子句,将不满足条件的行过滤掉。
2)WHERE 子句紧随 FROM 子句。
3)案例实操
查询出分数大于60的数据
select * from score where s_score > 60;
3.2.5、比较运算符(BETWEEN/IN/ IS NULL)
1)下面表中描述了谓词操作符,这些操作符同样可以用于JOIN…ON和HAVING语句中。
操作符 支持的数据类型 描述
A=B 基本数据类型 如果A等于B则返回TRUE,反之返回FALSE
A<=>B 基本数据类型 如果A和B都为NULL,则返回TRUE,其他的和等号(=)操作符的结果一致,如果任一为NULL则结果为NULL
A<>B, A!=B 基本数据类型 A或者B为NULL则返回NULL;如果A不等于B,则返回TRUE,反之返回FALSE
A A<=B 基本数据类型 A或者B为NULL,则返回NULL;如果A小于等于B,则返回TRUE,反之返回FALSE
A>B 基本数据类型 A或者B为NULL,则返回NULL;如果A大于B,则返回TRUE,反之返回FALSE
A>=B 基本数据类型 A或者B为NULL,则返回NULL;如果A大于等于B,则返回TRUE,反之返回FALSE
A [NOT] BETWEEN B AND C 基本数据类型 如果A,B或者C任一为NULL,则结果为NULL。如果A的值大于等于B而且小于或等于C,则结果为TRUE,反之为FALSE。如果使用NOT关键字则可达到相反的效果。
A IS NULL 所有数据类型 如果A等于NULL,则返回TRUE,反之返回FALSE
A IS NOT NULL 所有数据类型 如果A不等于NULL,则返回TRUE,反之返回FALSE
IN(数值1, 数值2) 所有数据类型 使用 IN运算显示列表中的值
A [NOT] LIKE B STRING 类型 B是一个SQL下的简单正则表达式,如果A与其匹配的话,则返回TRUE;反之返回FALSE。B的表达式说明如下:‘x%’表示A必须以字母‘x’开头,‘%x’表示A必须以字母’x’结尾,而‘%x%’表示A包含有字母’x’,可以位于开头,结尾或者字符串中间。如果使用NOT关键字则可达到相反的效果。
A RLIKE B, A REGEXP B STRING 类型 B是一个正则表达式,如果A与其匹配,则返回TRUE;反之返回FALSE。匹配使用的是JDK中的正则表达式接口实现的,因为正则也依据其中的规则。例如,正则表达式必须和整个字符串A相匹配,而不是只需与其字符串匹配。
2)案例实操
(1)查询分数等于80的所有的数据
select * from score where s_score = 80;
(2)查询分数在80到100的所有数据
select * from score where s_score between 80 and 100;
(3)查询成绩为空的所有数据
select * from score where s_score is null;
(4)查询成绩是80和90的数据
select * from score where s_score in(80,90);
3.2.6、LIKE和RLIKE
1)使用LIKE运算选择类似的值
2)选择条件可以包含字符或数字:
% 代表零个或多个字符(任意个字符)。
_ 代表一个字符。
3)RLIKE子句是Hive中这个功能的一个扩展,其可以通过Java的正则表达式这个更强大的语言来指定匹配条件。
4)案例实操
(1)查找以8开头的所有成绩
select * from score where s_score like ‘8%’;
(2)查找第二个数值为9的所有成绩数据
select * from score where s_score like ‘_9%’;
(3)查找成绩中含9的所有成绩数据
select * from score where s_score rlike ‘[9]’;
逻辑运算符(AND/OR/NOT)
操作符 含义
AND 逻辑并
OR 逻辑或
NOT 逻辑否
案例实操
(1)查询成绩大于80,并且s_id是01的数据
select * from score where s_score >80 and s_id = ‘01’;
(2)查询成绩大于80,或者s_id 是01的数
select * from score where s_score > 80 or s_id = ‘01’;
(3)查询s_id 不是 01和02的学生
select * from score where s_id not in (‘01’,‘02’);
3.2.7、分组
GROUP BY语句
GROUP BY语句通常会和聚合函数一起使用,按照一个或者多个列队结果进行分组,然后对每个组执行聚合操作。
案例实操:
(1)计算每个学生的平均分数
select s_id ,avg(s_score) from score group by s_id;
(2)计算每个学生最高成绩
select s_id ,max(s_score) from score group by s_id;
HAVING语句
1)having与where不同点
(1)where针对表中的列发挥作用,查询数据;having针对查询结果中的列发挥作用,筛选数据。
(2)where后面不能写分组函数,而having后面可以使用分组函数。
(3)having只用于group by分组统计语句。
2)案例实操:
求每个学生的平均分数
select s_id ,avg(s_score) from score group by s_id;
求每个学生平均分数大于85的人
select s_id ,avg(s_score) avgscore from score group by s_id having avgscore > 85;
3.2.8、JOIN语句
3.2.8.1、等值JOIN
Hive支持通常的SQL JOIN语句,但是只支持等值连接,不支持非等值连接。
案例操作
(1) 查询分数对应的姓名
SELECT s.s_id,s.s_score,stu.s_name,stu.s_birth FROM score s LEFT JOIN student stu ON s.s_id = stu.s_id
3.2.8.2、表的别名
1)好处
(1)使用别名可以简化查询。
(2)使用表名前缀可以提高执行效率。
2)案例实操
合并老师与课程表
select * from techer t join course c on t.t_id = c.t_id;
3.2.8.3、内连接(INNER JOIN)
内连接:只有进行连接的两个表中都存在与连接条件相匹配的数据才会被保留下来。
select * from techer t inner join course c on t.t_id = c.t_id;
3.2.8.4、左外连接(LEFT OUTER JOIN)
左外连接:JOIN操作符左边表中符合WHERE子句的所有记录将会被返回。
查询老师对应的课程
select * from techer t left join course c on t.t_id = c.t_id;
3.2.8.5、右外连接(RIGHT OUTER JOIN)
右外连接:JOIN操作符右边表中符合WHERE子句的所有记录将会被返回。
select * from techer t right join course c on t.t_id = c.t_id;
3.2.8.6、满外连接(FULL OUTER JOIN)
满外连接:将会返回所有表中符合WHERE语句条件的所有记录。如果任一表的指定字段没有符合条件的值的话,那么就使用NULL值替代。
SELECT * FROM techer t FULL JOIN course c ON t.t_id = c.t_id ;
3.2.8.7、多表连接
注意:连接 n个表,至少需要n-1个连接条件。例如:连接三个表,至少需要两个连接条件。
多表连接查询,查询老师对应的课程,以及对应的分数,对应的学生
select * from techer t
left join course c
on t.t_id = c.t_id
left join score s
on s.c_id = c.c_id
left join student stu
on s.s_id = stu.s_id;
大多数情况下,Hive会对每对JOIN连接对象启动一个MapReduce任务。本例中会首先启动一个MapReduce job对表techer和表course进行连接操作,然后会再启动一个MapReduce job将第一个MapReduce job的输出和表score;进行连接操作。
3.2.9、 排序
3.2.9.1 全局排序(Order By)
Order By:全局排序,一个reduce
1)使用 ORDER BY 子句排序
ASC(ascend): 升序(默认)
DESC(descend): 降序
2)ORDER BY 子句在SELECT语句的结尾。
3)案例实操
(1)查询学生的成绩,并按照分数降序排列
SELECT * FROM student s LEFT JOIN score sco ON s.s_id = sco.s_id ORDER BY sco.s_score DESC;
(2)查询学生的成绩,并按照分数升序排列
SELECT * FROM student s LEFT JOIN score sco ON s.s_id = sco.s_id ORDER BY sco.s_score asc;
3.2.9.2 按照别名排序
按照分数的平均值排序
select s_id ,avg(s_score) avg from score group by s_id order by avg;
3.2.9.3 多个列排序
按照学生id和平均成绩进行排序
select s_id ,avg(s_score) avg from score group by s_id order by s_id,avg;
3.2.9.4 每个MapReduce内部排序(Sort By)局部排序
Sort By:每个MapReduce内部进行排序,对全局结果集来说不是排序。
1)设置reduce个数
set mapreduce.job.reduces=3;
2)查看设置reduce个数
set mapreduce.job.reduces;
3)查询成绩按照成绩降序排列
select * from score sort by s_score;
4) 将查询结果导入到文件中(按照成绩降序排列)
insert overwrite local directory ‘/export/servers/hivedatas/sort’ select * from score sort by s_score;
3.2.9.5 分区排序(DISTRIBUTE BY)
Distribute By:类似MR中partition,进行分区,结合sort by使用。
注意,Hive要求DISTRIBUTE BY语句要写在SORT BY语句之前。
对于distribute by进行测试,一定要分配多reduce进行处理,否则无法看到distribute by的效果。
案例实操:
(1) 先按照学生id进行分区,再按照学生成绩进行排序。
设置reduce的个数,将我们对应的s_id划分到对应的reduce当中去
set mapreduce.job.reduces=7;
通过distribute by 进行数据的分区
insert overwrite local directory ‘/export/servers/hivedatas/sort’ select * from score distribute by s_id sort by s_score;
3.2.9.6 CLUSTER BY
当distribute by和sort by字段相同时,可以使用cluster by方式。
cluster by除了具有distribute by的功能外还兼具sort by的功能。但是排序只能是倒序排序,不能指定排序规则为ASC或者DESC。
1) 以下两种写法等价
select * from score cluster by s_id;
select * from score distribute by s_id sort by s_id;