元数据在Hive中起着关键的作用,它使得Hive能够理解和操作存储在底层存储系统中的数据。以下是一些常见的元数据信息:
数据库(Database):元数据中包含有关数据库的定义,例如数据库名称、所有者、创建时间等。
表(Table):每个表都有相应的元数据,包括表名称、列名称、列的数据类型、分区信息、表的存储格式、表的所有者等。
列(Column):表中每个列都有相关的元数据,包括列名称、数据类型、注释等。
分区(Partition):对于分区表,元数据包含有关分区的定义和属性,例如分区列、分区值、分区路径等。
数据类型(Data Types):元数据中记录了各种数据类型的定义,例如整数、字符串、日期等。
存储格式(Storage Format):Hive支持不同的存储格式,例如文本格式(Text)、序列文件格式(SequenceFile)、列式存储格式(ORC)等。元数据中包含有关表的存储格式的定义和属性。
4 Hive建表
create (external) table student
( id bigint (comment) '学生id', // 定义字段名,字段类型,comment是注解,可写可不写
name string,
age int,
gender string,
clazz string
)
partitioned by(pt string) // 可选,创建分区表
clustered by (clazz) into 12 buckets // 可选,创建分桶
row format delimited fields terminated by ',' // 必选,指定列分隔符
location '/data/hive' // 可选, 指定Hive表的数据的存储位置,通常跟外部表一起使用
stored as rcfile; // 可选,指定储存格式为rcfile,默认textfile格式
partitioned by(year string,month string) //二级分区
4.1 建表方式(5种)
使用默认建表方式
create table student
( id bigint, // 定义字段名,字段类型
name string,
age int,
gender string,
clazz string
)
row format delimited fields terminated by ','; //指定分割符
指定location
create external table student
( id bigint,
name string,
age int,
gender string,
clazz string
)
row format delimited fields terminated by ','
location '/data/hive'; //指定Hive表的数据的存储位置,一般在数据已经上传到HDFS(也就是在目录已经存在,指定一下位置指向这个目录),想要直接使用,会指定Location,通常Location会跟外部表(external)一起使用,内部表一般使用默认的location
指定存储格式
create table student
( id bigint,
name string,
age int,
gender string,
clazz string
)
row format delimited fields terminated by ','
stored as rcfile; //指定存储格式
注意:除textfile以外,其他存储格式的数据都不能直接加载(就是不能直接select,格式不一样),需要使用从表加载的方式(就是insert into)
**create table xxx as select_statement(SQL语句) **
create table student as select * from student1;
truncate table students; //不要表的内容了,内部表才能truncate
create table xxx like table_name
create table student like student1; //只想建表,不加载数据
5 Hive加载数据
小技巧:在hive里也可以操作hdfs命令,就是把hdfs去掉,直接从dfs开始写
使用 hdfs dfs -put ’ linux 本地数据’ ‘hive表对应的hdfs下的目录’
使用 load data inpath
//下列命令需要在hive shell里执行
方式1:
//将hdfs上的/input1目录下的数据 移动至 students表对应的hdfs目录下。移动、移动、移动
load data inpath '/input1/students.txt' into table students;
方式2:
//加上 local 关键字,可以将Linux本地路径下的文件,上传至hive表所对应的hdfs目录下
load data local inpath '/usr/local/soft/data/students.txt' into table students;
方式3:
// overwrite 表示覆盖
load data local inpath '/usr/local/soft/data/students.txt' overwrite into table students;
create table xxx as SQL语句
insert into / overwrite table xxx SQL语句 (没有as)
//将student1 表的数据加载到students中,这里是复制,不是移动,students1表中的数据不会丢失
insert into table students select * from students1;
//overwrite 覆盖插入
insert overwrite table students select * from students1;
6 Hive的各种表
6.1 内部表与外部表
内部表(Managed tables)vs 外部表(External tables)
// 内部表
create table students_internal
(
id bigint,
name string,
age int,
gender string,
clazz string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
LOCATION '/input1';
// 外部表
create external table students_external
(
id bigint,
name string,
age int,
gender string,
clazz string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
LOCATION '/input2';
删除表 :
hive> drop table students_internal;
Moved: 'hdfs://master:9000/input1' to trash at: hdfs://master:9000/user/root/.Trash/Current
OK
Time taken: 0.474 seconds
hive> drop table students_external;
OK
Time taken: 0.09 seconds
hive>
可以看出,删除内部表时,表中的数据(hdfs上的目录文件)会和表的元数据一起删除;
删除外部表时,只会删除表的元数据,表中的数据不会被删除(可以理解为在HDFS上还保存着,但在Hive中已经没有了,查不到此表信息了)
一般在公司中,外部表使用的多一点,可以避免误删。外部表的数据跟表是分开的,只是表结构和表信息交由hive管理。
外部表还可以将其他数据源中的数据 映射到hive中,比如HBase
设计外部表的初衷就是 让 表的元数据 与 数据 解耦
6.2 分区表
分区表实际上是在表的目录下以分区命名,又创建一个子目录
作用:进行分区裁剪,避免全局扫描,减少MapReduce处理的数据量,提高效率
一般在公司的hive中,所有的表基本上都是分区表,通常按日期分区、地域分区。
分区表在使用的时候记得加上分区字段
分区也不是越多越好,一般不超过3级,根据实际业务衡量
建立分区表 :
create table students_pt
(
id bigint,
name string,
age int,
gender string,
clazz string
)
PARTITIONED BY(pt string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
删除、增加
// 增加一个分区
alter table students_pt add partition(pt='20210614');
// 删除一个分区
alter table students_pt drop if exists partition(pt='20210614');
往分区中插入数据 :
insert into table students_pt partition(pt='20210614');
load data local inpath '/usr/local/soft/data/students.txt' into table students_pt partition(pt='20210614');
查询分区表数据 :
// 全表扫描,效率低
select count(*) from students_pt;
// 使用where条件进行分区扫描,避免全表扫描,效率高
select count(*) from students_pt where pt='20210614';
// 也可以在where条件中使用非等值(一个范围)判断
select count(*) from students_pt where pt<='20210616' and pt>='20210614';