HDFS的Shell命令

HDFS就是分布式文件系统,可以用一些命令来操作这个分布式文件系统上的文件。

  • 访问HDFS的命令:

    hadoop dfs —- 已过时

    hdfs dfs

  • 小技巧

    1. 在命令行中输入hdfs回车,会提示hdfs后可以用哪些命令,其中就有dfs。
    2. 在命令行中输入dfs回车,会提示dfs后可以用哪些命令。
  • 注意事项

    分布式文件系统的路径在命令行中,要从/开始写,即绝对路径。

1.创建目录

1
2
3
4
5
6
[mkdir [-p] <path> ...] # 创建目录,-p:多层级创建

格式:hdfs dfs -mkdir (-p) /目录
例如:
- hdfs dfs -mkdir /data
- hdfs dfs -mkdir -p /data/a/b/c

2.上传指令

1
2
3
4
5
6
7
8
9
10
11
[-put [-f] [-p] <localsrc> ... <dst>] # 将本地文件上传到分布式文件系统

格式:hdfs dfs -put /本地文件 /分布式文件系统路径
注意:直接写/是省略了文件系统的名称hdfs://ip:port。
例如:
- hdfs dfs -put /root/a.txt /data/
- hdfs dfs -put /root/logs/* /data/

其它指令:功能同上
[-moveFromLocal <localsrc> ... <dst>]
[-copyFromLocal [-f] [-p] [-l] <localsrc> ... <dst>]

3.创建空文件

1
2
hdfs dfs [generic options] -touchz <path> ...
格式:hdfs dfs -touchz /text.txt

4.向文件追加内容

1
2
3
[-appendToFile <localsrc> ... <dst>]
格式:hdfs dfs -appendToFile 本地文件 hdfs上的文件
注意:不支持在中间随意增删改操作

5.查看指令

1
2
3
4
5
6
7
8
9
[-ls [-d] [-h] [-R] [<path> ...]] 
格式:hdfs dfs -ls /

[-cat [-ignoreCrc] <src> ...]
格式:hdfs dfs -cat /xxx.txt

[-tail [-f] <file>]
格式:hdfs dfs -cat /xxx.txt
注意:默认最多查看1000行

6.下载指令

1
2
3
4
5
6
7
8
[-copyToLocal [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
注意:本地路径文件夹可以不存在

[-moveToLocal <src> <localdst>]
注意:从hdfs的某个路径将数据剪切到本地,已经被遗弃了

[-get [-p] [ignoreCrc] [-crc] <src> ... <localdst>]
格式:同copyToLocal

7.合并下载

1
2
3
hdfs dfs [generic options] -getmerge [-nl] <src> <localdst>
格式:hdfs dfs -getmerge hdfs上的路径 本地路径
实例:hdfs dfs -getmerge /data/*.xml /root/test.txt

8.移动hdfs中的文件(更名)

1
2
3
hdfs dfs [generic options] -mv <src> ... <dst>
格式:hdfs dfs -mv /hdfs路径 /hdfs另一个路径
实例 hdfs dfs -mv /aaa /bbb # 这里是将aaa整体移到bbb中

9.复制hdfs中的文件(更名)

1
2
hdfs dfs [generic options] -cp [-f] [-p | -p[topax]] <src> ... <dst>
格式:hdfs dfs -cp /hdfs路径1 /hdfs路径2

10.删除命令

1
2
3
4
5
[-rm [-f] [-r|-R] [-skipTrash] <src> ...]
注意:如果删除的是文件夹需加-r

[-rmdir [--ignore-fail-on-non-empty] <dir> ...]
注意:必须是空文件夹,非空则使用rm删除

11.查看磁盘利用率和文件大小

1
2
[-df [-h] [<path> ...]] # 查看分布式系统磁盘使用情况
[-du [-s] [-h] <path> ...] # 查看分布式系统上路径下文件的情况

12.修改权限

1
2
3
4
5
# 跟本地操作一致,-R是让子目录或文件也进行相应的修改
[-chgrp [-R] GROUP PATH...]
[-chmod [-R] <MODE[,MODE]... | OCTALMODE> PATH...]
格式:hdfs dfs -chmod 777 /data
[-chmod [-R] [OWNER][:[GROUP]] PATH...]

13.修改文件的副本数

1
2
[-setrep [-R] [-w] <rep> <path> ...]
格式:hadoop fs -setrep 3 / # 将hdfs根目录及子目录下的内容设置成三个副本

14.查看文件状态

1
2
3
4
5
6
7
8
9
10
11
12
hdfs dfs [generic options] -stat [format] <path> ...

作用:当向hdfs上写文件时,通过dfs.blocksize配置项来设置block的大小,这就导致了hdfs上的不同文件block大小不同。有时候想知道hdfs上某个文件的block大小,可以预估计算的task个数。stat意义:可以查看文件的一些属性。
格式:hdfs dfs -stat [format] 文件路径
format形式:
# %b:打印文件的大小(目录大小为0)
# %n:打印文件名
# %o:打印block的size
# %r:打印副本数
# %y:utc时间 yyyy-MM-dd HH:mm:ss
# %Y:打印自1970年1月1日以来的utc微秒数
# %F:目录打印directory,文件打印regular file

15.测试

1
2
3
4
5
6
7
8
hdfs dfs [generic options] -test -[defsz] <path>
参数说明:
# -e:文件是否存在 存在返回0
# -z:文件是否为空 为空返回0
# -d:是否是路径(目录),是返回0
格式:hdfs dfs -test -d 文件 # 单纯这一行控制台不会打印结果
实例:hdfs dfs -test -d /data/1.txt && echo "OK" || echo "NO"
解释:测试当前的内容是否是文件夹,是返回ok,不是返回no

Hive的安装部署

一、内嵌模式

使用hive自带默认元数据库derby来进行存储,通常用于测试

  • 优点:使用简单,不用进行配置
  • 缺点:只支持单session

安装步骤:(在Slave1中安装)

1)解压hive并配置环境变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@Master software]# tar -zxvf apache-hive-3.1.2-bin.tar.gz -C /opt/module
# 修改hive安装后的名称,方便后面使用
[root@Master module]# mv apache-hive-3.1.2-bin/ hive

# 或者直接vim /etc/profile 同样可以配置环境变量
[root@Master module]# cd /etc/profile.d
[root@Master profile.d]# vim my_env.sh
# 添加如下内容:
# HIVE_HOME
export HIVE_HOME=/opt/module/hive
export PATH=$HIVE_HOME/bin:$PATH

# 让profile生效
[root@Master profile.d]# source /etc/profile

2)配置hive-env.sh

如果不存在,就在hive-env.sh.template复制一个

image-20220610234807805

1
2
3
4
5
6
7
8
[root@Slave1 conf]# cp hive-env.sh.template hive-env.sh

# 之后vim hive-env.sh
# 添加环境变量
export JAVA_HOME=/opt/module/jdk1.8.0_231
export HADOOP_HOME=/opt/module/hadoop-3.1.3
export HIVE_CONF_DIR=/opt/module/hive/conf
export HIVE_AUX_JARS_PATH=/opt/module/hive/lib

3)配置hive-site.xml

如果没有可以把conf/hive-default.xml.template拷贝起来用

1
2
3
4
[root@Slave1 conf]# cp hive-default.xml.template hive-site.xml

# 把hive-site.xml所有包含${system:java.io.tmpdir}替换成/opt/module/hive/iotmp
# 如果系统默认没有指定系统用户名,需要把${system:user.name}替换成当前用户名root

第二张图片忘记在#后面加$符,后面记得自己加上。

image-20220611000545186

image-20220611000557579

image-20220611000622019

扩展:hive-site.xml中有两个重要的配置说明

1
2
3
4
5
6
7
8
9
10
11
12
<!--该参数主要指定Hive的数据存储目录-->
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive/warehouse</value>
<description>location of default database for the warehouse</description>
</property>
<!--该参数主要指定Hive的临时文件存储目录-->
<property>
<name>hive.exec.scratchdir</name>
<value>/tmp/hive</value>
<description>HDFS root scratch dir for Hive jobs which gets created with write all (733) permission. For each connecting user, an HDFS scratch dir: ${hive.exec.scratchdir}/&lt;username&gt; is created, with ${hive.scratch.dir.permission}.</description>
</property>

在linux中新建上面两个目录,并且进行权限赋值(可选操作,hive会自动创建)

1
2
3
4
[root@Slave1 hive]# hdfs dfs -mkdir -p /user/hive/warehouse
[root@Slave1 hive]# hdfs dfs -mkdir -p /tmp/hive/
[root@Slave1 hive]# hdfs dfs -chmod 750 /user/hive/warehouse
[root@Slave1 hive]# hdfs dfs -chmod 777 /tmp/hive/

4)启动hadoop集群

5)初始化hive

1
[root@Slave1 ~]# schematool --initSchema -dbType  derby

报错

  • Illegal character entity: expansion character

    image-20220611002926555

    错误在第3215行,vim hive-site.xml +3215

    image-20220611003046143

    将标注的三个字符删掉

6)启动hive

注:启动之前要先启动hadoop集群,且需要在初始化的路径上启动hive

hive

1
2
3
# 进入之后可以执行下面操作
hive> show databases; # 查看数据库
hive> show tables; # 查看表

二、本地模式

使用mysql替换derby进行元数据的存储,hive的相关进程都是在同一台机器上,及本地模式,mysql因为是独立的进程,所以mysql可以和hive在同一台机器上,也可以在其它机器上。

说明:

通常使用关系型数据库来进行元数据的存储(mysql、oracle等着执行待jdbc驱动的数据库)

  • 优点:支持多session
  • 缺点:需要配置、还需要安装mysql等关系型数据库

配置安装mysql(在Slave2安装)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# 环境准备
# centos7中,系统默认采用的数据库是mariadb,这个数据库与mysql冲突!
# 因此,在安装mysql之前,需要先将其卸载!

[root@Slave2 ~]# rpm -qa | grep mariadb # 查询是否安装了mariadb

# 强制卸载mariadb
# --nodeps:强制卸载,rpm卸载程序的时候,如果这个程序被其他程序依赖,是无法卸载的。
# 此时,就需要使用--nodeps,忽略依赖,强制卸载
# 下面的卸载命令中,卸载的包是上方查询到的包
[root@Slave2 ~]# rpm -e mariadb-libs-5.5.64-1.el7.x86_64 --nodeps

[root@Slave2 ~]# rpm -qa | grep mysql # 查询是否安装了mysql
# 安装mysql
# 执行 【tar -xvf 解压对应的mysql压缩包】,就会得到以下依赖包
# 安装mysql,其实就是需要安装 mysql-community-server,但是它依赖其它包
[root@Slave2 ~]# rpm -ivh mysql-community-common-5.7.28-1.el7.x86_64.rpm
[root@Slave2 ~]# rpm -ivh mysql-community-libs-5.7.28-1.el7.x86_64.rpm
[root@Slave2 ~]# rpm -ivh mysql-community-client-5.7.28-1.el7.x86_64.rpm
[root@Slave2 ~]# yum install -y net-tools
[root@Slave2 ~]# rpm -ivh mysql-community-server-5.7.28-1.el7.x86_64. rpm

# 开启mysql服务
# 查看mysql服务的运行状态
[root@Slave2 ~]# systemctl status mysqld
# 如果没有开启则开启
[root@Slave2 ~]# systemctl start mysqld

# 登录到mysql
# 在第一次开启mysql服务的时候,会自动生成一个随机的密码
[root@Slave2 ~]# grep password /var/log/mysqld.log
2022-05-12T14:01:44.512146Z 1 [Note] A temporary password is generated for root@localhost: aK8n4AQuV:J;
# 使用这个随机密码登录到mysql
[root@Slave2 ~]# mysql -u root -p

# 修改mysql的安全等级
# 1.修改mysql的密码策略(安全等级)
# mysql默认的密码安全等级有点高,在设置密码的时候,必须同时包含大小写字母、数字、特殊字符,以及对位数有要求
show variables like '%validate_password%'; # 查看密码策略
set global validate_password_policy=LOW; # 修改密码策略等级为LOW
set global validate_password_length=4; # 密码的最小长度
set global validate_password_mixed_case_count=0; # 至少要包含0个大写字母和小写字母
set global validate_password_number_count=0; # 至少要包含0个数字
set global validate_password_special_char_count=0; # 至少要包含0个特殊字符

#2.修改密码
alter user root@localhost identified by '123456';

#3.远程授权
grant all privileges on *.* to 'root'@'%' identified by '123456' with grant option;

配置hive环境变量(在Slave1中操作)

1
2
3
[root@Slave1 ~]# cd /opt/module/hive
[root@Slave1 hive]# cd conf
[root@Slave1 conf]# vim hive-site.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!--配置mysql的连接字符串-->
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://Slave2:3306/hive?createDatabaseIfNotExist=true</value>
<description>
JDBC connect string for a JDBC metastore.
To use SSL to encrypt/authenticate the connection, provide database-specific SSL flag in the connection URL.
For example, jdbc:postgresql://myhost/db?ssl=true for postgres database.
</description>
</property>
<!--配置mysql的连接驱动-->
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
<description>Driver class name for a JDBC metastore</description>
</property>
<!--配置登录mysql的用户-->
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
<description>Username to use against metastore database</description>
</property>

<!--配置登录mysql的密码-->
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>root</value>
<description>password to use against metastore database</description>
</property>

注意:hive的元数据在mysql库里创建的数据库hive的编码最好设置成latin1

1
show variables like 'character%';

将mysql的驱动包mysql-connector-java-5.1.37-bin.jar上传到$HIVE_HOME/lib下(注意驱动时jar结尾的,不是tar)

初始化数据库

1
[root@Slave1 lib]# schematool --initSchema -dbType mysql

启动hive

注意:这时候在Slave1的任何目录下输入hive都可以启动hive

hive

三、远程模式

1)服务端配置

修改hive-site.xml

内嵌模式以及本地模式的时候已经改完了

说明:使用远程模式,需要在hadoop的core-site.xml文件中添加以下属性
1
2
3
4
5
6
7
8
<property>
<name>hadoop.proxyuser.root.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.root.groups</name>
<value>*</value>
</property>
1
2
[root@Master hadoop]# vim core-site.xml
[root@Master hadoop]# xsync core-site.xml

分发完记得重启集群

2)hive的两种服务说明

第一种服务:hiveserver2

1
2
3
4
5
6
1. 该服务端口号默认是10000
2. 可以单独启动此服务进程,供远程客户端连接;此服务内置metastore服务。
3. 启动方式:
方法一:直接调用hiveserver2,会进入监听状态不退出。
方法二:hive --service hiveserver2 & 进入后台启动
方法三:hive --service hiveserver2 >/dev/null 2>&1 &; 信息送入黑洞

第二种服务:metastore

1
2
3
4
5
1. 此服务才是真正连接元数据库的服务进程
2. 也可以让远程客户端连接
3. 启动方式:
方法一:hive --service metastore &
方法二:hive --service metastore 2>&1 >/dev/null &; 信息送入黑洞

3)客户端连接hiveserver2服务

  • 先在Master解压hive并配置环境变量(内嵌模式第一步),无需再修改配置文件。

  • 在Slave1执行hive --service hiveserver2 &,之后jpsRunJar进程代表启动了。

连接方式:

1
2
3
4
5
6
7
8
9
10
11
# 以下命令在Master执行
方式一:
beeline 回车
!connect jdbc:hive2://Slave1:10000 回车
输入用户名 回车
输入密码 回车
方法二(直连):
beeline -u jdbc:hive2://Slave1:10000 -n 用户名

解析
hive2 是hive的协议名称

4)客户端连接metastore服务

想要连接metastore服务的客户端必须配置如下属性和属性值

1
2
3
4
<property>
<name>hive.metastore.uris</name>
<value>thrift://Slave1:9083</value>
</property>

注意:如果之前Slave1有开启hiveserver2服务,需先停止。

1
2
3
4
5
6
7
[root@Slave1 ~]# jps
7113 Jps
922 ResourceManager
1083 NodeManager
3676 RunJar
717 DataNode
[root@Slave1 ~]# kill -9 3676

在Slave1执行hive --service metastore &,之后jpsRunJar进程代表启动了。

回到Master配置

1
2
[root@Master ~]# cd $HIVE_HOME/conf
[root@Master conf]# cp hive-default.xml.template hive-site.xml

将hive-site.xml原本的配置都删掉替换成上面的配置

image-20220611153005378

之后Master直接执行hive就行

Hive的基本操作

一、语法规则

大小写规则

1
2
1. hive的数据库名、表名都不区分大小写
2. 建议关键字大写

命名规则

1
2
3
1. 名字不能使用数字开头
2. 不能使用关键字
3. 尽量不适用特殊符号

二、库操作语法

1)创建数据库

创建数据库的本质就是在hive的参数${hive.metastore.warehouse.dir}对应的目录下,创建一个新的目录,此目录命名为:库名.db

注意:在创建库或者表时除了创建目录外,还会在mysql中(元数据库),添加元数据(描述信息)

1
2
3
hive> create database test1; 
hive> create database test1 if not exists test1; 之前存在就不创建
hive> create database test1 if not exists test1 comment 'this is a database of test1'; 添加描述

hive有一个默认的数据库default,如果不明确说明要使用哪个库,则使用默认库。

2)查看所有数据库

1
hive> show database;

3)切换数据库

1
hive> use mydb;

4)查看数据库信息

1
2
3
hive> desc database dbName;  
hive> desc database extended dbName;
hive> describe database dbName;

5)删除数据库

1
2
hive> drop database dbName;  只能删除空库
hive> drop database dbName cascade;

6)查看当前使用的库

1
hive> select current_database();

三、表操作语法

1)创建表

本质就是在对应的数据库目录下创建一个子目录,目录名为表名。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
语法1:默认创建在当前使用的库
create table t_user(id int,name string);
语法2:使用库.表形式
create table mydb.t_user(id int,name string);
语法3:指定分隔规则形式
create table if not exists t_user(
name string comment 'this is a name',
chinese int,
math int,
english int
)
comment 'this is my table'
row format delimited
fields terminated by '\t' 字段之间以什么做分隔
lines terminated by '\n' 行与行之间以什么做分隔
stored as textfile; 文件在hdfs上以什么形式存储

2)查看表

1
2
hive> show tables;
hive> show tables in mydb; 可以指定查看某库里的表

3)查看表结构

1
2
3
hive> desc tableName;
hive> desc extended tableName;
hive> describe extended tableName;

4)修改表结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- 修改表名
alter table oldTableName rename to newTableName;
- 修改列名
alter table tableName change column oldName newName colType;
alter table tableName change column colName colName colType;
- 修改列的位置:注意2.x以后,必须是相同类型进行移动位置
# 注意:位置改变后,列对应的数据不会互换,相当于将两个列名进行替换而已(感觉有点无用了)
# eg:英语 数学 替换后 数学 英语
60 100 60 100
alter table tableName change column colName colName colType after colName1;
alter table talbeName change column colName colName colType first;
- 增加字段
alter table talbeName add columns (sex int,...);
- 删除字段:实际上是保留小括号内的字段
alter table tableName replace columns(
id int,
name int,
size int,
pic string
);

5)删除表

1
drop table talbeName;

四、数据导入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@Master hive]# mkdir hivedata
[root@Master hive]# cd hivedata
[root@Master hivedata]# vi user.txt
# 加入如下数据(不要空行、空格)
1,张三
2,李四
3,王五
create table t_user(
id int,
name string
)
row format delimited
fields terminated by ','
lines terminated by '\n'
stored as textfile;

加载数据到Hive,一般分为两种:

1
2
- 一种是从本地linux上加载到Hive中
- 另外一种是从HDFS加载到Hive中

方法1:

1
hdfs dfs -put ./user.txt /user/hive/warehouse/mydb.db/t_user

方法2:在hive中使用load命令

1
2
3
4
5
6
7
8
9
10
11
load data [local] inpath '文件路径' [overwrite] into table 表名
参数说明:
local 加载linux本地文件时加上,加载hdfs上的文件则不需要加,注意:上传本地文件相当于拷贝,而加载hdfs上的文件时,会移动原本文件到对应表目录中
overwrite 如不写,如果有重名文件,则追加
加载数据时:
1. 最好写绝对路径,从根路径开始
2. 也可以写相对路径,但是一定要记住登录hive时的位置,从当前位置写相对路径
3. ~在hive中,是相对路径的写法
4. 使用beeline工具进行远程登录(客户端与服务器不在同一机器)时,使用以下语句:
load data local inpath '文件路径' [overwrite] into table 表名
会有一个大坑:local是指服务端的文件系统,而不是当前操作hive的客户端

方法3:从另一张表(也可称为备份表)中动态加载数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
insert into table tableName2 select [...] from talbeName1;

扩展内容:向多张表插入数据
from tableName1
insert into tableName2 select *
insert into tableName3 select * where 条件
...

create table t_user2(
id int,
name string
)
row format delimited
fields terminated by ','
lines terminated by '\n'
stored as textfile;

insert into table t_user2 select * from t_user;

方法4:克隆表数据

1
2
3
4
5
- create table if not exists tableName2 as select [...] from tableName1;
- create table if not exists tableNmae2 like tableName1 location 'tableName1存储目录的路径' # 新表不会产生自己的目录,因为用的是别的表路径

扩展内容:只复制表结构
create table if not exists tableName2 like tableName1;

加载数据的本质:

1)如果数据在本地,加载数据的本质就是将数据copy到hdfs上的表目录下。

2)如果数据在hdfs上,加载数据的本质就是将数据移动到hdfs的表目录下。

注意:hive使用的是严格的读时模式:加载数据时不检查数据的完整性,读时发现数据不对则使用NULL代替。而mysql使用的是写时模式:在写入数据的时候就进行检查.

五、案例演示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
create table flow(
id string comment 'this is id column',
phonenumber string,
mac string,
ip string,
url string,
urltype string,
uppacket int,
downpacket int,
upflow int,
downflow int,
issuccess int
)
comment 'this is log table'
row format delimited
fields terminated by '\t'
lines terminated by '\n'
stored as textfile;

加载数据:
load data local inpath '/opt/module/hive/hivedata/HTTP_234234234.dat' into table flow;

1. 统计每个电话号码的总流量(M)
select l.phonenumber,
round(sum(l.upflow + l.downflow) / 1024.0,2) as total
from flow l
group by l.url
order by urlcount desc
limit 3;

2. 求访问次数排名前三的url
select l.url url,
count(l.url) as urlcount
from flow l
group by l.url
order by urlcount desc
limit 3;

六、数据导出

1)hive数据导出分类

1
2
3
1. 从hive表中导出到本地文件系统中(目录、文件)
2. 从hive表中导出到hdfs文件系统中
3. hive表导出到其它hive表中

2)导出到目录

1
2
3
4
5
6
7
8
9
10
11
12
13
--1. 导出到本地文件系统
insert overwrite local directory '/root/out/00'
select * from student;

--2. 导出到hdfs
insert overwrite directory '/root/out/01'

-- 导出的文件中字段默认不分隔

--3. 修改导出后的列与列之间的格式:
insert overwrite local directory '/root/out/01'
row format delimited fields terminated by ','
select * from student;

3)导出到本地文件系统的文件中

1
2
hive -e 'select * from mydb.student' >> /root/out/02;
-- 分隔符默认为\t

七、hive的内部表和外部表

1)表分类

在Hive表中,表类型主要分为两种

第一种:内部表

1
2
3
- 也叫管理表
- 表目录会创建在集群上的{hive.metastore.warehouse.dir}下相应库对应的目录中
- 默认创建的表就是内部表

第二种:外部表

1
2
3
4
5
6
7
8
9
10
11
- 外部表需要使用关键字"external"
- 外部表会根据创建时LOCATION指定的路径来创建目录
- 如果没有指定LOCATION,则位置跟内部表相同,一般使用的是第三方提供或者公用的数据
- 建表语法:
create external table t_user(
id int,
name string
)
row format delimited
fields terminated by ','
location '/publicData';

2)内部表和外部表转换

内部表转外部表

1
2
alter table tableName set tblproperties('EXTERNAL'='TRUE');
注意:内部表转外部表,TRUE一定要大写

外部表转内部表

1
2
alter table tableName set tblproperties('EXTERNAL'='false');
说明:false不区分大小写

3)两者之间区别

  1. 内部表和外部表在创建时的差别

    关键字:EXTERNAL和LOCATION

    举例:

    1
    2
    - 内部表 -- create table t_inner(id int);
    - 外部表 -- create external table t_outer(id int) location 'HDFS:///AA/BB
  2. drop时不同的特性

    1
    2
    1. 元数据会被清楚
    2. 内部表的表目录会被删除,但是外部表的表目录不会被删除
  3. 使用场景

    内部表:可以随时修改删除数据。

    外部表:数据不想被删除的情况下使用外部表。

Hive Shell技巧

1.linux执行hive命令

通过shell的参数-e可以执行一次就运行完的命令

1
[hadoop@Slave1 ~]$ hive -e "select * from cat"

2.linux执行一个sql文件

可以执行sql文件中的hive语句

1
[hadoop@Slave1 ~]$ hive -f /path/cat.sql # 路径为本地路径

3.执行linux命令

前缀加上!,最后 ; 结尾,就能执行linux命令

1
hive> ! pwd ;

4.执行hdfs命令

不用敲入前缀hdfs或者hadoop

1
hive> dfs -ls /tmp;

5.显示当前库

省的不知道用的是哪个库

1
2
3
4
hive> set hive.cli.print.current.db=true; 
-- 结果
hive (mydb)>
-- 注意:这种方式,退出hive之后就失效了,也就是只针对当前session

可以通过配置hive-site.xml解决

1
2
3
4
<property>
<name>hive.cli.print.current.db</name>
<value>true</value>
</property>

也可以在$HIVE_HOME/conf执行vim .hiverc添加hive.cli.print.current.db=true来解决