红丝带网

Hive 核心原理(hive-3.1.2)

一、Hive 概述

1.1 Hive 是什么

由Facebook开源用于解决海量结构化日志的数据统计

基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射成一张表,并且提供类SQL的查询功能

Hive仅仅是一个工具,本身不存储数据只提供一种管理方式,同时也不涉及分布式概念,就是个软件而已

Hive本质就是MapReduce,将类SQL(HQL)转换成MapReduce程序

1.1.1 HQL转换MR流程


解释:

  1. Hive处理的数据存储在HDFS
  2. Hive分析数据底层默认实现是MapReduce[可以修改为spark]
Hive-on-MR is deprecated in Hive 2 and may not be available in the future versions. Consider using a different execution engine (i.e. spark, tez) or using Hive 1.X releases.
  1. 执行的程序运行在yarn上
  2. Hive相当于Hadoop的一个客户端
  3. Hive不是分布式

1.2 Hive 优缺点

1.2.1 优点

  1. 操作接口采用类SQL语法,提供快速开发的能力(简单、易上手)
  2. 避免去写MR,减少开发人员学习成本
  3. Hive的延迟比较高(因为MR延迟高),因此Hive常用于数据分析
  4. Hive优势在于处理大数据(数据量少真不如MySQL等)
  5. Hive支持用户自定义函数,可以根据自己的去求实现自己的函数

1.2.2 缺点

  1. Hive的HQL表达能力有限(MR决定的)迭代算法无法表达不适用于数据挖掘
  2. Hive的效率比较低Hive自动生成的MR作业,通常情况不够智能Hive调优难(只能对资源,SQL层面调优,无法深入作业底层逻辑)

1.3 Hive 架构原理

  1. 用户接口:Client

CLI(hive shell)、JDBC/ODBC(java访问hive)、WEBUI(浏览器访问hive)

  1. 元数据:Metastore

包括表名、表所属的数据库、表的拥有者、列/分区字段、表的类型、表数据所在的目录等(自带个derby数据库,推荐配置到MySQL)

  1. 底层存储:HDFS

使用HDFS进行存储,使用MapReduce计算

  1. 驱动器:Driver
  2. 解析器(SQL Parser):将SQL字符串转换成抽象语法树AST,并对语法树进行语法分析,如:SQL语法、表/字符是否存在
  3. 编译期(Physical Plan):将AST编译生成逻辑执行计划
  4. 优化器(Query Optimizer):对逻辑执行计划进行优化
  5. 执行器(Execution):把逻辑执行计算转换成运行的物理计划,即MR/Spark

Hive通过给用户提供的一系列交互接口,接受到用户编写的SQL,使用自己的Driver结合MetaStore,将SQL指令翻译成MapReduce提交到Hadoop中执行,将执行结果输出到用户交互接口。

1.4 Hive 和传统数据库比较

Hive除了提供类似SQL语法外和传统数据库没有任何相似之处,Hive是站在数据仓库出发点而设计的。

1.4.1 数据存储位置

Hive是建立在Hadoop之上,所有的Hive数据都是存储在HDFS上;传统数据库将数据保存在本地文件系统中;因此Hive能够处理更大更多的数据

1.4.2 数据更新

Hive是针对数据仓库应用设计,因此数据一次写入多次读出,即Hive中不建议对数据进行改写操作,所有数据都是在加载的时候确定好;对于数据库通常需要进行频繁的增删查改

1.4.3 索引

Hive在加载数据过程不会对数据进行任何处理,因为数据量庞大建立索引并不划算,因此Hive访问数据中满足特定值需要暴力扫描真个数据,因此访问延迟高。由于MapReduce的引入,Hive可以并行访问数据,即便没有索引也可用于大数据量的访问;传统数据库通常针对一个或多个列建立索引,因此在访问数据是延迟低效率高,即Hive不适合实时数据分析

1.4.4 执行

Hive 的执行引擎为MR/Spark,传统数据库都有自己的执行引擎

