4.6 Hive 核心操作
库操作
- 查看数据库列表
show databases;
- 选择数据库
use default;
- 创建数据库
create database mydb1;
- 在hdfs目录下查看创建的数据库
- 删库(敏感操作)
drop database mydb1;
表操作
- 创建表
create table t2(id int);
- 查看表结构
describe t2;
- 查看表创建信息
show create table t2;
- 重命名
alter table t2 rename to t2_bak;
- 加载数据
我们在Linux上创建一个名为t2.data的文件
里面存放数据
1
2
3
4
5
load data local inpath '/data/soft/hivedata/t2.data' into table default.t2_bak
即可加载数据文件数据到表中
除了这种方式外,hdfs还支持可视化操作,直接在文件浏览器中可视化的上传数据到表指定文件夹下即可映射数据结构
- 查看表中数据
select * from t2_bak;
- 表增加字段及注释、删除表
在工作中会有给已存在的表增加字段的需求,需要使用alter命令 在这里我们给t2_bak表增加一个name字段,重新查看表结构信息,再查询一下这个表中的数据,结果发 现,第二列为null,这是正常的,因为我们的数据数据文件中就只有一列,第二列查询不到,就显示为 null,不会报错,这一点要注意一下。
alter table t2_bak add columns (name string);
- 删除表
drop table t2;
- 指定列和行分隔符的指定
create table t3_new( id int comment 'ID', stu_name string comment 'name', stu_birthday date comment 'birthday', online boolean comment 'is online' )row format delimited fields terminated by '\t' lines terminated by '\n';
案例:Hive复合数据类型实操
Array
数组数据结构
举例数据:
序号 |
姓名 |
爱好 |
1 |
zhangsan |
swing,sing,coding |
2 |
lisi |
music,football |
这里爱好一列就是Array数据结构
建表语句如下:
create table stu( id int, name string, favors array<string> ) row format delimited fields terminated by '\t' collection items terminated by ',' lines terminated by '\n';
加载数据语句:
load data local inpath '/data/soft/hivedata/stu.data' into table default.stu
查询结果:
-- 查询全部 hive (default)> select * from stu; stu.id stu.name stu.favors 1 zhangsan ["swing","sing","coding"] 2 lisi ["music","football"] -- 查询所有学生的第二个爱好 hive (default)> select id,name,favors[1] from stu; 1 zhangsan sing 2 lisi football
角标是从0开始的,如果查询不到会返回null值
Map
map集合里面存储的是键值对
举例数据:
序号 |
姓名 |
成绩 |
1 |
zhangsan |
chinese:80,math:90,english:100 |
2 |
lisi |
chinese:89,english:70,math:88 |
这里成绩就是map数据结构
建表语句如下:
create table stu2( id int, name string, scores map<string,int> ) row format delimited fields terminated by '\t' collection items terminated by ',' map keys terminated by ':' lines terminated by '\n';
加载数据:
load data local inpath '/data/soft/hivedata/stu2.data' into table default.stu2
查询结果:
-- 查询全部 hive (default)> select * from stu2; stu2.id stu2.name stu2.scores 1 zhangsan {"chinese":80,"math":90,"english":100} 2 lisi {"chinese":89,"english":70,"math":88} -- 查询所有学生的语文和数学成绩 hive (default)> select id,name,scores['chinese'],scores['math'] from stu2; id name _c2 _c3 1 zhangsan 80 90 2 lisi 89 88
Struct
结构体这种数据类型有点像Java中的对象
举例数据
序号 |
姓名 |
地址(户籍地址,公司城市) |
1 |
zhangsan |
bj,sh |
2 |
lisi |
gz,sz |
建表语句如下:
create table stu3( id int, name string, address struct<home_addr:string,office_addr:string> ) row format delimited fields terminated by '\t' collection items terminated by ',' lines terminated by '\n';
这里的地址字段我们就以结构体来定义,用于区分用户的家庭住址和工作地点
查询数据:
-- 查询所有 hive (default)> select * from stu3; stu3.id stu3.name stu3.address 1 zhangsan {"home_addr":"bj","office_addr":"sh"} 2 lisi {"home_addr":"gz","office_addr":"sz"} -- 查询用户家庭住址 hive (default)> select id,name,address.home_addr from stu3; id name home_addr 1 zhangsan bj 2 lisi gz
Struct与Map对比
- map中可以随意增加k-v对的个数 struct中的k-v个数是固定的
- map在建表语句中需要指定k-v的类型 struct在建表语句中需要指定好所有的属性名称和类型
- map中通过[]取值 struct中通过.取值,类似java中的对象属性引用
- map的源数据中需要带有k-v struct的源数据中只需要有v即可
综合应用案例
举例数据
序号 |
姓名 |
爱好 |
成绩 |
地址(户籍地址,公司城市) |
1 |
zhangsan |
english,sing,swing |
chinese:80,math:90,english:100 |
bj,sh |
2 |
Lisi |
games,coding |
chinese:89,english:70,math:88 |
gz,sz |
建表语句:
create table student ( id int comment 'id', name string comment 'name', favors array<string> , scores map<string, int>, address struct<home_addr:string,office_addr:string> ) row format delimited fields terminated by '\t' collection items terminated by ',' map keys terminated by ':' lines terminated by '\n';
生产场景
问:在mysql中有一张表student(id,name),还有一张表address(stu_id, home,school),还有联系方式表contact(stu_id,mine,parents,others)。如果把这三张表迁移到hive中, 如何迁移?
答: 可以一一对应迁移,优点是迁移成本非常低,包括DDL和业务逻辑,几乎不需要修改,可以直接使用。缺 点是产生大量的表连接,造成查询慢。 可以一对多,mysql中的多张关联表可以创建为hive中的一张表。优点是减少表连接操作。缺点是迁移成 本高,需要修改原有的业务逻辑。 实际上,在我们日常的开发过程中遇到这样的问题,要想比较完美、顺利的解决,一般都分为两个阶段, 第一个阶段,现在快捷迁移,就是上面说的一一对应,让我们的系统能跑起来,在此基础之上呢,再做一 张大表,尽量包含以上所有字段,例如: stu(id, name, address struct<home,school>, contact struct<…>); 等第二个阶段完工之后了,就可以跑在新的系统里面了。