Hive数据类型
基本数据类型
对于Hive的String类型相当于数据库的varchar类型,该类型是一个可变的字符串,不过它不能声明其中最多能存储多少个字符,理论上它可以存储2GB的字符数。
集合数据类型
Hive有三种复杂数据类型ARRAY、MAP 和 STRUCT。ARRAY和MAP与Java中的Array和Map类似,而STRUCT与C语言中的Struct类似,它封装了一个命名字段集合,复杂数据类型允许任意层次的嵌套。
案例实操
- 假设某表有如下一行,我们用JSON格式来表示其数据结构。在Hive下访问的格式为
1 | { |
- 基于上述数据结构,我们在Hive里创建对应的表,并导入数据。
1 | 创建本地测试文件test.txt |
注意:MAP,STRUCT和ARRAY里的元素间关系都可以用同一个字符表示,这里用“_”。
- Hive上创建测试表test
1 | create table test( |
1 | 字段解释: |
- 导入文本数据到测试表
1 | hive (default)> load data local inpath ‘/opt/module/datas/test.txt’into table test |
- 访问三种集合列里的数据,以下分别是ARRAY,MAP,STRUCT的访问方式
1 | hive (default)> select friends[1],children['xiao song'],address.city from test where name="songsong"; |
类型转化
Hive的原子数据类型是可以进行隐式转换的,类似于Java的类型转换,例如某表达式使用INT类型,TINYINT会自动转换为INT类型,但是Hive不会进行反向转化,例如,某表达式使用TINYINT类型,INT不会自动转换为TINYINT类型,它会返回错误,除非使用CAST操作。
隐式类型转换规则如下
- 任何整数类型都可以隐式地转换为一个范围更广的类型,如TINYINT可以转换成INT,INT可以转换成BIGINT。
- 所有整数类型、FLOAT和STRING类型都可以隐式地转换成DOUBLE。
- TINYINT、SMALLINT、INT都可以转换为FLOAT。
- BOOLEAN类型不可以转换为任何其它的类型。
可以使用CAST操作显示进行数据类型转换
例如CAST(‘1’ AS INT)将把字符串’1’ 转换成整数1;如果强制类型转换失败,如执行CAST(‘X’ AS INT),表达式返回空值 NULL。
DDL数据定义
创建数据库
- 创建一个数据库,数据库在HDFS上的默认存储路径是/user/hive/warehouse/*.db。
1 | hive (default)> create database db_hive; |
- 避免要创建的数据库已经存在错误,增加if not exists判断。(标准写法)
1 | hive (default)> create database db_hive; |
- 创建一个数据库,指定数据库在HDFS上存放的位置
1 | hive (default)> create database db_hive2 location '/db_hive2.db'; |
查询数据库
显示数据库
- 显示数据库
1 | hive> show databases; |
- 过滤显示查询的数据库
1 | hive> show databases like 'db_hive*'; |
查看数据库详情
- 显示数据库信息
1 | hive> desc database db_hive; |
- 显示数据库详细信息,extended
1 | hive> desc database extended db_hive; |
切换当前数据库
1 | hive (default)> use db_hive; |
修改数据库
用户可以使用alter database命令为某个数据库的dbproperties设置键-值对属性值,来描述这个数据库的属性信息。数据库的其他元数据信息都是不可更改的,包括数据库名和数据库所在的目录位置。
1 | hive (default)> alter database db_hive set dbproperties('createtime'='20170830'); |
在hive中查看修改结果
1 | hive> desc database extended db_hive; |
删除数据库
删除空数据库
1
hive>drop database db_hive2;
如果删除的数据库不存在,最好采用 if exists判断数据库是否存在
1 | hive> drop database db_hive; |
- 如果数据库不为空,可以采用cascade命令,强制删除
1 | hive> drop database db_hive; |
创建表
- 建表语法
1 | CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name |
- 字段解释说明
1 | (1)CREATE TABLE 创建一个指定名字的表。如果相同名字的表已经存在,则抛出异常;用户可以用 IF NOT EXISTS 选项来忽略这个异常。 |
管理表
理论
默认创建的表都是所谓的管理表,有时也被称为内部表。因为这种表,Hive会(或多或少地)控制着数据的生命周期。Hive默认情况下会将这些表的数据存储在由配置项hive.metastore.warehouse.dir(例如,/user/hive/warehouse)所定义的目录的子目录下。 当我们删除一个管理表时,Hive也会删除这个表中数据。管理表不适合和其他工具共享数据。
案例实操
- 普通创建表
1 | create table if not exists student2( |
- 根据查询结果创建表(查询的结果会添加到新创建的表中)
1 | create table if not exists student3 as select id, name from student; |
- 根据已经存在的表结构创建表
1 | create table if not exists student4 like student; |
- 查询表的类型
1 | hive (default)> desc formatted student2; |
外部表
理论
因为表是外部表,所以Hive并非认为其完全拥有这份数据。删除该表并不会删除掉这份数据,不过描述表的元数据信息会被删除掉。
管理表和外部表的使用场景
每天将收集到的网站日志定期流入HDFS文本文件。在外部表(原始日志表)的基础上做大量的统计分析,用到的中间表、结果表使用内部表存储,数据通过SELECT+INSERT进入内部表。
分区表
分区表实际上就是对应一个HDFS文件系统上的独立的文件夹,该文件夹下是该分区所有的数据文件。Hive中的分区就是分目录,把一个大的数据集根据业务需要分割成小的数据集。在查询时通过WHERE子句中的表达式选择查询所需要的指定的分区,这样的查询效率会提高很多。
分区表基本操作
- 引入分区表(需要根据日期对日志进行管理)
1 | /user/hive/warehouse/log_partition/20170702/20170702.log |
- 创建分区表语法
1 | hive (default)> create table dept_partition( |
- 加载数据到分区表中
1 | hive (default)> load data local inpath '/opt/module/datas/dept.txt' into table default.dept_partition partition(month='201709'); |
- 查询分区表中数据
- 单分区查询
1 | hive (default)> select * from dept_partition where month='201709'; |
- 多分区联合查询
1 | hive (default)> select * from dept_partition where month='201709' |
- 增加分区
创建单个分区
1
hive (default)> alter table dept_partition add partition(month='201706') ;
同时创建多个分区
1 | hive (default)> alter table dept_partition add partition(month='201705') partition(month='201704'); |
- 删除分区
删除单个分区
1
hive (default)> alter table dept_partition drop partition (month='201704');
同时删除多个分区
1 | hive (default)> alter table dept_partition drop partition (month='201705'), partition (month='201706'); |
- 查看分区表有多少分区
1 | hive> show partitions dept_partition; |
- 查看分区表结构
1 | hive> desc formatted dept_partition; |
分区表注意事项
- 创建二级分区表
1 | hive (default)> create table dept_partition2( |
- 正常的加载数据
1 | hive (default)> load data local inpath '/opt/module/datas/dept.txt' into table |
1 | hive (default)> select * from dept_partition2 where month='201709' and day='13'; |
- 把数据直接上传到分区目录上,让分区表和数据产生关联的三种方式
1 | 方式一:上传数据后修复 |
1 | 方式二:上传数据后添加分区 |
1 | 方式三:创建文件夹后load数据到分区 |
修改表
重命名表
- 语法
1 | ALTER TABLE table_name RENAME TO new_table_name |
- 操作
1 | hive (default)> alter table dept_partition2 rename to dept_partition3; |
增加/修改/替换列信息
- 语法
1 | 更新列 |
- 实操案例
1 | 查询表结构 |
1 | 添加列 |
1 | 查询表结构 |
1 | 更新列 |
1 | 替换列 |
删除表
1 | hive (default)> drop table dept_partition; |