HIve(一)
- 创建数据库
- 创建一个数据库,数据库在HDFS上的默认存储路径是/usr/hive/warehouse/*.db
- create database db_hive;
- 避免要创建的数据是已经存在错误,增加if not exists 判断。
- create database db_hive if not exists db_hive;
- 创建一个数据库,指定数据库在HDFS上存放的位置
- create databaes db_hive2 location '/db_hive2';
- 查询数据库
- 显示数据库
- show databases;
- show databases like 'db_hive*';
- 查看数据库详情
- 显示数据库信息
- desc database db_hive;
- 显示数据库详细信息,extended
- desc database extended db_hive;
- 修改数据库
- 用户可以使用ALTER DATABASE命令为某个数据库的DBPROPERTIES设置键-值对属性值,来描述这个数据库的属性信息。数据库的其他元数据信息都是不可更改的,包括数据库名和数据库所在的目录位置。
- alter database db_hive set dbproperties('createtime'='20170830');
- 删除数据库
-
- drop database db_hive2;
- 如果删除的数据库不存在,最好采用 if exists判断数据库是否存在
- drop database db_hive;
- 如果数据库不为空,可以采用cascade命令,强制删除
- drop database db_hive;
-
- 创建表
- 建表语句
- create table table_name ( .. ..) ROW FORMAT
-
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]
- 字段解释说明
-
CREATE TABLE 创建一个指定名字的表。如果相同名字的表已经存在,则抛出异常;用户可以用 IF NOT EXISTS 选项来忽略这个异常。
- EXTERNAL关键字可以让用户创建一个外部表,在建表的同时指定一个指向实际数据的路径(LOCATION),Hive创建内部表时,会将数据移动到数据仓库指向的路径;若创建外部表,仅记录数据所在的路径,不对数据的位置做任何改变。在删除表的时候,内部表的元数据和数据会被一起删除,而外部表只删除元数据,不删除数据。
- COMMENT:为表和列添加注释。
- PARTITIONED BY创建分区表
- CLUSTERED BY创建分桶表
- SORTED 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确定表的具体的列的数据。
- SerDe是Serialize/Deserilize的简称,目的是用于序列化和反序列化。
-
- STORED AS指定存储文件类型
- 常用的存储文件类型:SEQUENCEFILE(二进制序列文件)、TEXTFILE(文本)、RCFILE(列式存储格式文件)
- 如果文件数据是纯文本,可以使用STORED AS TEXTFILE。如果数据需要压缩,使用 STORED AS SEQUENCEFILE。
- LOCATION :指定表在HDFS上的存储位置。
- LIKE允许用户复制现有的表结构,但是不复制数据。
-
- 建表语句
- 管理表
-
- 理论
- 默认创建的表都是所谓的管理表,有时也被称为内部表。因为这种表,Hive会(或多或少地)控制着数据的生命周期。Hive默认情况下会将这些表的数据存储在由配置项hive.metastore.warehouse.dir(例如,/user/hive/warehouse)所定义的目录的子目录下。 当我们删除一个管理表时,Hive也会删除这个表中数据。管理表不适合和其他工具共享数据。
- 理论
-
- 案例实操
- 普通创建表
- 案例实操
|
create table if not exists student2( id int, name string ) row format delimited fields terminated by '\t' stored as textfile location '/user/hive/warehouse/student2'; |
-
-
- 根据查询结果创建表(查询的结果会添加到新创建的表中)
-
|
create table if not exists student3 as select id, name from student; |
-
-
- 根据已经存在的表结构创建表
-
|
create table if not exists student4 like student; |
- 外部表
- 理论
- 因为表是外部表,所以Hive并非认为其完全拥有这份数据。删除该表并不会删除掉这
份数据,不过描述表的元数据信息会被删除掉。
- 因为表是外部表,所以Hive并非认为其完全拥有这份数据。删除该表并不会删除掉这
- 管理表和外部表的使用场景
-
每天将收集到的网站日志定期流入HDFS文本文件。在外部表(原始日志表)的基础上做大量的统计分析,用到的中间表、结果表使用内部表存储,数据通过SELECT+INSERT进入内部表。
-
- 理论
- 案例实操
- 分别创建部门和员工外部表,并向表中导入数据。
- 建表语句
- 创建部门表
- 建表语句
- 分别创建部门和员工外部表,并向表中导入数据。
|
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'; |
-
-
- 向外部表中导入数据
- 导入数据
- load data local inpath '/opt/module/datas/dept.txt' into table default.dept;
- load data local inpath '/opt/module/datas/emp.txt' into table default.emp;
- 导入数据
- 向外部表中导入数据
-
-
管理表与外部表的互相转换
-
查询表的类型
-
desc formatted student2;
-
- 修改内部表student2为外部表
- alter table student2 set tblproperties('EXTERNAL'='TRUE');
- 查询表的类型
- desc formatted student2;
- 修改外部表student2为内部表
- alter table student2 set tblproperties('EXTERNAL'='FALSE');
- 查询表的类型
- desc formatted student2;
- 注意:('EXTERNAL'='TRUE')和('EXTERNAL'='FALSE')为固定写法,区分大小写!
-
-
分区表
- 分区表实际上就是对应一个HDFS文件系统上的独立的文件夹,该文件夹下是该分区所有的数据文件。Hive中的分区就是分目录,把一个大的数据集根据业务需要分割成小的数据集。在查询时通过WHERE子句中的表达式选择查询所需要的指定的分区,这样的查询效率会提高很多。
-
分区表基本操作
- 引入分区表(需要根据日期对日志进行管理)
- /user/hive/warehouse/log_partition/20170702/20170702.log
- /user/hive/warehouse/log_partition/20170703/20170703.log
- /user/hive/warehouse/log_partition/20170704/20170704.log
- 创建分区表语法
- 引入分区表(需要根据日期对日志进行管理)
| hive (default)> create table dept_partition(deptno int, dname string, loc string)partitioned by (month string)row format delimited fields terminated by '\t'; |
-
-
- 加载数据到分区表中
- load data local inpath '/opt/module/datas/dept.txt' into table default.dept_partition partition(month='201709');
- load data local inpath '/opt/module/datas/dept.txt' into table default.dept_partition partition(month='201708');
- load data local inpath '/opt/module/datas/dept.txt' into table default.dept_partition partition(month='201707’);
- 加载数据到分区表中
-
-
-
- 查询分区表中数据
- 单分区查询
- select * from dept_partition where month='201709';
- 多分区联合查询
- 单分区查询
- 查询分区表中数据
-
select * from dept_partition where month='201709' union select * from dept_partition where month='201708' union select * from dept_partition where month='201707';
-
-
- 增加分区
- 创建单个分区
- alter table dept_partition add partition(month='201706') ;
- 同时创建多个分区
- alter table dept_partition add partition(month='201705') partition(month='201704');
- 创建单个分区
- 删除分区
- 删除单个分区
- alter table dept_partition drop partition (month='201704');
- 同时删除多个分区
- alter table dept_partition drop partition (month='201705'), partition (month='201706');
- 删除单个分区
- 查看分区表有多少分区
- show partitions dept_partition;
-
查看分区表结构
-
show partitions dept_partition;
-
- 增加分区
-
分区表注意事项
- 创建二级分区表
-
|
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'; |
-
-
- 正常的加载数据
- 加载数据到二级分区表中
- load data local inpath '/opt/module/datas/dept.txt' into table default.dept_partition2 partition(month='201709', day='13');
- 加载数据到二级分区表中
- 查询分区数据
- select * from dept_partition2 where month='201709' and day='13';
- 正常的加载数据
- 把数据直接上传到分区目录上,让分区表和数据产生关联的三种方式
- 方式一:上传数据后修复
- 上传数据
- dfs -mkdir -p /user/hive/warehouse/dept_partition2/month=201709/day=12;
- dfs -put /opt/module/datas/dept.txt /user/hive/warehouse/dept_partition2/month=201709/day=12;
- 查询数据(查询不到刚上传的数据)
- select * from dept_partition2 where month='201709' and day='12';
- 执行修复命令
- msck repair table dept_partition2;
- 再次查询数据
- select * from dept_partition2 where month='201709' and day='12';
- 上传数据
- 方式二:上传数据后添加分区
- 上传数据
- dfs -mkdir -p /user/hive/warehouse/dept_partition2/month=201709/day=11;
- dfs -put /opt/module/datas/dept.txt /user/hive/warehouse/dept_partition2/month=201709/day=11;
- 执行添加分区
- alter table dept_partition2 add partition(month='201709', day='11');
- 查询数据
- select * from dept_partition2 where month='201709' and day='11';
- 上传数据
- 方式三:创建文件夹后load数据到分区
- 创建目录
- dfs -mkdir -p /user/hive/warehouse/dept_partition2/month=201709/day=10;
- 上传数据
- load data local inpath '/opt/module/datas/dept.txt' into table dept_partition2 partition(month='201709',day='10');
- 查询数据
- select * from dept_partition2 where month='201709' and day='10';
- 创建目录
- 方式一:上传数据后修复
-
- 分桶
- 分桶实际上是对文件(数据)的进一步切分
- Hive默认关闭分桶
- 作用:在往分桶表中插入数据的时候,会根据 clustered by 指定的字段 进行hash分区 对指定的buckets个数 进行取余,进而可以将数据分割成buckets个数个文件,以达到数据均匀分布,可以解决Map端的“数据倾斜”问题,方便我们取抽样数据,提高Map join效率
- 分桶字段 需要根据业务进行设定
- 开启分桶开关
- set hive.enforce.bucketing=true;
- 建立分桶表
create table students_buks ( id bigint, name string, age int, gender string, clazz string ) CLUSTERED BY (clazz) into 12 BUCKETS ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
- 往分桶表中插入数据
- 直接使用load data 并不能将数据打散
- load data local inpath '/usr/local/soft/data/students.txt' into table students_buks;
- 需要使用下面这种方式插入数据,才能使分桶表真正发挥作用
- insert into students_buks select * from students;
- https://zhuanlan.zhihu.com/p/93728864 Hive分桶表的使用场景以及优缺点分析
Hive JDBC
- 启动hiveserver2
- hive --service hiveserver2 &或者hiveserver2 &、
- 新建maven项目并添加两个依赖
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.7.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.hive/hive-jdbc -->
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-jdbc</artifactId>
<version>1.2.1</version>
</dependency>
编写JDBC代码
```java import java.sql.*; public class HiveJDBC { public static void main(String[] args) throws ClassNotFoundException, SQLException { Class.forName("org.apache.hive.jdbc.HiveDriver"); Connection conn = DriverManager.getConnection("jdbc:hive2://master:10000/test3"); Statement stat = conn.createStatement(); ResultSet rs = stat.executeQuery("select * from students limit 10"); while (rs.next()) { int id = rs.getInt(1); String name = rs.getString(2); int age = rs.getInt(3); String gender = rs.getString(4); String clazz = rs.getString(5); System.out.println(id + "," + name + "," + age + "," + gender + "," + clazz); } rs.close(); stat.close(); conn.close(); } }

浙公网安备 33010602011771号