Hive的基本操作和ACID

目录

一、Hive诞生的原因

二、Hive简介

三、Hive的服务(角色)

四、数据库与数据仓库的区别

 五、Hive SQL的基本操作

 六、插入数据到Hive

 七、Hive中数据的更新和删除


一、Hive诞生的原因

1. 方便对文件及数据的元数据进行管理,提供统一的元数据管理方式。

2. 提供更加简单的方式来访问大规模的数据集,使用SQL语言进行数据分析。

二、Hive简介

1. 数据仓库基本概念

数据仓库,英文名称为Data Warehouse,可简写为DW或DWH。数据仓库,是为企业所有级别的决策制定过程,提供所有类型数据支持的战略集合。它是单个数据存储,出于分析性报告和决策支持目的而创建。 为需要业务智能的企业,提供指导业务流程改进、监视时间、成本、质量以及控制。

下面这个图是很久以前注释的了,目前的生产上使用的hive大部分都是1.0以上的版本,后续画个新的架构和HQL编译原理图。

 

2. 数据处理分类:OLAP与OLTP

数据处理大致可以分成两大类:联机事务处理OLTP(on-line transaction processing)、联机分析处理OLAP(On-Line Analytical Processing)。OLTP是传统的关系型数据库的主要应用,主要是基本的、日常的事务处理,例如银行交易。OLAP是数据仓库系统的主要应用,支持复杂的分析操作,侧重决策支持,并且提供直观易懂的查询结果。

3. OLTP

OLTP,也叫联机事务处理(Online Transaction Processing),表示事务性非常高的系统,一般都是高可用的在线系统,以小的事务以及小的查询为主,评估其系统的时候,一般看其每秒执行的Transaction以及Execute SQL的数量。在这样的系统中,单个数据库每秒处理的Transaction往往超过几百个,或者是几千个,Select 语句的执行量每秒几千甚至几万个。典型的OLTP系统有电子商务系统、银行、证券等,如美国eBay的业务数据库,就是很典型的OLTP数据库。

4. OLAP

OLAP(On-Line Analysis Processing)在线分析处理是一种共享多维信息的快速分析技术;OLAP利用多维数据库技术使用户从不同角度观察数据;OLAP用于支持复杂的分析操作,侧重于对管理人员的决策支持,可以满足分析人员快速、灵活地进行大数据复量的复杂查询的要求,并且以一种直观、易懂的形式呈现查询结果,辅助决策。

5. 特点:

(1)快速性:用户对OLAP的快速反应能力有很高的要求。系统应能在5秒内对用户的大部分分析要求做出反 应。 ​

(2)可分析性:OLAP系统应能处理与应用有关的任何逻辑分析和统计分析。

(3)多维性:多维性是OLAP的关键属性。系统必须提供对数据的多维视图和分析,包括对层次维和多重层次 维的完全支持。 ​

(4)信息性:不论数据量有多大,也不管数据存储在何处,OLAP系统应能及时获得信息,并且管理大容量信 息。

三、Hive的服务(角色)

1、用户访问接口

CLI(Command Line Interface):用户可以使用Hive自带的命令行接口执行Hive QL、设置参数等功能。

JDBC/ODBC:用户可以使用JDBC或者ODBC的方式在代码中操作Hive。

Web GUI:浏览器接口,用户可以在浏览器中对Hive进行操作(2.2之后淘汰)。

2、Thrift Server:

Thrift服务运行客户端使用Java、C++、Ruby等多种语言,通过编程的方式远程访问Hive。

3、Driver

Hive Driver是Hive的核心,其中包含解释器、编译器、优化器等各个组件,完成从SQL语句到MapReduce任务的解析优化执行过程。

4、metastore

Hive的元数据存储服务,一般将数据存储在关系型数据库中,为了实现Hive元数据的持久化操作,Hive的安装包中自带了Derby内存数据库,但是在实际的生产环境中一般使用mysql来存储元数据。