1.4.5 可拓展性

由于Hadoop的高拓展性,因此Hive也具备很强的拓展性;传统数据库的拓展会受到一定的限制

1.4.6 数据规模

Hive可以利用MapReduce进行大规模数据的并行计算;传统数据库支持的数据规模较小

二、Hive 初步

2.1 Hive 安装

参考:HIVE环境安装

将元数据配置到MySQL中需要初始化,初始化命令():

schematool -dbType mysql -initSchema

2.2 Hive 基本操作

  1. 启动hive
[root@master hive-3.2.1]# hive
  1. 查看数据库
hive (hive)> show databases;
OK
database_name
default
hive
Time taken: 0.02 seconds, Fetched: 2 row(s)

hive自带一个default数据库,默认也是进这个数据库

  1. 切换数据库
hive (hive)> use hive;
OK
Time taken: 0.031 seconds
  1. 创建表
hive (hive)> create table if not exists tbl_1(id int,name string);
OK
Time taken: 0.628 seconds

和MySQL语法基本一致,只是Hive的数据类型和Java类似

  1. 查看表结构
hive (hive)> desc dz_1;
OK
col_name        data_type       comment
id                      int
name                    string
Time taken: 0.084 seconds, Fetched: 2 row(s)
-------------------- 分隔符 -------------------
查看表的详细信息
hive (hive)> desc formatted dz_1;
OK
col_name        data_type       comment
col_name              data_type               comment
id                      int
name                    string

