Hadoop入门学习笔记——七、Hive语法

news2025/1/19 11:29:22

视频课程地址:https://www.bilibili.com/video/BV1WY4y197g7
课程资料链接:https://pan.baidu.com/s/15KpnWeKpvExpKmOC8xjmtQ?pwd=5ay8

Hadoop入门学习笔记(汇总)

目录

  • 七、Hive语法
    • 7.1. 数据库相关操作
      • 7.1.1. 创建数据库
      • 7.1.2. 选择数据库
      • 7.1.3. 描述数据库详细信息
      • 7.1.4. 创建数据库并指定其在HDFS系统中的存储位置
      • 7.1.5. 删除数据库
      • 7.1.6. 修改数据库存储位置
      • 7.1.7. 查询当前USE的数据库
    • 7.2. 数据表操作
      • 7.2.1. Hive所支持的数据类型
      • 7.2.2. 创建数据表
        • 7.2.2.1. 基础建表语句
        • 7.2.2.2. 基于其他表的结构建表
        • 7.2.2.3. 基于查询结果建表
        • 7.2.2.4. 建表时指定Hive数据分隔符
      • 7.2.3. 删除表
      • 7.2.4. 数据加载和导出
        • 7.2.4.1. 数据加载
        • 7.2.4.2. 数据导出
      • 7.2.5. 分区表
      • 7.2.6. 分桶表
        • 7.2.6.1. 开启分桶的自动优化(自动匹配Reduce task数量和桶的数量一致)
        • 7.2.6.2. 创建分桶表
        • 7.2.6.3. 分桶表加载数据
      • 7.2.7. 修改表
        • 7.2.7.1. 表重命名
        • 7.2.7.2. 修改表的属性
        • 7.2.7.3. 修改表的分区
      • 7.2.8. 复杂类型操作

七、Hive语法

7.1. 数据库相关操作

7.1.1. 创建数据库

CREATE DATABASE [IF NOT EXISTS] db_name [LOCATION 'path'] [COMMENT database_comment];
  • IF NOT EXISTS,如存在同名数据库不执行任何操作,否则执行创建数据库操作
  • [LOCATION],自定义数据库存储位置,如不填写,默认数据库在HDFS的路径为:/user/hive/warehouse
  • [COMMENT database_comment],可选,数据库注释

例如:

create database if not exists myhive;

创建一个名字为myhive的数据库,如果该数据已存在,则不再执行创建动作。

7.1.2. 选择数据库

USE db_name;
  • 选择数据库后,后续SQL操作基于当前选择的库执行
  • 如不使用use,默认在default库执行

例如:

use myhive;

使用myhive数据库;

若想切换回使用default库

USE DEFAULT;

7.1.3. 描述数据库详细信息

desc database myhive;

可以看到数据库名称、数据库存放路径、所属用户等信息。
在这里插入图片描述
可以使用HDFS命令hadoop fs -ls /user/hive/warehouse查看对应的文件;
在这里插入图片描述

7.1.4. 创建数据库并指定其在HDFS系统中的存储位置

create database myhive2 location '/user/hive/myhive2';

此时可以再次使用desc database myhive2查看myhive2数据库的详细信息,可以看到myhive2数据库的存放路径是按照指定的位置存放的。
在这里插入图片描述
在这里插入图片描述

7.1.5. 删除数据库

DROP DATABASE [IF EXISTS] db_name [CASCADE];
  • [IF EXISTS],可选,如果存在此数据库执行删除,不存在不执行任何操作
  • [CASCADE],可选,级联删除,即数据库内存在表,使用CASCADE可以强制删除数据库

例如:
删除一个空的数据库(无数据、无表)

drop  database  myhive;

删除一个非空数据库(有表或有数据)/ 强制删除数据库

drop database myhive2 cascade;

7.1.6. 修改数据库存储位置

ALTER DATABASE db_name SET LOCATION hdfs_path;

不会在HDFS对数据库所在目录进行改名,只是修改location后,新创建的表在新的路径,旧的不变

7.1.7. 查询当前USE的数据库

SELECT current_database();

7.2. 数据表操作

7.2.1. Hive所支持的数据类型

分类类型描述字面量示例
原始类型BOOLEANtrue/falseTRUE
TINYINT1字节的有符号整数 -128~1271Y
SMALLINT2个字节的有符号整数,-32768~327671S
INT4个字节的带符号整数1
BIGINT8字节带符号整数1L
FLOAT4字节单精度浮点数1.0
DOUBLE8字节双精度浮点数1.0
DEICIMAL任意精度的带符号小数1.0
STRING字符串,变长“a”,’b’
VARCHAR变长字符串“a”,’b’
CHAR固定长度字符串“a”,’b’
BINARY字节数组
TIMESTAMP时间戳,毫秒值精度122327493795
DATE日期‘2016-03-29’
时间频率间隔
复杂类型ARRAY有序的的同类型的集合array(1,2)
MAPkey-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)