四、数据库与数据仓库的区别

1、数据库是对业务系统的支撑,性能要求高,相应的时间短,而数据仓库则对响应时间没有太多的要求,当然也是越快越好。

2、数据库存储的是某一个产品线或者某个业务线的数据,数据仓库可以将多个数据源的数据经过统一的规则清洗之后进行集中统一管理。

3、数据库中存储的数据可以修改,无法保存各个历史时刻的数据,数据仓库可以保存各个时间点的数据,形成时间拉链表,可以对各个历史时刻的数据做分析。

4、数据库一次操作的数据量小,数据仓库操作的数据量大。

5、数据库使用的是实体-关系(E-R)模型,数据仓库使用的是星型模型或者雪花模型。

6、数据库是面向事务级别的操作,数据仓库是面向分析的操作。

                                                               Hive与传统关系型数据库(RDBMS)对比图:

 五、Hive SQL的基本操作

1、Hive基本操作

展示所有数据库:

show databases;

切换数据库:

use database_name;

创建数据库:

 CREATE (DATABASE|SCHEMA) [IF NOT EXISTS] database_name
      [COMMENT database_comment] 
      [LOCATION hdfs_path] 
      [WITH DBPROPERTIES (property_name=property_value, ...)];

create database database_name;

删除数据库:

DROP (DATABASE|SCHEMA) [IF EXISTS] database_name [RESTRICT|CASCADE];    

drop database database_name;

注意:当进入hive的命令行开始编写SQL语句的时候,如果没有任何相关的数据库操作,那么默认情况下,所有的表存在于default数据库,在hdfs上的展示形式是将此数据库的表保存在hive的默认路径下,如果创建了数据库,那么会在hive的默认路径下生成一个database_name.db的文件夹,此数据库的所有表会保存在database_name.db的目录下。

2、数据库表的基本操作

基本语法:

CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name    -- 			(Note: TEMPORARY available in Hive 0.14.0 and later)
  	[(col_name data_type [COMMENT col_comment], ... [constraint_specification])]
  	[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]
  	[SKEWED BY (col_name, col_name, ...)                  -- (Note: Available in Hive 			0.10.0 and later)]
    ON ((col_value, col_value, ...), (col_value, col_value, ...), ...)
    [STORED AS DIRECTORIES]
  	[
   		[ROW FORMAT row_format] 
   		[STORED AS file_format]
    	| STORED BY 'storage.handler.class.name' [WITH SERDEPROPERTIES (...)]  -- 				(Note: Available in Hive 0.6.0 and later)
  	]
  	[LOCATION hdfs_path]
  	[TBLPROPERTIES (property_name=property_value, ...)]   -- (Note: Available in Hive 			0.6.0 and later)
  	[AS select_statement];   -- (Note: Available in Hive 0.5.0 and later; not 					supported for external tables)
 
	CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name
  		LIKE existing_table_or_view_name
  	[LOCATION hdfs_path];

基本数据类型:

| TINYINT
| SMALLINT
| INT
| BIGINT
| BOOLEAN
| FLOAT
| DOUBLE
| DOUBLE PRECISION -- (Note: Available in Hive 2.2.0 and later)
| STRING
| BINARY      -- (Note: Available in Hive 0.8.0 and later)
| TIMESTAMP   -- (Note: Available in Hive 0.8.0 and later)
| DECIMAL     -- (Note: Available in Hive 0.11.0 and later)
| DECIMAL(precision, scale)  -- (Note: Available in Hive 0.13.0 and later)
| DATE        -- (Note: Available in Hive 0.12.0 and later)
| VARCHAR     -- (Note: Available in Hive 0.12.0 and later)
| CHAR        -- (Note: Available in Hive 0.13.0 and later)

复杂数据类型:

data_type
| array_type
| map_type
| struct_type
| union_type  -- (Note: Available in Hive 0.7.0 and later)

array_type
: ARRAY < data_type >
 