Detailed Table Information
Database:               hive
OwnerType:              USER
Owner:                  root
CreateTime:             Wed Aug 26 19:55:58 CST 2020
LastAccessTime:         UNKNOWN
Retention:              0
Location:               hdfs://master:9000/user/hive/warehouse/hive.db/dz_1
Table Type:             MANAGED_TABLE
Table Parameters:
        COLUMN_STATS_ACCURATE   {\"BASIC_STATS\":\"true\",\"COLUMN_STATS\":{\"id\":\"true\",\"name\":\"true\"}}
        bucketing_version       2
        numFiles                0
        numRows                 0
        rawDataSize             0
        totalSize               0
        transient_lastDdlTime   1598442958

Storage Information
SerDe Library:          org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe
InputFormat:            org.apache.hadoop.mapred.TextInputFormat
OutputFormat:           org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
Compressed:             No
Num Buckets:            -1
Bucket Columns:         []
Sort Columns:           []
Storage Desc Params:
        serialization.format    1
Time taken: 0.154 seconds, Fetched: 32 row(s)
  1. 插入数据(不要用,不要用,不要用)
hive (hive)> insert into dz_1 values(1,'北京');
...
...
...
Time taken: 84.754 seconds

谁用谁知道,巨慢

  1. 查询数据
hive (hive)> select * from dz_1;
OK
dz_1.id        dz_1.name
1       北京
Time taken: 0.214 seconds, Fetched: 1 row(s)
  1. 退出hive
hive (hive)> quit;
  1. 执行hdfs shell
hive (hive)> dfs -ls /;
Found 3 items
drwxr-xr-x   - root supergroup          0 2020-07-21 15:57 /HBase
drwx-wx-wx   - root supergroup          0 2020-07-21 18:27 /tmp
drwxrwxrwx   - root supergroup          0 2020-07-21 18:00 /user
  1. 执行linux shell
hive (hive)> !pwd;
/usr/local/soft/hive-3.2.1

2.3 Hive 常规操作

hive (hive)> insert into dz_1 values(1,'zhangsan');
...
...
...
Time taken: 84.754 seconds

插入一条数据84秒,显然不现实…为此Hive插入数据将采用最暴力最直接的方式,只需要将数据文件放到hdfs制定的路径即可。但也不是什么数据都可以,需要在创建表时指定分隔符。

hive (hive)> create table if not exists dz_2(id int,name string)
> row format delimited fields terminated by '\t';
OK
Time taken: 0.118 seconds

准备数据

[root@master data]# cat student.txt
1       张三
2       李四
3       王五
4       七七
5       八八
[root@master data]# pwd
/usr/local/soft/hive-3.2.1/data

2.3.1 hive 插入数据一

加载本地数据到hive

hive (hive)> load data local inpath '/usr/local/soft/hive-3.2.1/data/student.txt' into table tbl_2;
Loading data to table hive.tbl_2
OK
Time taken: 0.311 seconds

hive (hive)> select * from dz_2;
OK
dz_2.id        dz_2.name
1       张三
2       李四
3       王五
4       七七
5       八八
Time taken: 0.192 seconds, Fetched: 5 row(s)

2.3.2 hive 插入数据二

hive管理的数据是放在hdfs,可以再配置文件指定存储路径,可以进入指定路径查看,也可以通过desc formatted 表名看到该表的存储路径

  • hive在hdfs存储的根路径是在/…/warehouse/下
  • 一个数据库对应一个文件夹,命名方式为数据库名.db(默认数据库除外)
  • 每张表也对应一个文件夹,命名方式为表名
  • 数据文件直接放在表对应的文件夹下,因此通过load方式其实底层调用的是hadoop fs -put
  • 默认数据库下的表直接放在warehouse下命名方式不变

基于上述规律可以有第二种插入方式,直接通过hadoop的shell将文件put到指定的hdfs路径下即可

[root@master data]# hadoop fs -put student.txt /user/hive/warehouse/hive.db/dz_2/student_1.txt
hive (hive)> select * from dz_2;
OK
dz_2.id        dz_2.name
1       张三
2       李四
3       王五
4       七七
5       八八
Time taken: 0.396 seconds, Fetched: 10 row(s)

总结:也可以用,但是必须知道表在hdfs上的路径,所以这种方式需要提前知道路径,不是很方便了。

看过hive数据库、表、数据在hdfs上的存储结构后,尝试再次加载一次数据,这次通过load加载hdfs上的数据

hive (hive)> load data inpath '/student.txt' into table tbl_2;
Loading data to table hive.tbl_2
OK
Time taken: 0.683 seconds

load方式加载hdfs文件不需要加local(很显然),这时候再次查看hdfs信息,此时原数据将会被删除(其实就是hadoop fs -mv)

对于多次加载相同数据文件情况,hive会将数据文件重命名后上传到hdfs指定路径,重命名格式:原文件名_copy_n.txt;和windows下同名文件处理类似。


2.4 Hive 数据类型

2.4.1 基本数据类型

分类

类型

描述

字面量示例

原始类型

BOOLEAN

true/false

TRUE


TINYINT

1字节的有符号整数 -128~127

1Y


SMALLINT

2个字节的有符号整数,-32768~32767

1S


INT

4个字节的带符号整数

1


BIGINT

8字节带符号整数

1L


FLOAT

4字节单精度浮点数1.0



DOUBLE

8字节双精度浮点数

1


DEICIMAL

任意精度的带符号小数

1


STRING

字符串,变长

“a”,’b’


VARCHAR

变长字符串

“a”,’b’


CHAR

固定长度字符串

“a”,’b’


BINARY

字节数组

无法表示


TIMESTAMP

时间戳,纳秒精度

122327493795


DATE

日期

‘2016-03-29’

复杂类型

ARRAY

有序的的同类型的集合

array(1,2)


MAP

key-value,key必须为原始类型,value可以任意类型

map(‘a’,1,’b’,2)


STRUCT

字段集合,类型可以不同

struct(‘1’,1,1.0), named_stract(‘col1’,’1’,’col2’,1,’clo3’,1.0)


UNION

在有限取值范围内的一个值

create_union(1,’a’,63)

常用的基本数据类型有int、bigint、double、string且不区分大小写;boolean一般使用0/1代替以减少存储量;string使用最多,一般都是处理日志,理论上可以存储2G数据(一行)。

  1. 整数类型

类型

后缀

例子

TINYINT

Y

100Y

SMALLINT

S

100S

BIGINT

L

100L

Hive有4种带符号的整数类型:TINYINT,SMALLINT,INT,BIGINT,分别对应Java中的byte,short,int,long。字节长度分别为1,2,4,8字节。在使用整数字面量时,默认情况下为INT,如果要声明为其他类型,通过后缀来标识:

  1. 小数

浮点类型包括FLOAT和DOUBLE两种,对应到Java的float和double,分别为32位和64位浮点数。DECIMAL用于表示任意精度的小树,类似于Java的BigDecimal,通常在货币当中使用。例如DECIMAL(5,2)用于存储-999.99到999.99的数字,省略掉小数位,DECIAML(5)表示-99999到99999的数字。DECIMAL则等同于DECIMAL(10,0)。小数点左边允许的最大位数为38位。

  1. 文本类型

Hive有3种类型用于存储字文本。STRING存储变长的文本,对长度没有限制。理论上将STRING可以存储的大小为2GB,但是存储特别大的对象时效率可能受到影响,可以考虑使用Sqoop提供的大对象支持。VARCHAR与STRING类似,但是长度上只允许在1-65355之间。例如VARCHAR(100).CHAR则用固定长度来存储数据。

  1. 布尔及二进制

BOOLEAN表示二元的true或false。 BINARY用于存储变长的二进制数据。

  1. 时间类型

TIMESTAMP则存储纳秒级别的时间戳,同时Hive提供了一些内置函数用于在TIMESTAMP与Unix时间戳(秒)和字符串之间做转换。例如:


cast(date as date)
cast(timestamp as date)
cast(string as date)
cast(date as string)
  1. 类型转换

Hive支持类似java的数据类型转换

Hive的类型层次中,可以根据需要进行隐式的类型转换,例如TINYINT与INT相加,则会将TINYINT转化成INT然后INT做加法。隐式转换的规则大致可以归纳如下:

  • 任意数值类型都可以转换成更宽的数据类型(不会导致精度丢失)或者文本类型。
  • 所有的文本类型都可以隐式地转换成另一种文本类型。也可以被转换成DOUBLE或者DECIMAL,转换失败时抛出异常。
  • BOOLEAN不能做任何的类型转换。
  • 时间戳和日期可以隐式地转换成文本类型。

隐式转换

  • tinyint -> smalint -> int -> bigint -> float -> double
  • string类型只有是数字才可以转换
  • boolean不能转换成任意类型

强制类型转换

也可以使用CAST进行显式的类型转换,例如CAST('1' as INT),如果转换失败,CAST返回NULL。

hive (hive)> select cast('1' as int);
OK
_c0
1
Time taken: 0.937 seconds, Fetched: 1 row(s)
hive (hive)> select cast('a' as int);
OK
_c0
NULL
Time taken: 0.184 seconds, Fetched: 1 row(s)
  1. 复杂类型

Hive有4种复杂类型的数据结构:ARRAY,MAP,STRUCT,UNION。

数据类型

描述

语法实例

struct

结构体,复杂无关系数据

struct<k1:v,k2:v>

map

字典,键值对元组集合

map<k,v>

array

数组,同一类型集合

array<v>

struct和map区别在于map只能存储一组一组的k-v对,且一个map中的k不能相同,struct可以存储很对组相同key不同value的数据结构,即map中每组数据的key都不相同,struct中每组数据对应位置的key都是一样的;集合数据类型允许任意层次的嵌套。

  1. ARRAY和MAP

ARRAY和MAP类型与Java中的数据和映射表。数组的类型声明格式为ARRAY<data_type>,元素访问通过0开始的下标,例如arrays[1]访问第二个元素。 MAP通过MAP<primitive_type,data_type>来声明,key只能是基本类型,值可以是任意类型。map的元素访问则使用[],例如map['key1'].

  1. 4.2 STRUCT

STRUCT则封装一组有名字的字段(named filed),其类型可以是任意的基本类型,元素的访问使用点号。

  1. UNION

UNION则类似于C语言中的UNION结构,在给定的任何一个时间点,UNION类型可以保存指定数据类型中的任意一种。类型声明语法为UNIONTYPE<data_type,data_type,…>。每个UNION类型的值都通过一个整数来表示其类型,这个整数位声明时的索引,从0开始。例如:

CREATE TABLE union_test(foo UNIONTYPE<int,double,array<string>,strucy<a:int,b:string>>);

foo的一些取值如下:

{0:1}
{1:2.0}
{2:["three" , "four"]}
{3:["a":5,b:"five"]}
{0:9}

其中冒号左边的整数代表数据类型,必须在预先定义的范围类,通过0开始的下标表示。冒号右边是该类型的取值。

下面的这个CRATE语句用到了这4中复杂类型:

CREATE TABLE complex (
  c1 ARRAY<INT>,
  c2 MAP<STRING,INT>,
  c3 STRUCT<a:STRING,b:INT,c:DOUBLE>,
  c4 UNIONTYPE<STRING,INT>
);

通过下面的SELECT语句查询相应的数据:

SELECT c1[0] , c2['b'],c3.c , c4 FROM complex

结果类似:

1 2 1.0 {1:63}


2.4.4 测试集合数据类型

需要存储如下格式数据(json)

{
    "name": "董咚咚",
    "friends": ["张强强" , "杜天天"], //列表Array
    "children": {                    //键值Map
        "jasper": 3 ,
            "baby": 1 ,
     }
    "address": {                     //结构Struct
        "street": "北京后场场" ,
        "city": "北京"
     }
}
{
    "name": "马宁宁",
    "friends": ["过徐徐" , "孙骁骁"],                 
    "children": {                       
        "伊一": 8 ,
         "气球": 6 ,
     }
    "address": {                       
        "street": "后场村" ,
        "city": "北京"
     }
}

将一条数据转换成一行数据,去除没必要的数据,在一条数据中,字段之间用’,‘隔开,集合元素之间用’_‘隔开,map的kv用’:'隔开,因此可以转换成如下格式

董咚咚,张强强_杜天天,jasper:3_baby:1,北京后场场_北京
马宁宁,过徐徐_孙骁骁,伊一:8_气球:6,后场村_北京

针对上述数据创建如下表

hive (hive)> create table tbl_3(name string,friends array<string>,childress map<string,int>,address struct<street:string,city:string>)
           > row format delimited fields terminated by ','
           > collection items terminated by '_'
           > map keys terminated by ':';
OK
Time taken: 0.124 seconds

解释:


  • row format delimited fields terminated by ','设置字段分割符
  • collection items terminated by '_'设置集合元素分割符
  • map keys terminated by ':'设置map键值对分隔符
  • lines terminated by '\n'设置行分隔符,默认\n

导入数据测试

hive (hive)> load data local inpath '/usr/local/soft/hive-3.2.1/data/test_collection' into table tbl_3;
Loading data to table hive.tbl_3
OK
Time taken: 0.281 seconds
hive (hive)> select * from tbl_3;
OK
tbl_3.name      tbl_3.friends   tbl_3.childress tbl_3.address
董咚咚  ["张强强","杜天天"]     {"jasper":3,"baby":1}   {"street":"北京后场村","city":"北京"}
马宁宁    ["过徐徐","孙骁骁"]       {"伊一":8,"气球":6}     {"street":"后场村","city":"北京"}
Time taken: 0.176 seconds, Fetched: 2 row(s)
hive (hive)> select name,friends[0],childress['baby'],address.street from tbl_3;
OK
name    _c1     _c2     street
董咚咚  张强强  1       北京后场村
马宁宁  过徐徐 NULL    后场村
Time taken: 0.222 seconds, Fetched: 2 row(s)


三、DDL 数据定义语言

3.1 数据库操作

3.1.1 创建数据库

1.方式一

创建一个数据库,默认存储在hdfs中/user/hive/warehouse/*.db


hive (default)> create database test;
OK
Time taken: 0.827 seconds

若数据库已经存在会报Execution Error,推荐使用方法二

2.方式二

避免创建的数据库已经存在的错误,使用if not exists写法

hive (default)> create database if not exists hive;
OK
Time taken: 0.029 seconds

3.方式三

指定数据库在hdfs的存储位置

create database test location '/hive/test.db';
OK
Time taken: 0.097 seconds

3.1.2 查询数据库

1.显示数据库

显示数据库

hive (hive)> show databases;
OK
database_name
default
hive
Time taken: 0.03 seconds, Fetched: 2 row(s)

过滤显示查询的数据库

hive (hive)> show databases like 'h*';
OK
database_name
hive
Time taken: 0.022 seconds, Fetched: 1 row(s)

2.查看数据库详情

显示数据库信息

hive (hive)> desc database hive;
OK
db_name comment location        owner_name      owner_type      parameters
hive    hive test       hdfs://master:9000/user/hive/warehouse/hive.db  root    USER
Time taken: 0.049 seconds, Fetched: 1 row(s)

显示数据库详细信息

hive (hive)> desc database extended hive;
OK
db_name comment location        owner_name      owner_type      parameters
hive    hive test       hdfs://master:9000/user/hive/warehouse/hive.db  root    USER    {creator=wj}
Time taken: 0.03 seconds, Fetched: 1 row(s)

{creator=wj}为自定义属性,可作为注释使用

3.1.3 修改数据库

已经创建的数据库其信息都是不可以修改的,包括数据库名和数据库所在的目录位置等,这里修改数据库指的是修改数据库的dbproperties的键值对


hive (test)> alter database test set dbproperties('creator'='wj');
OK
Time taken: 0.234 seconds

3.1.4 删除数据库

1.删除空数据库

hive (hive)> drop database d1;
OK
Time taken: 0.435 seconds

2.强制删除数据库

对于非空数据库,上述命令无法删除

hive (d1)> drop database d1;
FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. InvalidOperationException(message:Database d1 is not empty. One or more tables exist.)

因此可以使用cascade进行强制删除

hive (d1)> drop database d1 cascade;
OK
Time taken: 0.231 seconds

3.2 表操作

3.2.1 创建表

标准语句

create [external] table [if not exists] table_name
[(col_name data_type [comment col_comment],...)]
[comment table_comment]
[partitioned by (col_name data_type [col_name data_type],...)]
[clustered by (col_name,col_name)]
[row format ...]
[collection items ...]
[map keys ...]
[location hdfs_path]

3.2.2 修改表

  1. 表的重命名
hive (hive)> alter table emp rename to dz_emp;
OK
Time taken: 0.215 seconds
hive (hive)> show tables;
OK
tab_name
score
student
dz_1
tbl_2
tbl_3
tbl_4
dz_emp
Time taken: 0.025 seconds, Fetched: 7 row(s)
  1. 添加列
hive (hive)> alter table dz_emp add columns(emp_id int);
OK
Time taken: 0.147 seconds
  1. 修改列

包括修改列名,列属性

hive (hive)> alter table dz_emp change emp_id c_emp_id string;
OK
Time taken: 0.234 seconds
  1. 替换列
hive (hive)> alter table dz_emp replace columns(s_id string,c_id string,c_grade string);
OK
Time taken: 0.157 seconds

3.2.3 删除表

hive (hive)> drop table dz_emp;
OK
Time taken: 0.227 seconds3.2.4 内/外部表

1.内部表

又称管理表(MANAGED_TABLE),因为对应的表叫外部表(EXTERNAL_TABLE)所以喜欢叫它外部表,创建表默认是内部表,删除表时元数据和hdfs内数据均会被删除

2.外部表

与内部表对立,删除外部表时仅删除元数据hdfs内的数据不会被删除,再次创建同名表数据会"恢复",即hive并非认为其完全拥有此表,创建外部表命令如下:

hive (hive)> create external table dz_5(id int,name string);
OK
Time taken: 0.183 seconds
hive (hive)> desc formatted dz_5;
OK
col_name        data_type       comment
col_name              data_type               comment
id                      int
name                    string

Detailed Table Information
Database:               hive
OwnerType:              USER
Owner:                  root
CreateTime:             Thu Aug 27 19:57:54 CST 2020
LastAccessTime:         UNKNOWN
Retention:              0
Location:               hdfs://master:9000/user/hive/warehouse/hive.db/dz_5
Table Type:             EXTERNAL_TABLE

3.内外部表转换

内部表 -> 外部表

hive (hive)> alter table dz_4 set tblproperties('EXTERNAL'='TRUE');
OK
Time taken: 0.13 seconds

外部表 -> 内部表


hive (hive)> alter table dz_4 set tblproperties('EXTERNAL'='FALSE');
OK
Time taken: 0.13 seconds


4.应用场景

在实际生产环境中,涉及到共享数据一定要使用外部表,防止误操作导致的数据丢失,对于个人使用,数据分析的中间表可以使用内部表,方便管理。


3.2.5 分区表

假设Hive的数仓存储了一年的数据,现在需要查找出某一天的数据,当使用where语句时,Hive会对该表(文件夹)下所有数据进行全表扫描,从而导致查询效率低;因此引入分区表概念来优化查询(有谓词下推的意思)


1.创建分区表

hive (hive)> create table tbl_6(id int,name string) partitioned by(month string) row format delimited fields terminated by '\t';
OK
Time taken: 0.106 seconds


在创建表语法后加partitioned by (col_name data_type)


2.导入数据

需要注意的是当创建的是分区表时加载数据需要添加上分区信息否则会保存(因为hive不知道要把数据put到哪个文件夹)


hive (hive)> load data local inpath '/usr/local/soft/hive-3.2.1/data/test_partition' into table tbl_6 partition(month='2020-08');
Loading data to table hive.tbl_6 partition (month='2020-08')
OK
Time taken: 0.782 seconds
hive (hive)> select * from tbl_6;
OK
tbl_6.id        tbl_6.name      tbl_6.month
1       tzhangsan       2020-08
2       tlisi   2020-08
3       twangwu 2020-08
Time taken: 0.141 seconds, Fetched: 3 row(s)


可以发现分区字段会自动加到表的数据中(原始数据文件不会被添加,hive自己做的处理,在读取数据的时候自动添加分区字段数据),添加多个分区后


hive (hive)> load data local inpath '/usr/local/soft/hive-3.2.1/data/test_partition' into table tbl_6 partition(month='2020-09');
Loading data to table hive.tbl_6 partition (month='2020-09')
OK
Time taken: 0.634 seconds;

因此分区的本质就是分文件夹,文件夹以分区名命名,不同分区的数据被放在不同文件夹下,这样的好处是当执行where查询时,hive会直接去指定的分区文件夹下扫描数据,效率将大幅提高。


3.操作分区

添加分区(本质就是创建文件夹)


hive (hive)> alter table tbl_6 add partition(month='2020-10');
OK
Time taken: 0.169 seconds


删除分区(本质就是删除文件夹)


hive (hive)> alter table tbl_6 drop partition(month='2020-10');
OK
Time taken: 0.269 seconds


创建二级分区


hive (hive)> create table tbl_6(id int,name string) partitioned by(month string,day string) 
row format delimited fields terminated by '\t';
OK
Time taken: 0.106 seconds


理论、操作都一样,多级分区上限没有限制(适可而止),结合上面知识,向分区表插入数据也可以直接put文件到指定路径


查看分区


hive (hive)> show partitions tbl_6;
OK
partition
month=2020-08
month=2020-09
month=2020-10
Time taken: 0.127 seconds, Fetched: 3 row(s)
赞 ()