7.2.2. 创建数据表

7.2.2.1. 基础建表语句
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] tb_name
	(col_name col_type [COMMENT col_comment], ......)
	[COMMENT tb_comment]
	[PARTITIONED BY(col_name col_type, ......)]
	[CLUSTERED BY(col_name, col_name, ......)
	[SORTED BY(col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS]
	[ROW FORMAT DELIMITED FIELDS TERMINATED BY '']
	[STORED AS SEQUENCEFILE|TEXTFILE|RCFILE]
	[LOCATION 'path']
  • [IF NOT EXISTS],若tb_name不存在则创建;
  • [COMMENT tb_comment],表注释;
  • [EXTERNAL],创建外部表,需与下列属性搭配:
    • [ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘’],指定数据的分隔符;
    • [LOCATION ‘path’],表在HDFS系统中的存放路径;
  • [PARTITIONED BY(col_name col_type, …)],基于列进行分区存储,col_name为表中没有的列名,col_type为列的类型,支持依据多个列分区,这里的列不与表中的原始的数据列相同;
  • [CLUSTERED BY(col_name, col_name, …) INTO num_buckets BUCKETS],基于列分桶,col_name为表中已有的列,num_buckets为分桶个数;
  • [STORED AS SEQUENCEFILE|TEXTFILE|RCFILE],存储格式,如果文件数据是纯文本可以用TEXTFILE,如果数据需要压缩可以用SEQUENCEFILE;
  • [LOCATION ‘path’],存储位置;

1、内部表和外部表的区别

  • 内部表(CREATE TABLE table_name …)
    未被external关键字修饰的即是内部表, 即普通表。内部表又称管理表,内部表数据存储的位置由hive.metastore.warehouse.dir参数决定(默认:/user/hive/warehouse),删除内部表会直接删除元数据(metadata)及存储数据,即在MySQL的Hive数据库的TBLS表中的数据和在HDFS系统中的文件都会被删除,因此内部表不适合和其他工具共享数据。

  • 外部表(CREATE EXTERNAL TABLE table_name …LOCATION…)
    被external关键字修饰的即是外部表, 即关联表。外部表的数据可以放在任何位置,通过LOCATION关键字指定。数据存储的不同也代表了这个表在理念是并不是Hive内部管理的,而是可以随意临时链接到外部数据上的。在删除外部表的时候, 仅删除元数据(表的信息),不会删除数据本身,即仅删除MySQL的Hive数据库的TBLS表中的数据,但HDFS系统中的文件不会被删除。

表类型创建存储位置删除数据理念
内部表CREATE TABLE …Hive管理,默认/user/hive/warehouse- 删除 元数据(表信息)
- 删除 数据
Hiv管理表
持久使用
外部表CREATE EXTERNAL TABLE … LOCATION …随意,LOCATION关键字指定- 进删除 元数据(表信息)
- 保留 数据
临时链接外部数据用

2、使用内部表
使用以下语句建库、建表、插入数据

CREATE database myhive;
use myhive;
CREATE table stu(id int, name string);
INSERT INTO stu values(1, '周杰轮'), (2, '林君姐');

插入之后,由于是内部表,可以在HDFS系统中的/user/hive/warehouse/myhive.db/stu文件下看到对应的数据表存储文件
在这里插入图片描述
此时,使用hadoop fs -cat命令打开这个文件,查看其里面的内容,即是刚才插入的数据
在这里插入图片描述
其他一些创建内部表的方式:

-- 基于其它表的结构建表
CREATE TABLE tbl_name LIKE other_tbl;
-- 基于查询结果建表
CREATE TABLE tbl_name AS SELECT ...;

3、使用外部表,关联已有数据
3.1、第一种情况:先有表,后有数据
先在Linux系统中创建一个test_external.txt文件,内容如下(使用\t做为分隔符):

1 itheima
2 itcast
3 hadoop

在创建外部表之前,需要确保外部表所指定的存储位置的目录不存在,在本例中,需要确保HDFS系统中/tmp/test_ext1目录不存在;
在这里插入图片描述

然后创建外部表:

CREATE external table test_ext1(id int, name string) row format delimited fields terminated by '\t' LOCATION '/tmp/test_ext1';

创建一个外部表,表名为test_ext1,由2个字段id和name构成,该表的数据分隔符为\t,在HDFS系统中的存储位置为/tmp/test_ext1文件夹;
在这里插入图片描述
当前因为没有任何数据,所以该文件夹里面没有任何内容,这时,我们通过hadoop fs -puthdfs dfs -put命令将前面在Linux中创建的test_external.txt文件上传到/tmp/test_ext1目录下;

hdfs dfs -put test_external.txt /tmp/test_ext1/

上传完成后,在Hive中执行SELECT * FROM test_ext1;语句,便可以看到刚才上传的文件中的数据了;
在这里插入图片描述
3.2、第二种情况:先有数据,后有表
先在HDFS中创建一个test_ext2目录

hadoop fs -mkdir /tmp/test_ext2

将数据文件上传到test_ext2目录下

hadoop fs -put test_external.txt /tmp/test_ext2

然后创建同名(test_ext2)的外部表,并将其存储位置设置为/tmp/test_ext2

CREATE external table test_ext2(id int, name string) row format delimited fields terminated by '\t' LOCATION '/tmp/test_ext2';

然后使用SELECT * FROM test_ext2;语句查询数据,发现数据可以被Hive读取到。
在这里插入图片描述
3.3、删除外部表
在删除表之前,查看元数据库(MySQL的Hive库)中的TBLS表的数据和HDFS文件系统对应位置的文件夹;
在这里插入图片描述
在这里插入图片描述
然后执行删表语句drop table test_ext1;,执行成功后,再次查看元数据库(MySQL的Hive库)中的TBLS表的数据和HDFS文件系统对应位置的文件夹;
在这里插入图片描述
在这里插入图片描述

发现,元数据库中的表信息已被删除,但是HDFS系统中的数据文件仍然存在,未受影响。所以,删除外部表,完全不影响数据本身。

4、内外部表转换
创建一个内部表,创建一个外部表

-- 创建内部表t1
CREATE table t1(id int);
-- 创建外部表t2
CREATE external table t2(id int) row format delimited fields terminated by '\t' LOCATION '/tmp/t2';

使用desc formatted t1;语句查看t1表信息,可以看到,该表存储的位置在/user/hive/warehouse文件夹下,且其表类型为MANAGED_TABLE(即管理表,内部表);
在这里插入图片描述
使用desc formatted t2;语句查看t2表信息,可以看到,该表存储的位置在/tmp/t2文件夹下,且其表类型为EXTERNAL_TABLE(即外部表);
在这里插入图片描述
4.1、内部表转换成外部表

ALTER table t1 set TBLPROPERTIES ('EXTERNAL'='TRUE');

将t1表从内部表转换成外部表。

4.2、外部表转换成内部表

ALTER table t2 set TBLPROPERTIES ('EXTERNAL'='FALSE');

将t2表从外部表转换成内部表,注意括号里的EXTERNAL和TRUE、FALSE必须大写

7.2.2.2. 基于其他表的结构建表
CREATE TABLE tbl_name LIKE other_tbl;
7.2.2.3. 基于查询结果建表
CREATE TABLE tbl_name AS SELECT ...;
7.2.2.4. 建表时指定Hive数据分隔符

在HDFS系统中,通过hadoop fs -cathdfs dfs -cat命令查看Hive数据文件的内容时,在命令行里是看不到数据列的分隔符,这是因为,默认的分隔符是“\001”,是一个不可见的ASCII码,键盘打不出来,在有些文本编辑器中,其会显示为SOH,如下所示:
在这里插入图片描述
如果我们将Hive数据表文件下载到Linux服务器,然后使用vim工具打开查看,其会显示为^A,如下图所示:
在这里插入图片描述
当然,数据分隔符也是可以指定的,在创建表的时候,通过row format delimited fields terminated by可以指定,如将分隔符设置为一个制表符,则建表时可以如下写:

create table if not exists stu2(id int ,name string) row format delimited fields terminated by '\t';

7.2.3. 删除表

DROP TABLE tbl;

例如:

DROP table test;
DROP table myhive.test;

删除test表。

7.2.4. 数据加载和导出

7.2.4.1. 数据加载

1、LOAD语法(从文件向表导入数据)
在Hive客户端中执行以下语句:

LOAD DATA [LOCAL] INPATH 'path' [OVERWRITE] INTO TABLE tb_name [PARTITION(partition_key='partition_value')];

[LOCAL],表示要加载的数据文件是否在Linux文件系统中,若在Linux文件系统则需要写上LOCAL,若在HDFS系统则不需要写LOCAL;
‘path’,表示要加载的文件路径;
[OVERWRITE],表示是否要覆盖表中已有的数据(即表中原有的数据都删除,只保留本次导入的数据);
tb_name,为将数据加载进入的表名。

用法:
先创建一个内部表;

CREATE table myhive.test_load(
	dt string comment '时间',
	user_id string comment '用户id',
	search_word string comment '搜索关键词',
	url string comment '网址'
) comment '搜索引擎日志表' row format delimited fields terminated by '\t'

1.1、从Linux系统加载数据到Hive表中
将课程资料中的search_log.txt文件上传到node1服务器的/home/hadoop目录下;
直接从Linux系统中加载数据到test_load表;

load data local inpath '/home/hadoop/search_log.txt' into table test_load;

此时,数据就已经加载到了test_load表(加载速度很快);
在这里插入图片描述
1.2、从HDFS系统中加载数据到Hive表
将前面的search_log.txt文件上传到HDFS系统/tmp目录下;

hdfs dfs -put search_log.txt /tmp/

将HDFS文件系统中的search_log.txt文件加载到test_load表;

load data inpath '/tmp/search_log.txt' into table test_load;

此时,数据已导入test_load表中;
在这里插入图片描述
可以看到,数据已经变成了2份,第一份是前面从Linux本地导入的,第二份是从HDFS文件系统导入的;
此时,再次查看HDFS系统的/tmp目录,会发现之前上传的search_log.txt文件已经没有了,其实这个导入操作本质上是移动HDFS文件到Hive库表所在的目录
在这里插入图片描述
1.3、演示overwirte属性
再次执行从Linux本地加载数据,但本次带上overwrite属性

load data local inpath '/home/hadoop/search_log.txt' overwrite into table test_load;

执行完成后,再次查看test_load表的内容,会发现只剩了文件中的内容,而不像之前一样追加,这里是覆盖的写,该表中原有的数据全部被清空,只保留了本次导入的数据。
在这里插入图片描述
2、INSERT SELECT语法(从其他表向表导入数据)
在Hive客户端中执行以下语句:

INSERT [OVERWRITE | INTO] TABLE tb_name1 [PARTITION (partcol1=val1, partcol2=val2 ...) [IF NOT EXISTS]] SELECT select_statement1 FROM from_statement;

将SELECT查询语句的结果插入到其它表中,被SELECT查询的表可以是内部表或外部表。
[OVERWRITE | INTO],表示覆盖或追加数据,覆盖时用OVERWRITE,追加时用INTO;
tb_name1,表示数据导入目标表的表名;

用法:
先创建一个内部表;

CREATE table myhive.test_load2(
	dt string comment '时间',
	user_id string comment '用户id',
	search_word string comment '搜索关键词',
	url string comment '网址'
) comment '搜索引擎日志表2' row format delimited fields terminated by '\t';

将test_load表中的数据导入test_load2

INSERT INTO table test_load2 select * FROM test_load;

执行上述语句,会发现又被转换成MapReduce任务执行,所以在大规模数据下与LOAD DATA没有区别,但是在小规模数据下,使用LOAD DATA会更快一些。
此时,test_load2表中已经有了数据。
在这里插入图片描述
如果再次执行上面的SQL,会发现test_load2表里面的数据会被追加一份。
在这里插入图片描述
如果将上面的SQL语句修改为:

INSERT OVERWRITE table test_load2 select * FROM test_load;

执行完成后,查看数据,会发现之前的数据被覆盖了,只保留了本次SQL执行的结果。
在这里插入图片描述
3、数据导入方式的选择

  • 数据在Linux本地
    • 推荐使用load data local方式加载;
  • 数据在HDFS系统
    • 如果不需要保留源文件:推荐使用load data方式加载;
    • 如果需要保留源文件:推荐使用外部表先关联数据,然后通过insert select方式加载;
  • 数据已经在Hive表中
    • 只能使用insert select方式加载。
7.2.4.2. 数据导出

1、INSERT OVERWRITE方式
在Hive客户端中执行以下语句:

insert overwrite [local] directory 'path' [row format delimited fields terminated by ''] select select_statement1 FROM from_statement;

将select语句的结果写入指定的文件中。
[local],表示是否导出到Linux系统本地,若是,则带上该参数,若不是,则不用写;
‘path’,表示Linux本地或HDFS系统中的路径,若前面有local,这里写的就是Linux系统路径,若没有local,这里写的就是HDFS文件系统路径,这里的path是一个文件夹;
[row format delimited fields terminated by ‘’],表示指定导出数据时所使用的数据分隔符(与表所使用的数据分隔符无关),默认分隔符为ASCII码\001,不可见。

用法:

1.1、导出数据到本地:

INSERT overwrite local directory '/home/hadoop/export1' select * FROM test_load;

将test_load表中的数据导出到Linux系统的/home/hadoop/export1文件夹中。
执行时发现,该语句需要被转换成MapReduce任务执行;
执行完成后,可以在/home/hadoop目录下看到export1文件夹;
在这里插入图片描述
进入该文件夹,并查看其内文件的内容
在这里插入图片描述
上图可以看到导出的数据,但是由于导出时未指定数据分隔符,所以使用的是默认分隔符,是不可见内容;
将上述导出语句中增加指定分隔符的参数:

INSERT overwrite local directory '/home/hadoop/export2' row format delimited fields terminated by '\t' select * FROM test_load;

此时查看Linux本地的/home/hadoop/export2目录及其内容如下,可以看到导出的数据已通过\t进行了分割:
在这里插入图片描述
1.2、导出数据到HDFS系统中

INSERT overwrite directory '/tmp/export_to_hdfs1' row format delimited fields terminated by '\t' select * FROM test_load;

执行完成后,查看HDFS文件/tmp目录下的内容
在这里插入图片描述
2、hive shell方式
在Linux的命令行下执行:

./hive -e "select ... from ...;" > 'local_path'
# 或
./hive -f 'sql_file_path' > 'local_path'

“select … from …;”,表示要执行的SQL语句;
‘local_path’,表示要导出的Linux文件路径;
‘sql_file_path’,表示要执行的SQL脚本文件在Linux中的路径;

用法:

2.1、通过SQL语句导出数据

# 切换目录
cd /export/server/hive/bin
# 将Hive中的myhive库的test_load表的内容导出到Linux系统/home/hadoop/下的export3.txt文件中
./hive -e "select * from myhive.test_load;" > /home/hadoop/export3.txt
# 查看/home/hadoop/export3.txt的
cat /home/hadoop/export3.txt

在这里插入图片描述
2.2、通过SQL文件导出数据
在Linux系统/home/hadoop目录下创建一个export.sql文件,写入如下内容:

select * from myhive.test_load;

然后在Linux的命令行中执行如下命令:

# 使用hive -f命令,执行export.sql文件中的SQL语句,将其执行结果导出到当前目录下的export4.txt文件中
/export/server/hive/bin/hive -f export.sql > export4.txt
# 查看export4.txt文件内容
cat export4.txt

在这里插入图片描述

7.2.5. 分区表

在大数据中,最常用的一种思想就是分治,我们可以把大的文件切割划分成一个个的小的文件,这样每次操作一个小的文件就会很容易了。
在hive当中也是支持这种思想的,就是我们可以把大的数据,按照一定的规则(如每天、每小时等)切分成一个个小的文件。
每一个分区,都是一个文件夹。同时,Hive也支持多个字段作为分区,多分区带有层级关系。
在这里插入图片描述
1、创建一个按月进行单分区(按month分区)的学生成绩表,并指定数据分隔符为\t

CREATE table myhive.score(
	id STRING COMMENT '学生ID',
	cid STRING COMMENT '课程ID',
	score int COMMENT '课程分数'
) COMMENT '学生成绩表'
partitioned by (month STRING)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';

将课程资料中score.txt文件加载到上表中,并指定分区的月份为202005;

load data local inpath '/home/hadoop/score.txt' into table myhive.score partition(month='202005');

上面创建的表,相当于有4个列,前3个列从数据文件中获取,最后一个列是当数据插入时进行指定;
在这里插入图片描述

load data local inpath '/home/hadoop/score.txt' into table myhive.score partition(month='202006');

再加载一次数据,本次指定month为 202006。
然后查看HDFS系统中score表所对应目录的情况;
在这里插入图片描述
对Linux本地的score.txt文件修改一些内容,然后再次加载数据

load data local inpath '/home/hadoop/score.txt' into table myhive.score partition(month='202007');

在这里插入图片描述
在这里插入图片描述
2、创建一个按年、月、日,三个层次的多分区学生成绩表,并指定数据分隔符为\t

CREATE table myhive.score2(
	id STRING COMMENT '学生ID',
	cid STRING COMMENT '课程ID',
	score int COMMENT '课程分数'
) COMMENT '学生成绩表2'
partitioned by (year STRING, month STRING, day STRING)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';

这个表实际有6个字段,其中前3个是数据列,后3个是在数据插入时指定的分区列
在这里插入图片描述
将Linux系统中score.txt的数据加载到上面的多分区表中

load data local inpath '/home/hadoop/score.txt' into table myhive.score2 partition(year="2022", month='01', day="10");

此时,score2表中的数据为,可以看到id,cid和score的数据来自score.txt文件的内容,而year,month,day三个字段的数据来自导入语句指定;
在这里插入图片描述
然后再查看HDFS系统中的目录结构
在这里插入图片描述
再导入几次数据

load data local inpath '/home/hadoop/score.txt' into table myhive.score2 partition(year="2022", month='01', day="11");
load data local inpath '/home/hadoop/score.txt' into table myhive.score2 partition(year="2023", month='01', day="11");
load data local inpath '/home/hadoop/score.txt' into table myhive.score2 partition(year="2022", month='02', day="11");

此时,再次查看HDFS系统中score2目录下的目录结构
在这里插入图片描述
3、分区表在创建时指定的分区字段,在插入数据时必须都要传入,否则Hive会报错。
4、分区表查询时,如果以分区列做为where条件,会极大的提高查询效率,因为只需要读取对应文件夹下的数据即可。

7.2.6. 分桶表

分桶和分区一样,也是一种通过改变表的存储模式,从而完成对表优化的一种调优方式
但和分区不同,分区是将表拆分到不同的子文件夹中进行存储,而分桶是将表拆分到固定数量的不同文件中进行存储。
在这里插入图片描述

7.2.6.1. 开启分桶的自动优化(自动匹配Reduce task数量和桶的数量一致)
set hive.enforce.bucketing = TRUE;
7.2.6.2. 创建分桶表
CREATE table myhive.course(c_id string, c_name string, t_id string) clustered by (c_id)
INTO 3 buckets row format delimited fields terminated by '\t';

创建一个course表,根据表中的c_id字段分三个桶;

7.2.6.3. 分桶表加载数据

由于桶表的数据加载通过load data无法执行,只能通过insert select方式加载。
1、创建一个临时表(外部表或内部表均可),通过load data把数据加载到临时表;

-- 创建临时中转表(需要注意,中转表的分隔符需要与分桶表保持一致)
CREATE table myhive.course_temp(c_id string, c_name string, t_id string) row format delimited fields terminated by '\t';
-- 将数据加载到中转表
load data local inpath '/home/hadoop/course.txt' into table myhive.course_temp;

2、从临时表通过insert select方式将数据加载到分桶表;

INSERT overwrite table myhive.course select * FROM myhive.course_temp cluster by(c_id);

这里需要注意,在向分桶表插入数据时,需要使用cluster by标明分桶依赖字段。注意,这里是cluster,而不是建表时缩写的clustered!
此时,我们可以查看HDFS系统中的文件情况hadoop fs -ls /user/hive/warehouse/myhive.db/course
在这里插入图片描述
会发现,course表的数据被放在了三个文件中,这里是因为最开始创建分桶表时,指定的分桶数量为3,如果指定其他数量的分桶数,那就会生成对应的文件个数。

3、为什么不可以用load data,必须用insert select插入数据
如果没有分桶设置,插入(加载)数据只是简单的将数据放入到:

  • 表的数据存储文件夹中(没有分区);
  • 表指定分区的文件夹中(带有分区)。

一旦有了分桶设置,比如分桶数量为3,那么,表内文件或分区内数据文件的数量就限定为3。当数据插入的时候,需要一分为3,进入三个桶文件内。
数据的三份划分基于分桶列的值进行hash取模来决定,由于load data不会触发MapReduce,也就是没有计算过程(无法执行Hash算法),只是简单的移动数据而已,所以无法用于分桶表数据插入。

7.2.7. 修改表

7.2.7.1. 表重命名

语法:

alter  table  old_table_name  rename  to  new_table_name;

old_table_name,当前的表名;
new_table_name,新的表名。
例如:

--将表score2重命名成score3
ALTER table score2 rename to score3;
7.2.7.2. 修改表的属性

语法:

ALTER TABLE table_name SET TBLPROPERTIES table_properties;
table_properties:
  : (property_name = property_value, property_name = property_value, ... )

例如:

-- 将score3修改为外部表
ALTER table score3 set TBLPROPERTIES("EXTERNAL"="TRUE");
-- 将score3表的注释修改为this is table comment
ALTER table score3 set TBLPROPERTIES("comment"="this is table comment");

其余属性可参见:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL#LanguageManualDDL-listTableProperties

7.2.7.3. 修改表的分区

1、添加分区
语法:

ALTER TABLE tablename  ADD PARTITION (month='201101');

例如:

-- 给score3表添加一个year为2019,month为10,day为01的分区
ALTER table score3 add partition(year='2019', month='10', day='01');

分区添加完成之后,因为新分区内还没有数据,所以在Hive中是看不到的,但是可以在HDFS中看到对应的目录;
在这里插入图片描述
可以通过手动添加数据文件或者加载数据的方式导入数据;
例如,将另一个分区的数据文件复制一份过来hadoop fs -cp /user/hive/warehouse/myhive.db/score3/year=2022/month=01/day=10/score.txt /user/hive/warehouse/myhive.db/score3/year=2019/month=10/day=01/,这时,在DBeaver中就可以看到新分区中出现了数据
在这里插入图片描述

2、修改分区值(一般不要修改)
语法:

ALTER TABLE tablename PARTITION (month='202005') RENAME TO PARTITION (month='201105');

例如:

-- 将score3表year为2019,month为10,day为01的分区修改为year为2019,month为10,day为07
ALTER table score3 partition(year='2019', month='10', day='01') rename to partition(year='2019', month='10', day='07');

这时可以查看DBeaver中的数据,发现数据已经被修改了;
在这里插入图片描述
同时,查看HDFS系统中的目录结构,发现文件目录并没有修改。这时因为,修改分区值本质上是修改元数据,而HDFS系统中的文件夹不会被重命名(默认元数据中的分区值和HDFS系统中的文件夹名字是一样的,但是也可以不同)。
在这里插入图片描述
此时,可以连接元数据库(node1服务器上的MySQL数据库),进入hive库,查看PARTITIONS表的内容,会发现分区名字已经变为了year=2019/month=10/day=07,其SD_ID为14,其TBL_ID为5,对应的字典为score3(表名);
在这里插入图片描述
然后再查看SDS表中的数据,会发现SD_ID为14的数据,其对应的LOCATION的值为hdfs://node1:8020/user/hive/warehouse/myhive.db/score3/year=2019/month=10/day=01,通过这两个表实现了分区和HDFS系统中文件夹的对应,同时,也可以看到分区值已经变更了,但是HDFS中的物理存储路径没有变化。
在这里插入图片描述
当然,也可以先手动修改HDFS系统中对应路径的文件夹名,然后再来SDS表中修改LOCATION的值到新的路径,就可以实现分区值和HDFS路径一样了。

3、删除分区
语法:

ALTER TABLE tablename DROP PARTITION (month='201105');

例如:

-- 删除score3表中year为2019,month为10,day为07的分区
ALTER table score3 drop partition(year='2019', month='10', day='07');

删除分区后,Hive表中对应分区的数据也会被删除,但是HDFS系统中的相关文件夹和数据文件不会被删除。
这时因为删除分区只是删除了元数据,数据本身还在

7.2.8. 复杂类型操作

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1331052.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python之zip函数相关介绍

python3的zip函数 zip函数接受任意多个可迭代对象作为参数,将对象中对应的元素打包成一个tuple,然后返回一个可迭代的zip对象。 这个可迭代对象可以使用循环的方式列出其元素,若多个可迭代对象的长度不一致,则所返回的列表与长度最短的可迭…

WPF中使用DataGrid封装组合控件TreeView+DataGrid

(关注博主后,在“粉丝专栏”,可免费阅读此文) wpf的功能非常强大,很多控件都是原生的,但是要使用TreeViewDataGrid的组合,就需要我们自己去封装实现。 我们需要的效果如图所示&#x…

汽车品牌官网建设的效果如何

汽车、电动摩托车、自行车等是人们常用的出行工具,头部品牌不少,中小品牌也同样很多,在当今激烈竞争的市场,各商家都希望不断拓客寻求销量增长。由于市场产品同质化严重且无突出特色,加之选择性广,因此在实…

华为鸿蒙应用--封装数据持久化工具:首选项Preferences(鸿蒙工具)-ArkTs

一、使用方法: 0、初始化实例:一般在EntryAbility.ts的onWindowStageCreate中初始化;(可忽略) 1、将数据写入Preferences实例 function() {let arrayNum: number[] [1, 2, 3];let arrayStr: string[] ["5&quo…

vue3项目 - 使用 pnpm 包管理器来创建项目

创建项目 npm install -g pnpm pnpm create vue 输入项目名称、包名称、选择要安装的依赖,最后 pnpm install pnpm format #规范格式 pnpm dev #启动项目

深度学习 | 常见问题及对策(过拟合、欠拟合、正则化)

1、训练常见问题 1.1、模型架构设计 关于隐藏层的一个万能近似定理: Universal Approximation Theorem:一个具有足够多的隐藏节点的多层前馈神经网络,可以逼近任意连续的函数。(Cybenko, 1989)—— 必须包含至少一种有…

mysql自增序列 关于mysql线程安全 独享内存 溢出 分析

1 MySQL锁概述 锁是计算机协调多个进程或线程并发访问某一资源的机制。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。 相对其他数据库而言,MySQL的锁机制比较简单&#xff0c…

C++中的内存锁定

内存锁定(memory locking)是确保进程保留在主内存中并且免于分页的一种方法。在实时环境中,系统必须能够保证将进程锁定在内存中,以减少数据访问、指令获取、进程之间的缓冲区传递等的延迟。锁定内存中进程的地址空间有助于确保应用程序的响应时间满足实…

二维码初体验 com.google.zxing 实现

文章目录 一、概述二、实现效果1. 完整版本2. 简化版本 三、源码结构四、完整代码 一、概述 Java 操作二维码的开源项目很多,如 SwetakeQRCode、BarCode4j、Zxing 等,这边以Zxing 为例进行介绍。 二、实现效果 1. 完整版本 选择需要生成QR原始文件&a…

大模型工具_awesome-chatgpt-prompts-zh

https://github.com/PlexPt/awesome-chatgpt-prompts-zh 1 功能 整体功能,想解决什么问题 ChatGPT 中文调教指南:提供一些常用的使用场景及对应的 Prompt 提示 当前解决了什么问题,哪些问题解决不了 针对想解决实际问题,但不知道…

图像识别中的 Vision Transformers (ViT)

引言 Vision Transformers (ViT) 最近已成为卷积神经网络(CNN) 的竞争替代品,而卷积神经网络 (CNN) 目前在不同的图像识别计算机视觉任务中处于最先进的水平。ViT 模型在计算效率和准确性方面比当前最先进的 (CNN) 模型高出近 4 倍。 Transformer 模型已成为自然语…

Diffusion扩散模型学习:图片高斯加噪

高斯分布即正态分布;图片高斯加噪即把图片矩阵每个值和一个高斯分布的矩阵上的对应值相加 1、高斯分布 np.random.normal 一维: import numpy as np import matplotlib.pyplot as pltdef generate_gaussian_noise(mean, std_dev, size):noise np.ran…

小白入门之安装NodeJS

重生之我在大四学JAVA 第五章 安装NodeJS 如果你在购买我闲鱼的程序,请尽量使用node14版本 修改安装路径 接着傻瓜式NEXT 测试是否安装成功 如果上面没提示版本号,就按照前两章配置环境变量步骤配置下环境变量 设置镜像地址 npm config set re…

一种简单的自编码器PyTorch代码实现

1. 引言 对于许多新接触深度学习爱好者来说,玩AutoEncoder总是很有趣的,因为它具有简单的处理逻辑、简易的网络架构,方便可视化潜在的特征空间。在本文中,我将从头开始介绍一个简单的AutoEncoder模型,以及一些可视化潜…

全渠道在线客服系统支持的沟通渠道:多渠道整合与无缝对接

我们在挑选客服系统的时候,经常会看到有些客服产品会强调自己是“全渠道客服系统”,那什么是全渠道客服系统呢? 1、什么是全渠道客服系统? 简单来讲,它是指能把某个客户在不同渠道的互动历史放到一起集中展现&#x…

rqt_graph使用说明

其中右边的:/rosout是一个topic 也就是一个话题 /rosout是一个topic 也是一个话题 可以看到凡是在rqt_graph里面用长方形标识的全都是话题 通过观察可以发现:凡是用椭圆标识的全都是节点 如果切换为Nodes only视图会发现: 所说的no…

SpringSecurity安全框架 ——认证与授权

目录 一、简介 1.1 什么是Spring Security 1.2 工作原理 1.3 为什么选择Spring Security 1.4 HttpSecurity 介绍🌟 二、用户认证 2.1 导入依赖与配置 2.2 用户对象UserDetails 2.3 业务对象UserDetailsService 2.4 SecurityConfig配置 2.4.1 BCryptPasswo…

【数据结构入门精讲 | 第八篇】一文讲清全部排序算法(2)

在上一篇文章中我们介绍了冒泡排序、快速排序等算法,这一篇我们接着对排序算法的学习。 目录 归并排序堆排序选择排序计数排序基数排序排序总结 归并排序 归并排序是建立在归并操作上的一种有效,稳定的排序算法,该算法是采用分治法&#xff…

MySQL报错:1054 - Unknown column ‘xx‘ in ‘field list的解决方法

我在操作MySQL遇到1054报错,报错内容:1054 - Unknown column Cindy in field list,下面演示解决方法,非常简单。 根据箭头指示,Cindy对应的应该是VARCHAR文本数字类型,字符串要用引号,所以解决方…

【C语言】打印内存数据

C语言,用函数封装:16进制打印unsigned char *p指向的内存,长度为int l。16个字节,换一次行。16个字节用一个字符串缓存,一次打印。 以下是一个使用函数封装的C语言代码,用于以16进制格式打印unsigned char …