map_type
: MAP < primitive_type, data_type >
 
struct_type
: STRUCT < col_name : data_type [COMMENT col_comment], ...>
 
union_type
: UNIONTYPE < data_type, data_type, ... >  -- (Note: Available in Hive 0.7.0 and later)

行格式规范:

row_format
 	: DELIMITED [FIELDS TERMINATED BY char [ESCAPED BY char]] [COLLECTION ITEMS TERMINATED BY char]
 	[MAP KEYS TERMINATED BY char] [LINES TERMINATED BY char]
	[NULL DEFINED AS char]   -- (Note: Available in Hive 0.13 and later)
  	| SERDE serde_name [WITH SERDEPROPERTIES (property_name=property_value, property_name=property_value, ...)]

 文件基本类型:

file_format:
  : SEQUENCEFILE
  | TEXTFILE    -- (Default, depending on hive.default.fileformat configuration)
  | RCFILE      -- (Note: Available in Hive 0.6.0 and later)
  | ORC         -- (Note: Available in Hive 0.11.0 and later)
  | PARQUET     -- (Note: Available in Hive 0.13.0 and later)
  | AVRO        -- (Note: Available in Hive 0.14.0 and later)
  | JSONFILE    -- (Note: Available in Hive 4.0.0 and later)
  | INPUTFORMAT input_format_classname OUTPUTFORMAT output_format_classname

 表约束:

