Hive采用类SQL语言HQL进行数据库和数据表的创建、修改、查询、删除等等操作。同时采用HQL语言对表数据进行查询统计分析等操作。表面上hive是通过HQL来进行操作的,但实际底层是基于HDFS、MapReduce、YARN的实现。
只能在Hive的安装节点上使用,无法远程操作。
使用语法:hive 【操作选项】
hive
:会进入hive的交互式命令行窗口
hive -e "HQL语句"
:不需要进入交互式命令窗口也可以执行HQL语句 ,HQL语句也可以有多条,只要保证语句之间以分号分割即可,但是不建议这种方式执行多条HQL语句
hive -f xxx.sql --hiveconf key=value .... --hivevar key=value ......
不需要进入交互式命令行窗口去执行多条HQL语句,只要保证多条HQL语句声明到一个SQL文件即可。多条语句以分号分割,同时SQL文件中注释必须以–空格的形式去声明。
--hiveconf --hivevar
代表向SQL文件传递一个参数,传递的参数在SQL使用的时候,使用的语法:
--hiveconf key=value : ${hiveconf:key}
--hivevar key=value : ${hivevar:key}
可以通过Java代码借助JDBC工具远程连接Hive数据仓库,然后通过网络传递HQL语句以及执行结果。
必须启动hiveserver2,hiveserver2相等于是hive的远程连接服务,专门用来让我们通过JDBC远程连接的。hiveserver2启动之后会给我们提供一个网络端口10000(必须在hive-site.xml文件中配置hiveserver2的相关参数、core-site.xml中允许hiveserver2的用户操作Hadoop集群)。
nohup hiveserver2 1>xxxx.log 2>&1 &
Hive服务的启动和关闭代码比较多的,因此我们可以启动和关闭的命令封装成为一个shell脚本,便于我们后期的操作 hs2.sh
【注意】我们每次开启虚拟机都需要开启hdfs、yarn、jobhistory、hiveserver2,扩展作业:把HDFS、YARN、Jobhistory、hiveserver2的开启封装到一个通用的脚本文件中。
使用Java代码中的原始的JDBC去操作Hiveserver2
使用一些基于JDBC的工具\
dfs 选项操作
!Linux命令
Hive也有DDL语法,DDL语法就是hive用来管理数据库和数据表的语言。虽然Hive使用数据库和数据表来管理结构化数据,但是库和表的底层实现和正宗的数据库是没有任何的关系的。
Hive
create database 【if not exists】 database_name
【comment "注释"】
【location "hdfs的地址"】
【with dbproperties("key"="value","key"="value",........)】
修改数据库的dbproperties:
alter database database_name set dbproperties(key=value.....)
修改数据库的存储位置(hive2.2.1版本之后才支持):
alter database database_name set location "hdfs路径"
show databases;
desc database database_name
desc database extended database_name
drop database database_name
drop database database_name cascade
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name #external 外部的
[(col_name data_type [COMMENT col_comment], ...)] #表字段
[COMMENT table_comment] #表的备注
[PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)] #hive中特有的数据表 分区表
[CLUSTERED BY (col_name, col_name, ...) #hive中特有的数据表 分桶表
[SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS] #分桶表的信息
[ROW FORMAT row_format] #表字段之间的分隔符
[STORED AS file_format] #hdfs存储的文件的类型格式 默认是文本格式
[LOCATION hdfs_path] #单独指定数据表在hdfs上存储的目录,如果没有指定 那么就在表对应的数据库的路径下
hive数据表的分类
管理表/内部表——————删除表,表数据一并删除
外部表——————删除表,表数据在HDFS上依然存在
分区表
将表数据以分区目录的形式在HDFS上进行存储
分区表指定分区字段,分区字段不能是表字段,表字段是要在文件中存储的,分区字段是以目录的形式表示的
多级分区
分桶表
表字段数据最终是以文件的形式存放的,表数据以几个文件进行存储,分桶表的事情
分桶表指定分桶字段,分桶字段一定是表字段,分桶字段结合分桶格式使用hash取值的方式进行文件的分发
支持抽样取值tablesample
hive数据表底层存储文件的分隔符问题
row_format DELIMITED | 说明 |
---|---|
[FIELDS TERMINATED BY char [ESCAPED BY char]] | 列和列之间的分隔符 |
[LINES TERMINATED BY char] | 行和行之间分隔符 \n |
[COLLECTION ITEMS TERMINATED BY char] | 集合、struct、数组等等结构元素之间的分隔符 |
[MAP KEYS TERMINATED BY char] | map集合key value之间的分隔符 |
[NULL DEFINED AS char] | null值用什么字符表示 |
hive支持指定HDFS存储目录、一般不建议指定
Hive中还有两种比较特殊的创建数据表的语法
根据查询语法创建数据表
create table table_name as select查询语句
根据另外一个数据表创建一个新的数据表
create table table_name like other_table_name
创建的新表只有旧表的结构,没有旧表的数据
分区信息和分桶信息也会一并复制
修改表字段
增加/删除表分区目录信息
show tables;
desc table_name;
desc formatted table_name;
drop table if not exists table_name;
类型 | |
---|---|
整数类型 | tinyint |
smallint | |
int/integer | |
bigint | |
布尔类型 | boolean |
小数类型 | float |
double | |
字符串类型 | string |
时间日期有关的类型 | timestamp |
字节类型 | binary |
复杂的数据类型 | array-数组类型 |
map-Java中map集合 | |
struct—Java对象(可以存放多个数据,每个数据的类型都可以不一样) |
Hive中存储的数据是以数据库和数据表的形式进行存储的,因此我们就可以使用DML操作对表数据进行相关的增加、删除、修改等操作。但是因为hive的特殊性,Hive对数据的修改和删除不是特别的支持。
增加数据的语法
普通的insert命令:底层会翻译成为MR程序执行
insert into table_name(表字段) 【partition(分区字段=分区值)】 values(字段对应的值列表),(值列表).......
Hive中基本不用
insert into table_name(表字段) 【partition(分区字段=分区值)】 select 查询语句
insert overwrite table table_name(表字段) 【partition(分区字段=分区值)】 select 查询语句
Hive比较常用 根据一个查询语句添加数据 要求 table_name后面跟的表字段的个数、类型、顺序 必须和查询语句的得到结果一致
多插入语法,从同一个表A查询回来不同范围的数据插入到另外一个表B
form A
insert into/overwrite [table] table_name [partitio(分区字段=分区值)] select 查询字段 where筛选条件
insert into/overwrite [table] table_name [partitio(分区字段=分区值)] select 查询字段 where另外一个筛选条件
如果向表中增加数据,除了insert语法以外,我们还可以通过一些手法来添加数据
按照表格的格式要求,将一个符合格式要求的数据文件上传到数据表的所在HDFS目录下
不建议使用
【注意事项】 如果不是分区表,数据上传成功,表会自动识别 如果是分区表,可能会出现数据上传成功,但是表不识别(分区目录是我们手动创建的),我们修复分区表
msck repair table table_name
创建表的时候指定location, location位置可以存在
load装载命令
也是将文件装载到数据表当中(底层表现就是会把文件移动到数据表所在的目录下),load装载命令相比于手动上传文件而言,load不会出现数据上传无法识别的情况,因此load装载数据会走hive的元数据。
同时手动上传文件到数据表目录下,因为不走元数据,因此我们执行count()命令统计表中的数据行,结果不准确的,因为count()直接从元数据中获取结果。但是如果使用load装载,同样是将文件上传到hive数据表的存储目录,但是load走元数据。
load data [local] inpath "路径" [overwrite] into table table_name [partition(分区字段=分区值)]
local 如果加了local 那么后面路径是linux的路径
如果没有加local 那么路径是HDFS的路径(如果是HDFS上的文件装载,把文件移动到数据表的目录下,原始文件不见)
【注意事项】load装载的文件的格式必须和数据表的分割符一致,列也是对应。否则会出现装载失败或者数据异常。
更新操作
Hive中创建的分区表、管理表、外部表、分桶表默认不支持更新操作
更新操作需要hive的一些特殊手段,hive的事务操作
删除操作
Hive中创建的这些表默认不支持删除部分数据操作,但是支持删除所有数据的操作。
如果要删除表中所有数据,必须使用truncate table table_name 命令是DDL命令
导出操作
将hive数据表中数据导出到指定的目录下存储
export table table_name [partition(分区=值)] to "路径"
导入操作
将hive导出的数据导入到hive中
import [external] table table_name [partition(分区=值)] from "hdfs路径-必须是通过export导出的数据"
如果导入指定分区,分区必须导出目录也存在
create table demo(
hobby array<string>,
menu map<string,double>,
students struct<name:string,age:int,sex:string>
)row format delimited
fields terminated by ","
collection items terminated by "_"
map keys terminated by ":"
lines terminated by "\n";
-- 1、根据查询语句创建数据表:创建的数据表字段会根据查询语句的字段自动确定,类型自动推断
use demo;
create table teacher as select teacher_number as tn,teacher_name from teacher1;
select * from teacher;
-- 2、根据其他表创建一张一样的数据表
create table teacher2 like teacher1;
select * from teacher2;
desc formatted teacher2;
-- 3、创建一个具有复杂数据类型的数据表 必须指定复杂数据类型的元素的分割符
-- array map struct 三个类型都是有多条数据组成的,需要指定数据之间的分隔符
create table demo(
hobby array<string>,
menu map<string,double>,
students struct<name:string,age:int,sex:string>
)row format delimited
fields terminated by ","
collection items terminated by "_"
map keys terminated by ":"
lines terminated by "\n";
-- 向数据表增加特殊数据 insert增加问题比较多,不用insert增加了,而是使用文件添加
select * from demo;
select hobby[0],menu["apple"],students.age from demo;
-- DML操作语法
-- 1、insert增加单条或者多条数据
create table test(
name string,
age int
)row format delimited fields terminated by ",";
insert into test values("zs",20),("ww",30);
insert into test select name,age from test1;
create table test1(
name string,
age int
)partitioned by (timestr string)
row format delimited fields terminated by ",";
insert into test1 partition(timestr="2022") values("zs",20),("ww",30);
insert overwrite table test1 partition(timestr="2022") select name,age from test;
-- 多插入语法,根据多条增加语句增加数据,要求多条增加语句的查询是从同一张表查询过来
from test
insert overwrite table test1 partition(timestr="2022") select name,age
insert overwrite table test1 partition(timestr="2023") select name,age;
-- 修复hive分区表的分区
msck repair table test1;
show partitions test1;