学会了Hive的一些操作,发现Hive建过表,后续的数据并不是向MySQL是通过自己手写进行插入的,而是将TXT文件解析成为数据表的操作。其实是HDFS将文件映射成Hive表,然后然后通过写类SQL的语句来操作该文件,底层会被解析成为MR程序。
Hive的本质
把HDFS文件映射成一张Hive表, 然后通过写类SQL的语句来操作它(HDFS文件), 底层会被解析成MR程序, 交由Yarn来调度执行.
DDL(Data Define Language)是什么?
见名知意,数据定义语言
==Data Define Language
。
对数据库的操作
:包含创建(Create)数据库,数据表、修改数据库 (Alter table)
对数据表的操作
:内部表(Managed Table)及外部表(External),分区表(Partition)和分桶表
数据库Operation
1 2 3 4 5 6 7
| create database if not exists 数据库名;
show databases;
use 数据库名;
drop database 数据库名 casecade;
|
切割符
Hive表默认切割符是'\001'符号, 在windows中显示为 SOH, 在HDFS中显示为 小口, 在Linux中显示为 ^A
数据类型
1 2 3 4 5 6 7 8 9 10 11 12
| 常用的数据类型: 原生类型: int 整数 double 小数 string 字符串 timestamp 时间戳 date 日期(年月日) 复杂类型: array 数组类型 map 字段(映射)类型 struct 结构体 union 联合体
|
原因是: 我们的Hive表是UTF-8码表, Hive的元数据存在MySQL中, 用的GBK码表, 码表不一致导致的.
解决方案: 保持码表一致即可, 我们去MySQL中修改Hive元数据信息的码表, 改为: UTF-8
具体步骤:
- Step1: 先通过DataGrip连接node1机器的MySQL, 账号: root, 密码: 123456 当然, 也可以直接在CRT中连接MySQL数据库.
- Step2: 在MySQL中执行如下的内容即可, 详见MySQL的文件. 细节: 还要去hive-site.xml文件中修改下码表.
- Step3: 重启metastore服务 和 hiveserver2服务.
- Step4: 在Hive中把刚才的表删掉, 然后重建, 再次查询, 注释(描述信息)不乱码了.
具体步骤如下:
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
| show databases ; use hive3;
# (1)修改表字段注解和表注解 use hive3; alter table COLUMNS_V2 modify column COMMENT varchar(256) character set utf8; alter table TABLE_PARAMS modify column PARAM_VALUE varchar(4000) character set utf8;
# (2)修改分区字段注解
alter table PARTITION_PARAMS modify column PARAM_VALUE varchar(4000) character set utf8 ; alter table PARTITION_KEYS modify column PKEY_COMMENT varchar(4000) character set utf8;
# (3)修改索引注解
alter table INDEX_PARAMS modify column PARAM_VALUE varchar(4000) character set utf8;
#
<! <property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql://node1:3306/hive3?createDatabaseIfNotExist=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8</value> </property>
|
建表语法
建表语法:
create [external] table [if not exists]
表名(
列名 数据类型 [ comment ‘描述信息’],
列名 数据类型 [ comment ‘描述信息’],
列名 数据类型 [ comment ‘描述信息’],
……
) comment ‘表的描述信息’
分区
分桶(桶内排序 + 分桶个数)
行格式切割符
存储格式(行存储, 列存储)
存储位置
表的属性信息;
建表, 表字段, 数据类型等要和 HDFS源文件保持一致
建表并制定分隔符为\t
1 2 3 4 5 6 7 8 9 10 11 12
| create table archers( id string comment 'ID', name string comment '英雄', hp_max string comment '最大生命', mp_max string comment '最大法力', attack_max string comment '最高物攻', defense_max string comment '最大物防', attack_range string comment '攻击范围', role_main string comment '主要定位', role_assist string comment '次要定位' ) comment '射手信息' row format delimited fields terminated by '\t';
|
上传源文件(5种方式)
上传源文件到Hive表所在的 HDFS路径下
1 2 3 4
| load data local inpath '/root/archer.txt' overwrite into table archers;
load data inpath '/wordcount/archer.txt' into table archers;
|
哪里来的5种方式,细数一下
上传Linux文件到hdfs中,有两种方式,追加写入和覆盖写入
上传hdfs文件到hdfs中,有两种方式,追加写入和覆盖写入
通过hdfs端口8979上传文件,这是Hadoop3.x的特性,2.x好像不行
查看表结构信息
三种方式
1 2 3
| desc archers; desc formatted archers; show create table archers;
|
其它的建表方式
1 2 3
| create table archer1 as select * from archers; create table archer2 row format delimited fields terminated by ',' as select * from archers; create table archer3 like archers;
|
修改表 相关操作
1 2 3 4 5 6 7 8 9 10 11 12 13
| alter table archer1 rename to archers1;
alter table archers1 set location '/root/aa';
alter table archers1 set tblproperties('EXTERNAL'='TRUE'); alter table archers1 set tblproperties('EXTERNAL'='FALSE');
alter table archer2 add columns (address string, tel string); alter table archer2 change address addr string;
drop table archer2; truncate table archer2;
|
面试题: 内部表 和 外部表的区别是什么?
格式不同.
直接创建Hive表默认就是内部表, 如果要创建外部表, 必须用 external 关键字.
删除时是否会删除源文件.
删除内部表的时候, 除了会删除元数据, 还会删除源文件.
删除外部表的时候, 只会删除元数据, 但是源文件(HDFS上)还在.
应用场景不同.
删除Hive的时候, 如果也要同步删除源文件, 就用内部表. 否则就用外部表, 例如: Hbase 和 Hive的映射.
分区表之 静态分区
分区表详解:
概述/作用:
1. 分区 = 分文件夹, 即: 把1个整体 拆分成 n个文件夹, 避免全表扫描, 提高查询效率.
2. 例如: 公司成立10年所有的数据都在1个文件夹中放着, 查找数据, 每次都要全表扫描, 效率相对较低.
可以按照 年月分区, 把每年每月的数据都放一起, 这样查找时只要找指定的内容即可, 降低扫描次数, 提高效率.
格式:
create table 表名() partitioned by(分区字段1 数据类型, 分区字段2 数据类型…) row format ……;
细节:
分区字段必须是表中没有的字段.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| create table t_all_hero_part ( id string comment 'ID', name string comment '英雄', hp_max string comment '最大生命', mp_max string comment '最大法力', attack_max string comment '最高物攻', defense_max string comment '最大物防', attack_range string comment '攻击范围', role_main string comment '主要定位', role_assist string comment '次要定位' ) comment '王者荣耀英雄表' partitioned by (role string) row format delimited fields terminated by '\t';
|
1 2
| load data local inpath '/root/archer.txt' into table t_all_hero_part partition (role='sheshou');
|
分区表之 动态分区
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| create table t_all_hero_part_dynamic ( id string comment 'ID', name string comment '英雄', hp_max string comment '最大生命', mp_max string comment '最大法力', attack_max string comment '最高物攻', defense_max string comment '最大物防', attack_range string comment '攻击范围', role_main string comment '主要定位', role_assist string comment '次要定位' ) comment '王者荣耀英雄表' partitioned by (role string) row format delimited fields terminated by '\t';
|
1 2 3 4 5 6
| set hive.exec.dynamic.partition.mode; set hive.exec.dynamic.partition.mode=nonstrict;
insert into t_all_hero_part_dynamic partition (role) select *,role_main from t_all_hero;
|
分区表二级分区
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| create table stu_part( id int, name string, gender string, age int, sno string ) partitioned by (year string, month string) row format delimited fields terminated by ',';
insert into stu_part partition (year='2023',month='03') select * from stu; show partitions stu_part; alter table stu_part add partition (year='2022',month='02'); alter table stu_part partition(year='2022',month='02') rename to partition (year='2022',month='03'); alter table stu_part drop partition (year='2022',month='03');
|