您的位置:首页 > 博客中心 > 互联网 >

关于hive核心

时间:2022-05-11 13:04

一、DDL数据定义

1、创建数据库

1)创建一个数据库,数据库在 HDFS 上的默认存储路径是/user/hive/warehouse/*.db。

hive (default)> create database db_hive;

2)避免要创建的数据库已经存在错误,增加 if not exists 判断。(标准写法)

hive (default)> create database db_hive;

FAILED:  Execution   Error,   return   code  1 from org.apache.hadoop.hive.ql.exec.DDLTask. Database db_hive already exists

hive (default)> create database if not exists db_hive;

3)创建一个数据库,指定数据库在 HDFS 上存放的位置

hive (default)> create database db_hive2 location ‘/db_hive2.db‘;

2、查询数据库

显示数据库

1.显示数据库

hive> show databases;

2.过滤显示查询的数据库

hive> show databases like ‘db_hive*‘; 

OK 
db_hive 
db_hive_1
查看数据库详情

1.显示数据库信息

hive> desc database db_hive; 
OK 
db_hive		hdfs://master:8020/usr/hive/warehouse/db_hive.db	root	USER

2.显示数据库详细信息,extended

hive> desc database extended db_hive; 
OK
db_hive		hdfs://master:8020/usr/hive/warehouse/db_hive.db	root	USER
切换当前数据库
hive (default)> use db_hive;

3、修改数据库

用户可以使用 ALTER DATABASE 命令为某个数据库的 DBPROPERTIES 设置键-值对属性值,来描述这个数据库的属性信息。

数据库的其他元数据信息都是不可更改的,包括数据库名和数据库所在的目录位置。

hive (default)>alter hive set database dbproperties(‘createtime‘=‘20200830‘);

在 hive 中查看修改结果

hive> desc database extended db_hive;

db_name comment location owner_name owner_type parameters 
db_hive hdfs://hadoop102:8020/user/hive/warehouse/db_hive.db chaosUSER {createtime=20200830}

4、删除数据库

1.删除空数据库

hive>drop database db_hive2;

2.如果删除的数据库不存在,最好采用 if exists 判断数据库是否存在

hive> drop database db_hive;

FAILED: SemanticException [Error 10072]: Database does not exist: db_hive

hive> drop database if exists db_hive2;

3.如果数据库不为空,可以采用 cascade 命令,强制删除

hive> drop database db_hive;

FAILED: Execution   Error,   return   code  1 from org.apache.hadoop.hive.ql.exec.DDLTask.

InvalidOperationException(message:Database db_hive is not empty. One or more tables exist.) hive> drop database db_hive cascade;

5、创建表

1)建表语句
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name

  [(col_name data_type [COMMENT col_comment], ...)]

  [COMMENT table_comment]

  [PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)]

  [CLUSTERED BY (col_name, col_name, ...)

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

  [ROW FORMAT row_format]

  [STORED AS file_format]

  [LOCATION hdfs_path]
2)字段解释
?CREATE TABLE 创建一个指定名字的表。如果相同名字的表已经存在,则抛出异常;用户可以用 IF NOT EXIST 选项来忽略这个异常
?EXTERNAL 关键字可以让用户创建一个外部表,在建表的同时指定一个指向实际数据的路径(LOCATION),Hive 创建内部表时,会将数据移动到hadfs指向的路径;若创建外部表,仅记录数据所在的路径,不对数据的位置做任何改变。在删除表的时候,内部表的元数据和数据会被一起删除,而外部表只删除元数据,不删除数据。
?LIKE 允许用户复制现有的表结构,但是不复制数据
?COMMENT可以为表与字段增加注释描述
?PARTITIONED BY  创建分区表,指定分区
?ROW FORMAT 
  DELIMITED [FIELDS TERMINATED BY char] [COLLECTION ITEMS TERMINATED BY char] 
    MAP KEYS TERMINATED BY char] [LINES TERMINATED BY char] 
    | SERDE serde_name [WITH SERDEPROPERTIES 
    (property_name=property_value, property_name=property_value, ...)] 
  用户在建表的时候可以自定义 SerDe 或者使用自带的 SerDe。如果没有指定 ROW FORMAT 或者 ROW FORMAT DELIMITED,将会使用自带的 SerDe。在建表的时候,
用户还需要为表指定列,用户在指定表的列的同时也会指定自定义的 SerDe,Hive 通过 SerDe 确定表的具体的列的数据。 
?STORED AS 
  SEQUENCEFILE //序列化文件
  | TEXTFILE //普通的文本文件格式
  | RCFILE  //行列存储相结合的文件
  | INPUTFORMAT input_format_classname OUTPUTFORMAT output_format_classname //自定义文件格式
  如果文件数据是纯文本,可以使用 STORED AS TEXTFILE。如果数据需要压缩,使用 STORED AS SEQUENCE 。
?LOCATION指定表在HDFS的存储路径

6、修改表

重命名表
ALTER TABLE table_name RENAME TO new_table_name
增加/修改/替换列信息

更新列

ALTER TABLE table_name CHANGE [COLUMN] col_old_name col_new_name column_type [COMMENT col_comment] [FIRST|AFTER column_name]

增加和替换列

ALTER TABLE table_name ADD|REPLACE COLUMNS (col_name data_type [COMMENT col_comment], ...) 

注:ADD 是代表新增一字段,字段位置在所有列后面(partition 列前),REPLACE 则是表示替换表中所有字段。

简单示例

(1)查询表结构

hive> desc dept_partition;

(2)添加列

hive (default)> alter table dept_partition add columns(deptdesc string);

(3)更新列

hive (default)> alter table dept_partition change column deptdesc desc int;

(4)替换列

hive (default)> alter table dept_partition replace columns(deptno string, dname string, loc string);

注:hive不支持删除字段

7、删除表

注意:内部表和外部表删除的区别

 drop table dept_name;

8、实例

1)关于内部表与外部表

建表语句

创建部门表

create external table if not exists default.dept( deptno int, dname string, loc int )

row format delimited fields terminated by ‘\t‘;

创建员工表

create external table if not exists default.emp( empno int, ename string, job string, mgr int, hiredate string, sal double, comm double, deptno int)
row format delimited fields terminated by ‘\t‘;

查看创建的表

hive (default)> show tables; 
OK 
tab_name 
dept 
emp

向外部表中导入数据导入数据

hive (default)>load data inpath local ‘/opt/module/data/dept.txt‘ into table default.dept;
hive (default)>load data local inpath‘/opt/module/data/emp.txt‘ into table default.emp;

查询结果

hive (default)> select * from emp;
hive (default)> select * from dept;

查看表格式化数据

hive (default)> desc formatted dept;

Table Type: EXTERNAL_TABLE
管理表与外部表的互相转换

(1)查询表的类型

hive (default)> desc formatted student2;

 Table Type: MANAGED_TABLE

(2)修改内部表 student2 为外部表

alter table student2 set tblproperties(‘EXTERNAL‘=‘TRUE‘);

(3)查询表的类型

hive (default)> desc formatted student2;

 Table Type: EXTERNAL_TABLE

(4)修改外部表 student2 为内部表

alter table student2 set tblproperties(‘EXTERNAL‘=‘FALSE‘);

(5)查询表的类型

hive (default)> desc formatted student2;

 Table Type: MANAGED_TABLE

注意:(‘EXTERNAL‘=‘TRUE‘)和(‘EXTERNAL‘=‘FALSE‘)为固定写法,区分大小写!

2)关于基础分区表

1.引入分区表(需要根据日期对日志进行管理)

/user/hive/warehouse/log_partition/20200702/20200702.log

/user/hive/warehouse/log_partition/20200703/20200703.log

/user/hive/warehouse/log_partition/20200704/20200704.log

2.创建分区表语法

create table dept_partition( deptno int, dname string, loc string) partitioned by (month string)
row format delimited fields terminated by ‘\t‘;

3.加载数据到分区表中

hive (default)>load data local inpath ‘/opt/module/datas/dept.txt‘ into table default.dept_partition partition(month=‘202009‘);

hive (default)>load data local inpath ‘/opt/module/datas/dept.txt‘ into table default.dept_partition partition(month=‘202008‘);

hive (default)>load data local inpath ‘/opt/module/datas/dept.txt‘ into table default.dept_partition partition(month=‘202007’);

4.查询分区表中数据

单分区查询

hive (default)> select * from dept_partition where month=‘202009‘;

多分区联合查询

hive (default)> select * from dept_partition where month=‘202009‘ union all select * from dept_partition where month=‘202008‘ union select * from dept_partition where month=‘202007‘;、
简单写法
hive (default)> select * from dept_partition where month>=‘202007‘and month<=‘202009‘ 

5.增加分区

创建单个分区

hive (default)> alter table dept_partition add partition(month=‘202006‘) ;

同时创建多个分区

hive (default)> alter table dept_partition add partition(month=‘202005‘) partition(month=‘202004‘);

6.删除分区

删除单个分区

hive (default)> alter table dept_partition drop partition (month=‘202004‘);

同时删除多个分区

hive (default)> alter table dept_partition drop partition (month=‘202005‘), partition (month=‘202006‘);
简单写法
hive (default)> alter table dept_partition drop partition (month>=‘202005‘,month<=‘202006‘);

7.查看分区表有多少分区

hive> show partitions dept_partition;

8.查看分区表结构

hive> desc formatted dept_partition;
3)关于多级分区表

hive中的多级分区表,可以理解为多级目录,按照分区字段顺序将原本数据划分为多级目录

1.创建二级分区表

hive (default)> create table dept_partition2(deptno int, dname string, loc string)
partitioned by (month string, day string) 
row format delimited fields terminated by ‘\t‘;

2.正常的加载数据

(1)加载数据到二级分区表中

hive (default)>load data local inpath ‘/opt/module/datas/dept.txt‘ into table default.dept_partition2 partition(month=‘202009‘, day=‘13‘);

(2)查询分区数据

hive (default)> select * from dept_partition2 where month=‘202009‘ and day=‘13‘;

3.把数据直接上传到分区目录上,让分区表和数据产生关联的三种方式

(1)方式一:上传数据后修复

? 上传数据

hive (default)> dfs -mkdir -p /user/hive/warehouse/dept_partition2/month=202009/day=12; 

hive (default)> dfs -put /opt/module/datas/dept.txt /user/hive/warehouse/dept_partition2/month=202009/day=12;

查询数据(查询不到刚上传的数据)

hive (default)> select * from dept_partition2 where month=‘202009‘ and day=‘12‘;

执行修复命令

hive> msck repair table dept_partition2;

再次查询数据

hive (default)> select * from dept_partition2 where month=‘202009‘ and day=‘12‘;

(2)方式二:上传数据后添加分区

? 上传数据

hive (default)> dfs -mkdir -p /user/hive/warehouse/dept_partition2/month=202009/day=11; 

hive (default)> dfs -put /opt/module/datas/dept.txt /user/hive/warehouse/dept_partition2/month=202009/day=11;

执行添加分区

 hive (default)> alter table dept_partition2 add partition(month=‘202009‘,day=‘11‘);

查询数据

hive (default)> select * from dept_partition2 where month=‘202009‘ and day=‘11‘;

(3)方式三:创建文件夹后 load 数据到分区

创建目录

hive (default)> dfs -mkdir -p /user/hive/warehouse/dept_partition2/month=202009/day=10;

上传数据

hive (default)>load data local inpath ‘/opt/module/datas/dept.txt‘ into table dept_partition2 partition(month=‘202009‘,day=‘10‘);

查询数据

hive (default)> select * from dept_partition2 where month=‘202009‘ and day=‘10‘;
4)关于动态分区表

前面的分区创建方式为静态分区,如果需要创建非常多的分区,或者根据指定字段值分区,就需要使用动态分区,hive的动态分区可以基于查询参数推断出需要创建的分区名称。

eg:

insert overwrite table employees partition(country,state)

select ...,se.cnty,se.st

from staged_employees se;

如上面例子,hive可以根据select语句中最后2列来确定分区字段country和state的值。这也是为什么在上面例子使用了不同的命名,就是为了强调源表字段值和输出分区值之间的关系是根据位置而不是根据命名来匹配的。

关于混合使用动态和静态分区

eg:

insert overwrite table employees partition(country=‘China‘,state)

select ...,se.cnty,se.st

from staged_employees se

where se.cnty=‘China‘;

如上面例子,指定了country字段的值为静态的中国,而分区字段state是动态值

注意:静态分区必须出现在动态分区键之前

动态分区功能默认是关闭的,开启后,也会默认是严格模式执行,在这种模式下要求至少有一列分区字段是静态的,这有助于因设计错误导致查询产生大量的分区。

动态分区属性

属性名称 缺省值(默认值) 描述
hive.exec.dynamic.partition false 设置为true,表示开启动态分区功能
hive.exec.dynamic.parititon.mode strict 设置为nonstrict,表示允许所有分区都是动态的
hive.exec.dynamic.partitions.pernode 100 每个mapper或reducer可以创建的最大动态分区个数,如果某个mapper或reducer尝试创建超过这个值的分区的话,就会报错
hive.exec.dynamic.parititons 1000 一个动态分区创建语句可以创建的最大动态分区个数。如果超过也会报错
hive.exec.max.created.files 100000 全局可以创建的最大文件个数。有一个Hadoop计数器,会跟踪记录创建了多少个文件,如果超过也会报错。
5)关于倾斜表

通过指定一个或者多个列经常出现的值(严重偏斜),Hive 会自动将涉及到这些值的数据拆分为单独的文件。在查询时,如果涉及到倾斜值,它就直接从独立文件中获取数据,而不是扫描所有文件,这使得性能得到提升。

create [exertnal] table 倾斜表名(字段名 类型,字段名 类型) skewed by (倾斜字段) ON (对应常见倾斜值,对应常见倾斜值)

row format delimited fields terminated by 字段分隔符;

9、视图

当查询变得长或复杂的时候,通过使用视图将这个查询语句分割成多个小的、更可控的片段可以降低这种复杂度。这点和在编程语言中使用函数或者软件设计中的分层设计的概念是一致的。封装复杂的部分可以是最终用户通过重用重复的部分来构建复杂的查询。

对于视图来说一个常见的使用场景就是基于一个或多个列的值来限制输出结果。有些数据库允许将视图作为一个安全机制,也就是不给用户直接访问具有敏感数据的原始表,而是提供给用户一个通过WHERE子句限制了的视图,以供访问。Hive 目前并不支持这个功能,因为用户必须具有能够访问整个底层原始表的权限,这时视图才能工作。然而,通过创建视图来限制数据访问可以用来保护信息不被随意查询。

Hive 会先解析视图,然后使用解析结果再来解析整个查询语句。然而,作为Hive查询优化器的一部分,查询语句和视图语句可能会合并成-一个单-一的实际查询语句。这个概念视图仍然适用于视图和使用这个视图的查询语句都包含了一个ORDER BY子句或-一个LIMIT子句的情况。这时会在使用这个视图的查询语句之前对该视图进行解析。例如,如果视图语句含有一个LIMIT 100 子句,而同时使用到这个视图的查询含有一个LIMIT 200子句,那么用户最终最多只能获取100条结果记录。因为定义一个视图实际上并不会“具体化”操作任何实际数据,所以视图实际上是对其所使用到的表和列的一个查询语句固化过程。因此,如果视图所涉及的表或者列不再存在时,会导致视图查询失败。

一个视图的名称要和这个视图所在的数据库下的其他所有表和视图的名称不同。用户还可以为所有的新列或部分新列增加一个COMMNET子句,进行写注释。这些注释并非“ 继承”原始表中的定义。同样地,如果AS SELECT子句中包含没有命名别名的表达式的话,例如size(cols)(计算cols中元素的个数),那么Hive将会使用_ _CN 作为新的列名,其中N表示从0开始的一个整数。如果AS SELECT语句不合法的话,那么创建视图过程将失败。

eg:

CREATE VIEW IF NOT EXISTS shipments (time, part)

COMMENT ‘ Time and parts for shipments. ‘

TBLPROPERTIES ( ‘creator‘ = ‘me‘ )

AS SELECT ...;

在AS SELECT子句之前,用户可以通过定义TBLPROPERTIES来定义表属性信息,这点和表相同。上例中,我们定义的属性为“creator”, 表示这个视图的创建者名称。

CREATE [EXTERNAL] TABLE ... LIKE ..结构同样适用于复制视图,只需要在LIKE表达式里面写视图名就可以了:

eg:

CREATE TABLE shipments2 LIKE shipments;

视图不能够作为INSERT语句或LOAD命令的目标表。视图是只读的。对于视图只允许改变元数据中TBLPROPERTIES(表属性)属性信息:

ALTER VIEW shipments SET TBLPROPERTIES (‘created_ at‘ = ‘ some_ timestamp‘) ;

1)Hive 的视图和关系型数据库的视图区别

和关系型数据库一样,Hive 也提供了视图的功能,不过请注意,Hive 的视图和关系型数据库的数据还是有很大的区别:

  (1)只有逻辑视图,没有物化视图;

  (2)视图只能查询,不能做加载数据操作,如:Load/Insert/Update/Delete 数据;

  (3)视图在创建时候,只是保存了一份元数据,当查询视图的时候,才开始执行视图对应的那些子查询

  (4)view定义中若包含了ORDER BY/LIMIT语句,当查询视图时也进行ORDER BY/LIMIT语句操作,view当中定义的优先级更高

? ? view: order by age asc;

? ? select order by age desc;

? ? select * from view order by age desc;

  (5)view支持迭代视图

? ? view1: select * from tb_user1;

? ? view2: select * from view1;

? ? view3: select * from view2;

2)Hive视图的创建语句
CREATE VIEW [IF NOT EXISTS] [db_name.]view_name 
  [(column_name [COMMENT column_comment], ...) ]
  [COMMENT view_comment]
  [TBLPROPERTIES (property_name = property_value, ...)]
  AS SELECT ... ;
3)Hive视图的查看语句
show views;
desc view_test;-- 查看某个具体视图的信息
4)Hive视图的使用语句
select colums from view_test;
select * from view_test;
5)Hive视图的删除语句
DROP VIEW [IF EXISTS] [db_name.]view_name;
drop view view_test;

10、索引

Hive只有有限的索引功能。Hive中没有普通关系型数据库中键的概念,但是还是可以对一些字段建立索引来加速某些操作的。一张表的索引数据存储在另外一张表中。

索引处理模块被设计成为可以定制的Java编码的插件,因此,用户可以根据需要对其进行实现,以满足自身的需求。

当逻辑分区实际上太多太细而几乎无法使用时,建立索引也就成为分区的另-一个选择。建立索引可以帮助裁剪掉一张表的一些数据块,这样能够减少MapReduce的输人数据量。并非所有的查询都可以通过建立索引获得好处。通过EXPLAIN命令可以查看某个查询语句是否用到了索引。

Hive中的索引和那些关系型数据库中的一样, 需要进行仔细评估才能使用。维护索引也需要额外的存储空间,同时创建索引也需要消耗计算资源。用户需要在建立索引为查询带来的好处和因此而需要付出的代价之间做出权衡。

1)创建索引
create index t1_index on table tb_user(name) 

as ‘org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler‘ with deferred rebuild 

in table t1_index_table;

as:指定索引器;

in table:指定索引表,若不指定默认生成在default_tb_user_t1_index表中

create index t2_index on table tb_user(name)

as ‘org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler‘ with deferred rebuild;

with deferred rebuild表示在执行alter index xxx_index on xxx rebuild时将调用generateIndexBuildTaskList获取Index的MapReduce,并执行为索引填充数据。

2)显示索引
show [formatted] index on tb_name;

关键字FORMATTED是可选的。增加这个关键字可以使输出中包含有列名称。用户还可以替换INDEX为INDEXES,这样输出中就可以列举出多个索引信息了。

3)重建索引

建立新索引之后必须重建索引才能生效

ALTER INDEX t2_index ON tb_user REBUILD;
ALTER INDEX employees_index ON TABLE employees
PARTITION (country = ‘China‘)
REBUILD;

如果省略掉PARTITION,那么将会对所有分区进行重建索引。

还没有一个内置的机制能够在底层的表或者某个特定的分区发生改变时,自动触发重建索引。但是,如果用户具有一个工作流来更新表分区中的数据的话,那么用户可能已经在其中某处使用到了ALTER TABLE .. TOUCH PARTITION(..)功能,同样地,在这个工作流中也可以对对应的索引执行重建索引语句ALTER INDEX ... REBUILD。

如果重建索引失败,那么在重建开始之前,索引将停留在之前的版本状态。从这种意义上看,重建索引操作是原子性的。

4)删除索引

如果有索引表的话,删除一个索引将会删除这个索引表:

DROP INDEX IF EXISTS t1_index ON tb_user;
DROP INDEX IF EXISTS employees_index ON TABLE employees;

Hive不允许用户直接使用DROP TABLE语句之前删除索引表。而通常情况下,IF EXISTS都是可选的,其用于当索引不存在时避免抛出错误信息。如果被索引的表被删除了,那么其对应的索引和索引表也会被删除。同样地,如果原始表的某个分区被删除了,那么这个分区对应的分区索引也同时会被删除掉。

二、DML数据操作

1、数据导入

1) 向表中装载数据(Load
load data [local] inpath ‘/opt/module/datas/table_name.txt‘ [overwrite] | into table table_name
[partition (partcol1=val1,…)];

(1)load data:表示加载数据

(2)local:表示从本地加载数据到 hive 表;否则从 HDFS 加载数据到 hive 表

(3)inpath:表示加载数据的路径

(4)overwrite:表示覆盖表中已有数据,否则表示追加

(5)into table:表示加载到哪张表

(6)student:表示具体的表

(7)partition:表示上传到指定分区

2)Load示例

(1)创建一张表

hive (default)> create table student(id string, name string) 
row format delimited fields terminated by ‘\t‘;

(2)加载本地文件到 hive

hive (default)>load data local inpath ‘/opt/module/datas/student.txt‘ 
into table default.student;

(3)加载 HDFS 文件到 hive 中

上传文件到 HDFS

hive (default)> dfs -put /opt/module/datas/student.txt /user/chaos/hive;

加载 HDFS 上数据

hive (default)>load data inpath ‘/user/chaos/hive/student.txt‘ into table default.student;

(4)加载数据覆盖表中已有的数据

上传文件到 HDFS

hive (default)> dfs -put /opt/module/datas/student.txt /user/chaos/hive;

加载数据覆盖表中已有的数据

hive (default)>load data inpath ‘/user/chaos/hive/student.txt‘ overwrite into table default.student;
3) 通过查询语句向表中插入数据(Insert

1.创建一张分区表

create table student(id int, name string) partitioned by (month string) 
row format delimited fields terminated by ‘\t‘;

2.基本插入数据

hive (default)>insert into table student partition(month=‘202009‘) values(1,‘wangwu‘);

3.基本模式插入(根据单张表查询结果)

hive (default)> insert overwrite table student partition(month=‘202008‘) 
select id, name from student where month=‘202009‘;

4.多插入模式(根据多张表查询结果)

from(select * from student
)t 
insert overwrite table student partition(month=‘202007‘) 
select id,name where month=‘202009‘ 
insert overwrite table student partition(month=‘202006‘)
select id, name where month=‘202009‘;
4) 查询语句中创建表并加载数据(As Select

根据查询结果创建表(查询的结果会添加到新创建的表中)

create table if not exists student3 as select id, name from student;
5)创建表时通过 Location 指定加载数据路径

1.创建表,并指定在 hdfs 上的位置

hive (default)> create table if not exists student5(id int, name string)
row format delimited fields terminated by ‘\t‘ 
location ‘/user/hive/warehouse/student5‘;

2.上传数据到 hdfs 上

hive (default)> dfs -put /opt/module/datas/student.txt /user/hive/warehouse/student5;

3.查询数据

hive (default)> select * from student5;
6) Import 数据到指定 Hive 表中

注意:先用 export 导出后,再将数据导入。

hive (default)> import table student2 partition(month=‘202009‘) from ‘/user/hive/warehouse/export/student‘;

2、 数据导出

1)Insert 导出

(1)将查询的结果导出到本地

hive (default)> insert overwrite local directory ‘/opt/module/datas/export/student‘ 
select * from student;

(2)将查询的结果格式化导出到本地

hive(default)>insert overwrite local directory ‘/opt/module/datas/export/student1‘ 
ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘\t‘ 
select * from student;

(3)将查询的结果导出到 HDFS 上(与导出到本地的区别是没有 local)

hive (default)>insert overwrite directory ‘/user/chaos/student2‘ 
ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘\t‘ 
select * from student;
2 )Hadoop命令导出到本地
hive (default)>dfs -get /user/hive/warehouse/student/month=202009/000000_0 /opt/module/datas/export/student3.txt;
3) Hive Shell 命令导出基本语法:

(hive -f/-e 执行语句或者脚本 > file)

[chaos@hadoop102 hive]$ bin/hive -e ‘select * from default.student;‘ > /opt/module/datas/export/student4.txt;
4)Export 导出到 HDFS
hive(default)> export table default.student to ‘/user/hive/warehouse/export/student‘;

3、 清除表中数据(Truncate

注意:Truncate 只能删除管理表,不能删除外部表中数据

hive (default)> truncate table student;

三、查询

查询语句语法:

[WITH CommonTableExpression (, CommonTableExpression)*](Note: Only available starting with Hive 0.13.0)
  SELECT [ALL | DISTINCT] select_expr, select_expr, ...
  FROM table_reference
  [WHERE where_condition]
  [GROUP BY col_list]
  [ORDER BY col_list]
  [CLUSTER BY col_list] | [DISTRIBUTE BY col_list] 
  [SORT BY col_list]
  [LIMIT number]

1、 基本查询(Select…From

1) 全表和特定列查询

全表查询

hive (default)> select * from emp;

选择特定列查询

hive (default)> select empno, ename from emp;

注意:

(1)SQL 语言大小写不敏感。

(2)SQL 可以写在一行或者多行

(3)关键字不能被缩写也不能分行

(4)各子句一般要分行写。

(5)使用缩进提高语句的可读性。

2) 列别名

1.重命名一个列

2.便于计算

3.紧跟列名,也可以在列名和别名之间加入关键字‘AS’

4.中文别名需要使用反引号 `

5.案例实操查询名称和部门,创建时间

select 
	ename AS name,
	deptno dn,
	fcd as `创建时间`
from emp;
3) 算术运算符
运算符 描述
A+B A 和 B 相加
A-B A 减去 B
A*B A 和 B 相乘
A/B A 除以 B
A%B A 对 B 取余
A&B A 和 B 按位取与
A|B A 和 B 按位取或
A^B A 和 B 按位取异或
4)常用函数

1.求总数(count)

select count(*) cnt from emp;

2.求工资的最大值(max)

select max(sal) max_sal from emp;

3.求部门工资的最小值(min)

select deptno,min(sal) min_sal from emp group by deptno;

4.求工资的总和(sum)

select sum(sal) sum_sal from emp; 

5.求工资的平均值(avg)

 select avg(sal) avg_sal from emp;
5 )Limit 语句

典型的查询会返回多行数据。LIMIT 子句用于限制返回的行数。

select * from emp limit 5;

2、Where 语句

1.使用 WHERE 子句,将不满足条件的行过滤掉

2.WHERE 子句紧随 FROM 子句

1) 比较运算符(Between/In/ Is Null

下面表中描述了谓词操作符,这些操作符同样可以用于 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 为 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>=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) LikeRLike

1.使用 LIKE 运算选择类似的值

2.选择条件可以包含字符或数字:

% 代表零个或多个字符(任意个字符)。

_ 代表一个字符。

3.RLIKE 子句是 Hive 中这个功能的一个扩展,其可以通过 Java 的正则表达式这个更强大的语言来指定匹配条件。

eg:

(1)查找以 2 开头薪水的员工信息

select * from emp where sal LIKE ‘2%‘;

(2)查找第二个数值为 2 的薪水的员工信息

select * from emp where sal LIKE ‘_2%‘;

(3)查找薪水中含有 2 的员工信息

select * from emp where sal RLIKE ‘[2]‘;

3)逻辑运算符(And/Or/Not
操作符 含义
AND 逻辑并
OR 逻辑或
NOT 逻辑否

3、分组查询

1)Group By 语句

GROUP BY 语句通常会和聚合函数一起使用,按照一个或者多个列队结果进行分组,然后对每个组执行聚合操作。

eg:

(1)计算 emp 表每个部门的平均工资

select t.deptno, avg(t.sal) avg_sal

from emp t

group by t.deptno;

(2)计算 emp 每个部门中每个岗位的最高薪水

select t.deptno, t.job, max(t.sal) max_sal

from emp t

group by t.deptno, t.job;

2) Having 语句

having 与 where 不同点

(1)where 针对表中的列发挥作用,查询数据;having 针对查询结果中的列发挥作用,筛选数据。

(2)where 后面不能写聚合函数,而 having 后面可以使用聚合函数。

(3)having 只用于 group by 分组统计语句。

eg:

求每个部门的平均薪水大于 2000 的部门求每个部门的平均工资

select deptno, avg(sal)

from emp

group by deptno;

求每个部门的平均薪水大于 2000 的部门

select deptno, avg(sal) avg_sal

from emp

group by deptno

having avg_sal > 2000;

4、 Join 语句

1)等值 Join

Hive 支持通常的 SQL JOIN 语句,但是只支持等值连接,不支持非等值连接。

eg:

select

? e.empno,

? e.ename,

? d.deptno,

? d.dname

from emp e

join dept d on e.deptno != d.deptno;

会报错,‘>‘和‘<‘ 这种也不支持

2) 表的别名

1.好处

(1)使用别名可以简化查询。

(2)使用表名前缀可以提高执行效率。<提高的不多,不过也算可以优化提高的点,同时也增加sql的可读性>

3) 内连接

只有进行连接的两个表中都存在与连接条件相匹配的数据才会被保留下来。

4) 左外连接左外连接

JOIN 操作符左边表中符合 WHERE 子句的所有记录将会被返回。

5)右外连接右外连接

JOIN 操作符右边表中符合 WHERE 子句的所有记录将会被返回。

6) 满外连接

将会返回所有表中符合 WHERE 语句条件的所有记录。如果任一表的指定字段没有符合条件的值的话,那么就使用 NULL 值替代。

7) 多表连接

注意:连接 n 个表,至少需要 n-1 个连接条件。

例如:连接三个表,至少需要两个连接条件。

eg:

1.创建位置表

create table if not exists default.location( loc int, loc_name string) row format delimited fields terminated by ‘\t‘;

2.导入数据

hive (default)>load data local inpath ‘/opt/module/data/location.txt‘ into table default.location;

3.多表连接查询

SELECT e.ename, d.deptno, l.loc_name

FROM emp e

JOIN dept d ON d.deptno = e.deptno

JOIN location l ON d.loc = l.loc;

大多数情况下,Hive 会对每对 JOIN 连接对象启动一个 MapReduce 任务。本例中会首先启动一个 MapReduce job 对表 e 和表 d 进行连接操作,然后会再启动一个 MapReduce job 将第一个 MapReduce job 的输出和表 l;进行连接操作。

注意:为什么不是表 d 和表 l 先进行连接操作呢?这是因为 Hive 总是按照从左到右的顺序执行的。

8) 笛卡尔积

1.笛卡尔集会在下面条件下产生

(1)省略连接条件

(2)连接条件无效

(3)所有表中的所有行互相连接

注意:开启严格模式的话,笛卡尔积这种查询会报错

9) 连接谓词中不支持 or
select
	e.empno,
	e.ename,
	d.deptno
from emp e 
join dept d on e.deptno=d.deptno or e.ename=d.dname;

FAILED: SemanticException [Error 10019]: Line 10:3 OR not supported in JOIN currently ‘dname‘

5、排序

1)全局排序(Order By

Order By:全局排序,一个 Reducer

1.使用 ORDER BY 子句排序

ASC(ascend): 升序(默认)

DESC(descend): 降序

2.ORDER BY 子句在 SELECT 语句的结尾

2) 按照别名排序

eg:

按照员工薪水的 2 倍排序

select ename, sal*2 twosal from emp order by twosal;

3) 多个列排序

eg:

按照部门升序和工资降序排序

select ename, deptno, sal from emp order by deptno asc, sal desc ;

4) 每个 MapReduce 内部排序/区内排序(Sort By

Sort By:每个 Reducer 内部进行排序,对全局结果集来说不是排序。

eg:

1.设置 reduce 个数

hive (default)> set mapreduce.job.reduces=3;

2.查看设置 reduce 个数

hive (default)> set mapreduce.job.reduces;

3.根据部门编号降序查看员工信息

hive (default)> select * from emp sort by empno desc;

4.将查询结果导入到文件中(按照部门编号降序排序)

hive (default)> insert overwrite local directory ‘/opt/module/datas/sortby-result‘ select * from emp sort by deptno desc;

5) 分区排序(Distribute By

Distribute By:类似 MR 中 partition,进行分区,结合 sort by 使用。

注意,Hive 要求 DISTRIBUTE BY 语句要写在 SORT BY 语句之前。

对于 distribute by 进行测试,一定要分配多 reduce 进行处理,否则无法看到 distribute by 的效果。

eg:

根据部门编号查看每个部门,再根据员工编号降序查看每个部门中员工

先按照部门编号分区,再按照员工编号降序排序。

hive (default)> set mapreduce.job.reduces=3;

hive (default)> insert overwrite local directory ‘/opt/module/datas/distribute-result‘ select * from emp distribute by deptno sort by empno desc;

6) Cluster By

当 distribute by 和 sorts by 字段相同时,可以使用 cluster by 方式。

cluster by 除了具有 distribute by 的功能外还兼具 sort by 的功能。但是排序只能是升序排序,不能指定排序规则为 ASC 或者 DESC

以下两种写法等价

hive (default)> select * from emp cluster by deptno; 
hive (default)> select * from emp distribute by deptno sort by deptno;

注意:按照部门编号分区,不一定就是固定死的数值,可以是 20 号和 30 号部门分到一个分区里面去。

6) 分桶及抽样查询<很少用>

分区针对的是数据的存储路径;分桶针对的是数据文件。

分区提供一个隔离数据和优化查询的便利方式。不过,并非所有的数据集都可形成合理的分区,特别是之前所提到过的要确定合适的划分大小这个疑虑。

分桶是将数据集分解成更容易管理的若干部分的另一个技术。

eg:

先创建分桶表,通过直接导入数据文件的方式

(1)数据准备

student.txt

(2)创建分桶表,和一个普通表

create table stu_buck(id int, name string) clustered by(id) into 4 buckets row format delimited fields terminated by ‘\t‘;

create table stu(id int, name string) row format delimited fields terminated by ‘\t‘;

向普通的 stu 表中导入数据

load data local inpath ‘/opt/module/datas/student.txt‘ into table stu;

(3)查看表结构

hive (default)> desc formatted stu_buck;

Num Buckets: 4

(4)设置属性,通过子查询的方式导入数据

hive (default)> set hive.enforce.bucketing=true;

hive (default)> set mapreduce.job.reduces=-1;

hive (default)> insert into table stu_buck select id, name from stu;

分桶抽样查询

对于非常大的数据集,有时用户需要使用的是一个具有代表性的查询结果而不是全部结果。Hive 可以通过对表进行抽样来满足这个需求。查询表 stu_buck 中的数据。

hive (default)> select * from stu_buck tablesample(bucket 1 out of 4 on id);

注:tablesample 是抽样语句,语法:TABLESAMPLE(BUCKET x OUT OF y) 。

y 必须是 table 总 bucket 数的倍数或者因子。hive 根据 y 的大小,决定抽样的比例。例如,table 总共分了 4 份,当 y=2 时,抽取(4/2=)2 个 bucket 的数据,当 y=8 时,抽取(4/8=)1/2 个 bucket 的数据。

x 表示从哪个 bucket 开始抽取,如果需要取多个分区,以后的分区号为当前分区号加上 y。

例如,table 总 bucket 数为 4,tablesample(bucket 1 out of 2),表示总共抽取(4/2=)2 个 bucket的数据,抽取第 1(x)个和第 3(x+y)个 bucket 的数据。

注意:x 的值必须小于等于 y 的值,否则

FAILED: SemanticException [Error 10061]: Numerator should not be bigger than denominator in sample clause for table stu_buck

6、常用查询函数

1)条件函数
Return Type Name(Signature) Description
T if(boolean testCondition, T valueTrue, T valueFalseOrNull) Returns valueTrue when testCondition is true, returns valueFalseOrNull otherwise.如果testCondition 为true就返回valueTrue,否则返回valueFalseOrNull ,(valueTrue,valueFalseOrNull为泛型)
T nvl(T value, T default_value) Returns default value if value is null else returns value (as of HIve ).如果value值为NULL就返回default_value,否则返回value
T COALESCE(T v1, T v2, ...) Returns the first v that is not NULL, or NULL if all v‘s are NULL.返回第一非null的值,如果全部都为NULL就返回NULL 如:COALESCE (NULL,44,55)=44/strong>
T CASE a WHEN b THEN c [WHEN d THEN e] [ELSE f] END* When a = b, returns c; when a = d, returns e; else returns f.如果a=b就返回c,a=d就返回e,否则返回f 如CASE 4 WHEN 5 THEN 5 WHEN 4 THEN 4 ELSE 3 END 将返回4
T CASE WHEN a THEN b [WHEN c THEN d] [ELSE e] END* When a = true, returns b; when c = true, returns d; else returns e.如果a=ture就返回b,c= ture就返回d,否则返回e 如:CASE WHEN 5>0 THEN 5 WHEN 4>0 THEN 4 ELSE 0 END 将返回5;CASE WHEN 5<0 THEN 5 WHEN 4<0 THEN 4 ELSE 0 END 将返回0
boolean isnull( a ) Returns true if a is NULL and false otherwise.如果a为null就返回true,否则返回false
boolean isnotnull ( a ) Returns true if a is not NULL and false otherwise.如果a为非null就返回true,否则返回false
2)数学函数
Return Type Name (Signature) Description
DOUBLE round(DOUBLE a) Returns the rounded BIGINT value of a.返回对a四舍五入的BIGINT值
DOUBLE round(DOUBLE a, INT d) Returns a rounded to d decimal places.返回DOUBLE型d的保留n位小数的DOUBLW型的近似值
DOUBLE bround(DOUBLE a) Returns the rounded BIGINT value of a using HALF_EVEN rounding mode (as of ). Also known as Gaussian rounding or bankers‘ rounding. Example: bround(2.5) = 2, bround(3.5) = 4. 银行家舍入法(14:舍,69:进,5->前位数是偶:舍,5->前位数是奇:进)
DOUBLE bround(DOUBLE a, INT d) Returns a rounded to d decimal places using HALF_EVEN rounding mode (as of ). Example: bround(8.25, 1) = 8.2, bround(8.35, 1) = 8.4. 银行家舍入法,保留d位小数
BIGINT floor(DOUBLE a) Returns the maximum BIGINT value that is equal to or less than a向下取整,最数轴上最接近要求的值的左边的值 如:6.10->6 -3.4->-4
BIGINT ceil(DOUBLE a), ceiling(DOUBLE a) Returns the minimum BIGINT value that is equal to or greater than a.求其不小于小给定实数的最小整数如:ceil(6) = ceil(6.1)= ceil(6.9) = 6
DOUBLE rand(), rand(INT seed) Returns a random number (that changes from row to row) that is distributed uniformly from 0 to 1. Specifying the seed will make sure the generated random number sequence is deterministic.每行返回一个DOUBLE型随机数seed是随机因子
DOUBLE exp(DOUBLE a), exp(DECIMAL a) Returns ea where e is the base of the natural logarithm. Decimal version added in .返回e的a幂次方, a可为小数
DOUBLE ln(DOUBLE a), ln(DECIMAL a) Returns the natural logarithm of the argument a. Decimal version added in .以自然数为底d的对数,a可为小数
DOUBLE log10(DOUBLE a), log10(DECIMAL a) Returns the base-10 logarithm of the argument a. Decimal version added in .以10为底d的对数,a可为小数
DOUBLE log2(DOUBLE a), log2(DECIMAL a) Returns the base-2 logarithm of the argument a. Decimal version added in .以2为底数d的对数,a可为小数
DOUBLE log(DOUBLE base, DOUBLE a)log(DECIMAL base, DECIMAL a) Returns the base-base logarithm of the argument a. Decimal versions added in .以base为底的对数,base 与 a都是DOUBLE类型
DOUBLE pow(DOUBLE a, DOUBLE p), power(DOUBLE a, DOUBLE p) Returns ap.计算a的p次幂
DOUBLE sqrt(DOUBLE a), sqrt(DECIMAL a) Returns the square root of a. Decimal version added in .计算a的平方根
STRING bin(BIGINT a) Returns the number in binary format (see ).计算二进制a的STRING类型,a为BIGINT类型
STRING hex(BIGINT a) hex(STRING a) hex(BINARY a) If the argument is an INT or binary, hex returns the number as a STRING in hexadecimal format. Otherwise if the number is a STRING, it converts each character into its hexadecimal representation and returns the resulting STRING. (Seehttp://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_hex, BINARY version as of Hive .)计算十六进制a的STRING类型,如果a为STRING类型就转换成字符相对应的十六进制
BINARY unhex(STRING a) Inverse of hex. Interprets each pair of characters as a hexadecimal number and converts to the byte representation of the number. (BINARY version as of Hive , used to return a string.)hex的逆方法
STRING conv(BIGINT num, INT from_base, INT to_base), conv(STRING num, INT from_base, INT to_base) Converts a number from a given base to another (see ).将GIGINT/STRING类型的num从from_base进制转换成to_base进制
DOUBLE abs(DOUBLE a) Returns the absolute value.计算a的绝对值
INT or DOUBLE pmod(INT a, INT b), pmod(DOUBLE a, DOUBLE b) Returns the positive value of a mod b.a对b取模
DOUBLE sin(DOUBLE a), sin(DECIMAL a) Returns the sine of a (a is in radians). Decimal version added in .求a的正弦值
DOUBLE asin(DOUBLE a), asin(DECIMAL a) Returns the arc sin of a if -1<=a<=1 or NULL otherwise. Decimal version added in .求d的反正弦值
DOUBLE cos(DOUBLE a), cos(DECIMAL a) Returns the cosine of a (a is in radians). Decimal version added in .求余弦值
DOUBLE acos(DOUBLE a), acos(DECIMAL a) Returns the arccosine of a if -1<=a<=1 or NULL otherwise. Decimal version added in .求反余弦值
DOUBLE tan(DOUBLE a), tan(DECIMAL a) Returns the tangent of a (a is in radians). Decimal version added in .求正切值
DOUBLE atan(DOUBLE a), atan(DECIMAL a) Returns the arctangent of a. Decimal version added in .求反正切值
DOUBLE degrees(DOUBLE a), degrees(DECIMAL a) Converts value of a from radians to degrees. Decimal version added in .奖弧度值转换角度值
DOUBLE radians(DOUBLE a), radians(DOUBLE a) Converts value of a from degrees to radians. Decimal version added in .将角度值转换成弧度值
INT or DOUBLE positive(INT a), positive(DOUBLE a) Returns a.返回a
INT or DOUBLE negative(INT a), negative(DOUBLE a) Returns -a.返回a的相反数
DOUBLE or INT sign(DOUBLE a), sign(DECIMAL a) Returns the sign of a as ‘1.0‘ (if a is positive) or ‘-1.0‘ (if a is negative), ‘0.0‘ otherwise. The decimal version returns INT instead of DOUBLE. Decimal version added in .如果a是正数则返回1.0,是负数则返回-1.0,否则返回0.0
DOUBLE e() Returns the value of e.数学常数e
DOUBLE pi() Returns the value of pi.数学常数pi
BIGINT factorial(INT a) Returns the factorial of a (as of Hive ). Valid a is [0..20]. 求a的阶乘
DOUBLE cbrt(DOUBLE a) Returns the cube root of a double value (as of Hive ). 求a的立方根
INT BIGINT shiftleft(TINYINT|SMALLINT|INT a, INT b)shiftleft(BIGINT a, INT b) Bitwise left shift (as of Hive ). Shifts a b positions to the left.Returns int for tinyint, smallint and int a. Returns bigint for bigint a.按位左移
INTBIGINT shiftright(TINYINT|SMALLINT|INT a, INTb)shiftright(BIGINT a, INT b) Bitwise right shift (as of Hive ). Shifts a b positions to the right.Returns int for tinyint, smallint and int a. Returns bigint for bigint a.按拉右移
INTBIGINT shiftrightunsigned(TINYINT|SMALLINT|INTa, INT b),shiftrightunsigned(BIGINT a, INT b) Bitwise unsigned right shift (as of Hive ). Shifts a b positions to the right.Returns int for tinyint, smallint and int a. Returns bigint for bigint a.无符号按位右移(<<<)
T greatest(T v1, T v2, ...) Returns the greatest value of the list of values (as of Hive ). Fixed to return NULL when one or more arguments are NULL, and strict type restriction relaxed, consistent with ">" operator (as of Hive ). 求最大值
T least(T v1, T v2, ...) Returns the least value of the list of values (as of Hive ). Fixed to return NULL when one or more arguments are NULL, and strict type restriction relaxed, consistent with "<" operator (as of Hive ). 求最小值
3)集合函数
Return Type Name(Signature) Description
int size(Map) Returns the number of elements in the map type.求map的长度
int size(Array) Returns the number of elements in the array type.求数组的长度
array map_keys(Map) Returns an unordered array containing the keys of the input map.返回map中的所有key
array map_values(Map) Returns an unordered array containing the values of the input map.返回map中的所有value
boolean array_contains(Array, value) Returns TRUE if the array contains value.如该数组Array包含value返回true。,否则返回false
array sort_array(Array) Sorts the input array in ascending order according to the natural ordering of the array elements and returns it (as of version ).按自然顺序对数组进行排序并返回
4)类型转换函数
Return Type **Name(Signature) ** Description
bin

本类排行

今日推荐

热门手游