hive简介
hive是什么?
hive是基于hadoop的数据仓库工具,他可以将结构化的数据(HDFS)映射成一张数据库表,并提供hive sql数据库操作,底层数据是存储在HDFS上,hive本质是将sql语句转换成MapReduce任务来进行。不熟悉java来写mapreduce的用户可以很方便的利用HQL处理和计算HDFS上的结构化的数据,适合离线数据计算。
Hive是适用于离线海量数据数据统计分析,也就是数据仓库,不能做实时查询的
Hive | RDBMS | |
---|---|---|
查询语言 | HQL | SQL |
数据储存 | HDFS | RAW DEVICES or Local FS |
执行器 | MapReduce | Executor |
数据插入 | 支持批量导入/或单条插入 | 支持单条或批量 |
数据操作 | 覆盖追加 | 行级更新删除 |
处理数据规模 | 大 | 小 |
执行速度 | 延迟高 | 延迟低 |
分区 | 支持 | 支持 |
数据加载模式 | 读取时快 | 写的时候慢 |
应用场景 | 海量查询 | 实时查询 |
hive的数据类型
数据类型 | 所占字节 |
---|---|
TINYINT | 1byte |
SMALLINT | 2bytes |
INT | 4bytes |
BIGINT | 8bytes |
BOOLEAN | |
FLOAT | 4bytes |
DOUBLE | 8bytes |
STRING | |
BINARY | |
TIMESTAMP | |
DECIMAL | |
CHAR | |
VARCHAR | |
DATE |
特有数据类型
数据类型 | 描述 | 语法实例 |
---|---|---|
STRUCT | 与c中的结构体很相似,可以用‘.’来访问元素里的内容。 | struct() |
MAP | MAP是一组键值对元组集合,表示数组表示法可以访问数据 | map() |
ARRAY | 数组是一组具有相同类型和名称的变量的集合,这些变量称为数组的元素,每个数组元素都有一个编号,编号从零开始 | Array() |
案例演示:
我有一个文件叫demo.txt
ShuoMei,marriana_lvan,age:23_sex:female, liaoning_jinzhou
在hive中创建表test
create table test(name string,
friend array<string> ,
info map<string,int>,
address struct<province:string,city:string>
)
# 列分隔符
row format delimited fields terminated by ','
collection items terminated by '_'
# map的key与value的分隔符
map keys terminated by ':'
# 行分隔符
lines terminated by '\n';
最后这几句各种terminated怎么解释呢?
我从头开始捋顺,行中每个字段是一‘,’作为分隔,类似容器一样的字段,它里面的items是以‘_’作为分隔符,map类型的字段键与值是以':'作为分隔符的。每行数据是以‘\n’(换行符)来分隔的。
那么我这个demo文件中这一行怎么划分呢
字段name, shuomei
字段friend, [marriana, lvan]
字段info, {'age': 23, 'sex:':'female'}
字段address, ...结构体不知怎么表示学过c的朋友应该理解结构体是什么,这里就不说了。
HIVE数据定义与操作
数据库相关
创建数据库
CREATE (DATABASE/SCHEMA) [IF NOT EXISTS] database_name
[COMMENT database_comment] -- 加备注
[LOCATION hdfs_path] -- 设定hdfs路径,如果不写就是默认地址
[WITH DBPROPERTIES
(property_name=property_value,...)] -- 加属性,一般我们不会去做;
案例演示
-- 创建一个tomato的数据库
create database if not exists tomato;
查看数据库信息
desc database extended 数据库名;
删除数据库(学了就忘记吧)
drop database if exists tomato;
drop database if exists tomato casade;强行删除数据库
修改数据库(不重要)
ALTER (DATABASE/SCHEMA) database_name set LOCATION hdfs_path;
数据表相关
创建数据表
create [external] table if not exists 表名
(列名 数据类型 [comment 本列注释], ...)
[comment 表注释]
[partitioned by (列名 数据类型 [comment 本列注释], ...)]
[clustered by (列名, 列名,...)]
[sorted by (列名[asc|desc], ...)] info num_buckets buckets]
[row format row_format]
[stored as file_format]
[location hdfs_path]
[tblproperties (property_name=property_value, ...)]
[as select_statement]
- external表示创建外部表,hive在创建内部表时,会将数据移到数据仓库指定的路径,若创建的时外部表,仅仅记录数据所在的路径,不对数据的位置做任何改变
- partitioned by 表示创建分区表
- clustered by 创建分桶表
- sorted by 不常用
- row format delimited [fields terminated by char]
[collection items terminated by char]
[map keys terminated by char][line terminated by char] - stored as 指定文件存储类型(sequencefile 二进制文件、textfile文件、rcfile列式存储格式)
- location 指定表在hdfs上的存储位置
- like允许用户复制现有的表结构,但不复制数据
- as后跟查询语句,根据查询结果创建表
查看数据表结构
desc formatted table_name;
内部表和外部表的区别
管理表有时也被称为内部表,因为这种表hive或多或少会控制数据额生命周期。当删除一个管理表时。hive也会删除这个表中的数据,管理表不方便与其他工作贡献数据。
建立外部表的重要点
- 用关键字external说明
- 指定外部表存放的数据的路径
- 如果不指定外部表的存放路径,hive将在HDFS上的/user/hive/warehouse 文件夹下以外部表名创建一个文件夹,并且输入这个表的数据都存在这里
- 当删除一个外部表时,只会删除表的元数据信息,而不会删除数据。
- 在生产中一般创建外部表来存储数据
元数据怎么理解?
我的理解就是数据库中删除了与外部文件的关联关系,删或不删,数据文件在那里,哈哈,不知理解了没。也许我说得不对,欢迎指正。
修改表
-- 修改表名
ALTER TABLE school_score RENAME TO s_score;
-- 向表中添加列
ALTER TABLE s_score ADD COLUMNS (st_name STRING COMMENT '学生姓名',
c_name STRING COMMENT '课程名称');
-- 修改列名
ALTER TABLE table_name change column_name new_column_name new_type;
删除表
drop table if exists table_name;
清空表
truncate table employee
分区表
hive中有分区表的概念,我们可以看到分区具有重要的性能优势,分区表可以将数据以一种符合逻辑的方式进行组织,比如分层存储
查询分区表中的数据时,除非where语句中包含分区字段过滤条件来显示数据范围,否则不允许执行。也就是说用户不允许扫描所有的分区。进行这个限制的原因是,通常分区表都拥有非常大的数据集,而且数据增加迅速,如果没有进行分区限制的查询会消耗很大的资源来处理这个表
分区表分别有静态分区和动态分区,那么他有什么区别呢?
静态分区与动态分区的主要区别在于静态分区是手动指定,而动态分区是通过数据来进行判断。静态分区的列是在编译时期,通过用户传递列名来决定的,动态分区是在sql执行的时候确定的。
-- 静态分区
create table test
(name string, age int)
partitioned by (country string)
row format delimited fields terminated by '\t'
lines terminated by '\n'
stored as textfile;
-- 向分区表中插入数据
insert into table test partition(country="china") values("lao wang", 1);
insert into table test partition(country="American") values("jamie lanister", 33);
insert into table test partition(country="American") values("sansa stock", 18);
-- 查询分区表的数据
select * from test where country="china";
alter table test drop partition(country="china");
-- 删除分区 删除分区就像删除一个文件夹,每个分区都是一个文件夹
alter table test drop partition(country="china")
-- 动态分区
set hive.exec.dynamic.partition=true; -- 可以通过这个语句查看:set hive.exec.dynamic.partition;
set hive.exec.max.dynamic.partitions=100000; -- 如果自动分区数大于这个参数将会报错
set hive.exec.max.dynamic.partitions.pernode=100000;
-- 显示分区数
show partitions order_part;
-- 查询分区表中的数据
select * from user_trade limit 6; -- 这样会报错,因为没加分区条件
-- 严格模式 严格模式是要跟where的,要严格指定分区。默认hive是非严格模式
set hive.mapred.mode=strict;
select * from user_trade limit 6;
select * from user_trade where dt='2017-01-12'
数据导入与导出(不重要)
-- 从本地导入到表中
load data local inpath '本地路径' overwrite into table 表名 [partition(partcol1=val1, ...)];
-- 从HDFS导入到表中
load data inpath 'HDFS上的路径' into table 表名 [partition(partcol1=val1, ...)];
-- 将hive表中的数据导出到本地
insert overwrite directory 'HDFS路径' 查询语句;
网友评论