Hive-常用的数据类型、表、库等操作

By timebusker on December 12, 2017

数据库操作

# 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 ...;   

Hive表的复合数据类型(少用,待续)