数据库操作
# hive 默认数据库为default,进入hive环境直接使用
# 数据库的文件路径 /user/hive/warehouse
# 创建数据库:
create database db_test;
# 数据库的文件路径 /user/hive/warehouse/db_test
# 使用数据库
use db_test;
# 显示数据库列表:
show db_test;
# shell环境显示数据信息
set hive.cli.print.current.db=true;
# 删除
drop database db_test;
表操作
- 表的数据类型,除了string和复合数据类型(
array, map, struct
)之外,几乎和mysql
一致。 -
DDL
即数据库模式定义语言DDL(Data Definition Language)
,用于描述数据库中要存储的现实世界实体的语言,其实就是数据库中关于表操作的语句。 - 外部表: 表中的数据的生命周期/存在与否,不受到了表结构的影响,当表结构被删除的,表中对应数据依然存在。相当于只是表对相应数据的引用。
当使用外部表时,是不允许删除操作的,但是可以添加数据,并且这样做也会影响到hdfs中引用的文本数据。
-
内部表/管理表/受控表: 表中的数据的生命周期/存在与否,受到了表结构的影响,当表结构被删除的,表中的数据随之一并被删除。默认创建的表就是这种表。
-
持久表与临时表
在一次会话session
中创建的临时存在的表,当会话断开的时候,该表所有数据(包括元数据)都会消失,表数据是临时存储在内存中, (实际上,创建临时表后,在hdfs中会创建/tmp/hive目录来保存临时文件,但只要退出会话,数据就会马上删除)。 表在元数据库中没有显示,这种临时表通常就做临时的数据存储或交换。
临时表的特点:不能是分区表
- 分区表
在表目录的基础之上再来创建一级或多级子目录,实现对大表的数据的划分,在指定分区时,可以快速定位、加载子文件夹下面的所有的数据。 从而减少了内存数据量,提高了hql运行效率。
分区表存在的问题:分区表是简单的根据分区列对数据划分目录,容易导致各分区之间数据不均匀。
- 分桶表
桶的概念就是MapReduce的分区的概念,两者完全相同。物理上每个桶就是目录里的一个文件,一个作业产生的桶(输出文件)数量和reduce任务个数相同。 按照数据内容的某个值进行分桶,把一个大文件散列称为一个个小文件。 操作分桶表的时候,本地模式不起作用。
分桶表存在的问题:容易产生大量小文件,导致影响平台性能,namenode/
# 建外部表
# 使用 external 指定,配置外部表数据 目录 :location
create external table t6_external(
id int comment '注释'
)location "/data_path/";
# 内部表和外部表进行互相转换:
# 外--->内
alter table tb_test set tblproperties("EXTERNAL"="false");
# 内--->外
alter table tb_test set tblproperties("EXTERNAL"="true");
# 建临时表
create temporary table tb_test(
id int comment '注释'
);
# 建分桶表
# CLUSTERED BY来指定划分桶所用列和划分桶的个数。HIVE对key的hash值除bucket个数取余数,保证数据均匀随机分布在所有bucket里。
# SORTED BY对桶中的一个或多个列另外排序
create table bucketed_user (
id int comment '注释'
) clustered by (id) sorted by (id asc) into 4 buckets;
数据操作
hive表默认的解析方式—-行列的分隔符:
- 默认的行分隔符
\n
- 默认的列分隔符
\001
# 自定义分隔符
create table t2 (
id int,
name string,
birthday date,
online boolean
) row format delimited ---->开启使用自定义分隔符的标识
fields terminated by '\t' ---->对每一列分隔符的定义
lines terminated by '\n'; ---->对每一行分隔符的定义,当然可以省略不写,默认和linux保持一致,同时注意,这两个顺序不能颠倒
数据进入数据库表中的模式:
-
读模式 将数据加载到表中的时候,对数据的合法性不进行校验,只有在操作表的时候,才对数据合法性进行校验,不合法的数据显示为NULL (比如某一列的数据类型为日期类型,如果load的某条数据是该列不是日期类型,则该条数据的这一列不合法,导入hive之后就会显示为NULL) 适合大数据的加载,比如hive
-
写模型 在数据加载到表中的时候,需要对数据的合法性进行校验,加载到数据库中的数据,都是合法的数据。 适合事务性数据库加载数据,常见的mysql、oracle等都是采用这种模式
-
加载:数据文件加载/从其他表加载/创建表的时候加载/动态分区的加载
# load data 加载数据
load data [local] inpath 'path' [overwrite] into table [partition_psc];
local:
有 ==> 从linux本地加载数据
无 ==> 从hdfs加载数据,相当于执行mv操作(无指的是没有local参数时,而不是本地中没有这个文件)
overwrite
有 ==> 覆盖掉表中原来的数据
无 ==> 在原来的基础上追加新的数据
- 导出
# hadoop 指令导出到本地目录,本地目录缺失,自动在当前目录下创建表名目录
hadoop fs -get hdfs://xxxxx [local_path]
# hive export 导出到hdfs://xxxxx
# 导出到的hdfs目录必须是一个空目录,如果不存在时,则会自动创建该目录,同时会将元数据信息导出。
export table tb_test to 'hdfs://xxxxx';
# SQL 指令导出
# 如果不加local,则数据会导出到hdfs,否则会导出到linux文件系统。不管哪一种方式,如果目录不存在,则会自动创建,如果存在,则会覆盖。
insert overwrite [local] directory 'linux_fs_path' select ...from... where ...;