constraint_specification:
 		 : [, PRIMARY KEY (col_name, ...) DISABLE NOVALIDATE ]
 		   [, CONSTRAINT constraint_name FOREIGN KEY (col_name, ...) REFERENCES 					table_name(col_name, ...) DISABLE NOVALIDATE

3.Hive表创建

(1) 创建hive普通表(不包含行定义格式):

CREATE TABLE `test`(                              
  `sku` int,                                     
  `currency` string,                             
  `price` decimal(10,2),                                           
  `review_total` int,                            
  `review_score` decimal(10,2),                  
  `collection` string)                           
PARTITIONED BY (                                 
  `create_time` string)                          
ROW FORMAT SERDE                                 
  'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
STORED AS INPUTFORMAT                             
  'org.apache.hadoop.mapred.TextInputFormat'      
OUTPUTFORMAT                                      
  'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION                                           
  'hdfs://cdh-001:8020/home/data/user/hive/warehouse/data.db/test' 
TBLPROPERTIES (                                    
  'transient_lastDdlTime'='1586239332');
//需要创建的表的字段信息,类型于mysql
//与hdfs文件的映射路径,即hive表展示数据的实际存储位置,hive本身指存储元数据,即真实数据的地址
//最后更改表的用户,更改时间等,这段信息hive会自己创建

(2) 创建自定义行格式的hive表:

create table test2
(
id int,
name string,
hobby array<string>,
address map<string,string>
)
row format delimited
fields terminated by ','
collection items terminated by '-'
map keys terminated by ':';

(3) 创建默认分隔符的hive表:

create table test3
(
id int,
name string,
hobby array<string>,
address map<string,string>
)
row format delimited
fields terminated by '\001'
collection items terminated by '\002'
map keys terminated by '\003';
--或者
create table test3
(
id int,
name string,
hobby array<string>,
address map<string,string>
);

(4) 创建hive的外部表(需要添加external和location关键字):

create external table test4
(
id int,
name string,
hobby array<string>,
address map<string,string>
)
row format delimited
fields terminated by ','
collection items terminated by '-'
map keys terminated by ':'
location '/data';

内部表跟外部表的区别:
      1、hive内部表创建的时候数据存储在hive的默认存储目录中,外部表在创建的时候需要制定额外的目录。
      2、hive内部表删除的时候,会将元数据和数据都删除,而外部表只会删除元数据,不会删除数据。

应用场景:
      内部表:需要先创建表,然后向表中添加数据,适合做中间表的存储
      外部表:可以先创建表,再添加数据,也可以先有数据,再创建表,本质上是将hdfs的某一个目录的数据跟hive的表关联映射起来,因此适合原始数据的存储,不会因为误操作将数据给删除掉。

 (5) 创建单分区表

create table test5
(
id int,
name string,
hobby array<string>,
address map<string,string>
)
partitioned by(gender string)
row format delimited
fields terminated by ','
collection items terminated by '-'
map keys terminated by ':';

(6) 创建多分区表

create table test6
(
id int,
name string,
hobby array<string>,
address map<string,string>
)
partitioned by(gender string,age int)
row format delimited
fields terminated by ','
collection items terminated by '-'
map keys terminated by ':';	

当创建完分区表之后,在保存数据的时候,会在hdfs目录中看到分区列会成为一个目录,以多级目录的形式存在。
当创建多分区表之后,插入数据的时候不可以只添加一个分区列,需要将所有的分区列都添加值。
多分区表在添加分区列的值得时候,与顺序无关,与分区表的分区列的名称相关,按照名称就行匹配。

 给分区表添加分区列的值:

alter table table_name add partition(col_name=col_value);

 删除分区列的值:

alter table table_name drop partition(col_name=col_value);

添加分区列的值的时候,如果定义的是多分区表,那么必须给所有的分区列都赋值。
删除分区列的值的时候,无论是单分区表还是多分区表,都可以将指定的分区进行删除。

 (7) 分区修复
        在使用hive外部表的时候,可以先将数据上传到hdfs的某一个目录中,然后再创建外部表建立映射关系,如果在上传数据的时候,参考分区表的形式也创建了多级目录,那么此时创建完表之后,是查询不到数据的,原因是分区的元数据没有保存在mysql中,因此需要修复分区,将元数据同步更新到mysql中,此时才可以查询到元数据。具体操作如下:

//在hdfs创建目录并上传文件
hdfs dfs -mkdir /msb
hdfs dfs -mkdir /msb/age=10
hdfs dfs -mkdir /msb/age=20
hdfs dfs -put /root/data/data /msb/age=10
hdfs dfs -put /root/data/data /msb/age=20
//创建外部表
create external table test
(
id int,
name string,
hobby array<string>,
address map<string,string>
)
partitioned by(age int)
row format delimited
fields terminated by ','
collection items terminated by '-'
map keys terminated by ':'
location '/msb';
//查询结果(没有数据)
select * from test;
//修复分区
msck repair table test;
//查询结果(有数据)
select * from test;

 六、插入数据到Hive

1. 导入数据文件到hive表

//加载本地数据到hive表
load data local inpath '/root/data/data' into table test;   --(/root/data/data指的是本地linux目录)
//加载hdfs数据文件到hive表
load data inpath '/data/data' into table test;   --(/data/data指的是hdfs的目录)

注意:
1、load操作不会对数据做任何的转换修改操作
2、从本地linux load数据文件是复制文件的过程
3、从hdfs load数据文件是移动文件的过程
4、load操作也支持向分区表中load数据,只不过需要添加分区列的值

2. 从查询语句中获取数据插入hive表

//注意:这种方式插入数据的时候需要预先创建好结果表
//从表中查询数据插入结果表
INSERT OVERWRITE TABLE test0 SELECT id,name FROM test1;
//从表中获取部分列插入到新表中
from test
insert overwrite table test2
select id,name 
insert into table test3
select id;

 3. 将查询到的结果插入到文件系统中

//注意:路径千万不要填写根目录,会把所有的数据文件都覆盖
//将查询到的结果导入到hdfs文件系统中
insert overwrite directory '/result' select * from test;
//将查询的结果导入到本地文件系统中
insert overwrite local directory '/result' select * from test;

 4. 使用传统关系型数据库的方式插入数据,效率较低

insert into test values(1,'zhangsan');

 七、Hive中数据的更新和删除

在官网中我们可以看到看到hive0.14以上的版本中是支持Update和Delete操作的,但是实际上,是需要事务的支持的,Hive对于事务的支持有很多的限制(官网中有说明)。因此,在使用hive的过程中,我们一般不会进行Update和Delete的操作,而且对数据进行删除和更新本身也违背了数据仓库的初衷。

但如果你确实需要有这样的操作的话,且使用的是CDH平台,通过Cloudera Manager管理,可以参考我在 hive-site.xml 的 Hive 客户端高级配置代码段(安全阀)中添加的配置,而且Hive表的数据在hdfs中存储的格式必须是ORC格式,因为目前只有ORCFileformat支持AcidOutputFormat,不仅如此,建表时必须指定参数('transactional' = true),才能支持删除和更新。

建表语句案例:

CREATE TABLE `test`(               
   `sku` int,                                      
   `currency` string,                              
   `price` decimal(10,2),                                              
   `review_total` int,                             
   `review_score` decimal(10,2),                   
   `collection` string)                            
 PARTITIONED BY (                                  
   `create_time` string)      //分区                     
 CLUSTERED BY (                                    
   sku)                                            
 INTO 10 BUCKETS              //分桶                     
 ROW FORMAT SERDE                                  
   'org.apache.hadoop.hive.ql.io.orc.OrcSerde' //必须为orc格式    
 STORED AS INPUTFORMAT                             
   'org.apache.hadoop.hive.ql.io.orc.OrcInputFormat'  //必须为orc格式
 OUTPUTFORMAT                                       
   'org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat'
 LOCATION                                           
   'hdfs://cdh-001:8020/home/data/user/hive/warehouse/data.db/test'
 TBLPROPERTIES (                                    
   'last_modified_by'='root',                       
   'last_modified_time'='1568971585',               
   'transactional'='true',    // 这里必须为true                       
   'transient_lastDdlTime'='1568971585')

我在Cloudera Manager中 hive-site.xml 的 Hive 客户端高级配置代码段 (安全阀)添加的配置:

<property>
    <name>hive.support.concurrency</name>
    <value>true</value>
    <final>true</final>
    <description>开启hive锁表</description>
</property>
<property>
    <name>hive.exec.dynamic.partition.mode</name>
    <value>nonstrict</value>
    <final>true</final>
    <description>开启动态分区</description>
</property>
<property>
    <name>hive.txn.manager</name>
    <value>org.apache.hadoop.hive.ql.lockmgr.DbTxnManager</value>
    <final>true</final>
    <description>支持事务和数据并发</description>
</property>
<property>
    <name>hive.compactor.initiator.on</name>
    <value>true</value>
    <final>true</final>
    <description>仅适用于Thrift Metastore服务的一个实例</description>
</property>
<property>
    <name>hive.compactor.worker.threads</name>
    <value>1</value>
    <final>true</final>
    <description>Thrift Metastore服务中至少一个实例的正数</description>
</property>
<property>
    <name>hive.enforce.bucketing</name>
    <value>true</value>
    <final>true</final>
</property>
<!--以上的6个配置是必须添加的,下面的是我自己的,可以根据你自身需求确定是否添加-->

<property>
    <name>hive.lock.sleep.between.retries</name>
    <value>10</value>
    <final>true</final>
</property>
<property>
    <name>hive.fetch.task.conversion</name>
    <value>none</value>
    <final>true</final>
</property>
<property>
    <name>hive.cli.pretty.output.num.cols</name>
    <value>-1</value>
    <final>true</final>
    <description>格式化描述很多的表语句生成时要使用的列数,如果该值为-1,则hive将使用自动检测的最终宽度</description>
</property>
<property>
    <name>hive.cli.print.header</name>
    <value>true</value>
    <final>true</final>
    <description>print headers</description>
</property>
<property>
    <name>hive.exec.parallel</name>
    <value>true</value>
    <description>Hive群集并行计算</description>
</property>

未完待续 . . . . . .

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章