大数据的数据类型

本文介绍了Hive中的map和struct数据类型,展示了如何在Hive中创建和操作这些数据类型,同时涵盖了bucket排序提高查询效率的方法,正则匹配在数据搜索中的应用,以及union连接查询的规则和注意事项。
摘要由CSDN通过智能技术生成

map数据类型

create table test_db.test_map(
    id int,
    name string,
    members map<string,string>,  --这个map类型数据中存放的键值对,键为string类型,值也为string类型
    age int
)
row format delimited
fields terminated by ','
collection items terminated by '#'
map keys terminated by ':';
--2、向表中导入数据
load data local inpath '/root/hive_data/data_for_map_type.txt' into table test_db.test_map;
--3、查看表中的数据内容
select * from test_map;
--4、查看表的详细信息
desc formatted  test_db.test_map;
--5、map类型的应用
--需求:获取当前学生id和每个家庭成员的姓名
select id,name,members['father'] as father from test_db.test_map;
select id,name,members['mother'] as mother from test_db.test_map;
select id,name,members['brother'] as brother from test_db.test_map;
select id,name,members['sister'] as sister from test_db.test_map;
--需求:找到有哥哥的学员
--如果获取的键不存在返回为null,如果值不是null则证明有哥哥
select * from test_db.test_map where members ['brother'] is not null;
--需求:获取家庭成员为4人的学员
--判断该学院member 有三人,且有自己,就有四个人了
--size查询map类型是计算键值对的数量
select id,name,age from test_map where size(map_values(members))+1 = 4;

struct数据类型

struct数据类型和map数据类型查询时展示效果一致,但是map类型的键是从源文件中读取的,而struct中的键是我自己定义的

--1、创建一个数据表,用来处理struct数据
create  table  test_db.struct_tb(
    id string,
    info struct<name:string,age:int>
)
row format delimited
fields terminated by '#'
collection items terminated by ':';
--2、导入数据内容
load data local inpath '/root/hive_data/data_for_struct_type.txt' into table test_db.struct_tb;
--3、查询表中的数据内容
select * from struct_tb;
--4、struct的使用方式和map基本相同
--需求:获取所有学生的学号和姓名
select id,info.name from struct_tb;
--结论:map和struch相比,map的键实在数据内部的,而struct的键是我们手动定义的

hive查询语句

CREATE DATABASE itheima;
USE itheima;
CREATE TABLE itheima.orders (
               orderId bigint COMMENT '订单id',
               orderNo string COMMENT '订单编号',
               shopId bigint COMMENT '门店id',
               userId bigint COMMENT '用户id',
               orderStatus tinyint COMMENT '订单状态 -3:用户拒收 -2:未付款的订单 -1:用户取消 0:待发货 1:配送中 2:用户确认收货',
               goodsMoney double COMMENT '商品金额',
               deliverMoney double COMMENT '运费',
               totalMoney double COMMENT '订单金额(包括运费)',
               realTotalMoney double COMMENT '实际订单金额(折扣后金额)',
               payType tinyint COMMENT '支付方式,0:未知;1:支付宝,2:微信;3、现金;4、其他',
               isPay tinyint COMMENT '是否支付 0:未支付 1:已支付',
               userName string COMMENT '收件人姓名',
               userAddress string COMMENT '收件人地址',
               userPhone string COMMENT '收件人电话',
               createTime timestamp COMMENT '下单时间',
               payTime timestamp COMMENT '支付时间',
               totalPayFee int COMMENT '总支付金额'
) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
load data local inpath '/home/hadoop/it_orders.txt' into table itheima.orders ;
select * from orders;
--查询指定的列
select orderId,userid,totalmoney from orders;
--在指定列中进行计算
select orderId,userid,totalmoney+200 from orders;
--可以增加一个列,内部数据为固定值
select orderId,userid,totalmoney,'有效订单'as is_valid from orders;
--4、条件查询
--比较查询
select orderId,userid,totalmoney from orders
where totalmoney>10000;
--不等查询
select orderId,userid,totalmoney from orders
where userid !=2;
--逻辑查询
select orderId,userid,totalmoney from orders
where(totalmoney>10000) and (userid !=6);
--是否存在
select orderId,userid,totalmoney from orders
where userid in(1,3,6,9);
--范围查询
select orderId,userid,totalmoney from orders
where totalmoney between 10000 and 20000;
--5、聚合查询
select count(*) from orders;
select max(totalmoney)from orders;
--6、分组查询
select paytype,sum(totalmoney)from orders
group by paytype;
--7、分组筛选
select paytype,sum(totalmoney)from orders
group by paytype
having sum(totalmoney)>10000;
--8、排序查询
select orderId,userId,totalmoney from orders
order by userid desc ;
--9、分页查询 limit m,n(m代表起始位置,n代表数据条目数)
select orderId,userId,totalmoney from orders
limit 0,50;

数据连接

CREATE TABLE itheima.users (
                               userId int,
                               loginName string,
                               loginSecret int,
                               loginPwd string,
                               userSex tinyint,
                               userName string,
                               trueName string,
                               brithday date,
                               userPhoto string,
                               userQQ string,
                               userPhone string,
                               userScore int,
                               userTotalScore int,
                               userFrom tinyint,
                               userMoney double,
                               lockMoney double,
                               createTime timestamp,
                               payPwd string,
                               rechargeMoney double
) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
LOAD DATA LOCAL INPATH '/home/hadoop/it_users.txt' INTO TABLE itheima.users;
select * from users;
--1、内连接
--根据连接字段的匹配规则判断,匹配成功则保留,失败则忽略
select * from orders o join  users u on o.userId = u.userId;
--2、左外连接
--保留左表中的全部数据,右表中的数据匹配成功则保留失败则忽略
select * from orders o left join users u on o.userId = u.userId;
--3、右外连接
--保留右表中的全部数据,左表中数据匹配成功则保留失败则忽略
select * from orders o right join users u on o.userId = u.userId;
--左外连接和右外连接记住一个就可以,主表再左左连接和右右连接结果过相同
---------------------以上为mysql5.x中相同的连接方式--------------------------------------
--4、全外连接
--保留左表和右表的全部数据,匹配成功则保留,匹配不成功则忽略
select * from orders o full join users u on o.userId = u.userId;
--5、左半连接
--进行一次内连接,但是只返回左表中的数据,右表中的数据忽略
select * from orders o left semi join users u on o.userId = u.userId;
--6、交叉连接(笛卡尔积)
select * from (select * from orders limit 5) o cross join (select * from users limit 5) u;
--交叉连接在开发中用的比较少,因为效率不高,且没有必须使用交叉连接的场景

桶内排序

桶内排序,就是对于分桶表进行每一个筒内的强制排序,与全局排序相比效率更高

创建分桶排序

--1、创建一个分桶排序表
/*create  table 表名(
    字段名1 字段类型,
    字段命2 字段类型
    .......
)
clustered by (分桶字段)
sorted by (排序字段 desc | asc) into n buckets
*/
create database test_db;
use test_db;
create table  test_db.student_buck_sort
(
    id int,
    name string,
    gender string,
    age int,
    class string
)
--按照id分桶,age排序(升序) 分成3桶,默认分隔符为   ,
clustered by (id) sorted by (age) into 3 buckets
row format delimited fields terminated by ',';
--2、查看表的详细信息
desc formatted test_db.student_buck_sort;
--3、导入数据
load data local inpath '/home/hadoop/students.txt'  into table test_db.student_buck_sort;
--4、查看数据表
select * from student_buck_sort;

补充:

1、桶内排序表会将我们写入表中的数据强制进行桶内排序

2、桶内排序顾名思义就是将一个分桶内的数据按照制定规则排序,所以操作顺序也是先分桶,在排序

3、分桶和排序可以是相同字段,也可以是不同字段,但是必须是表中实体字段

4、使用这种方式创建表后,导入的数据会自动分桶并排序,这种排序方式是在自己的桶内进行排序·

查询时分桶排序

注意:一定要先修改分桶数量,后续操作才能有分桶效果

set mapreducce.job.reduces=3;

--1、创建一个普通的非分桶表
create table test_db.students(
    id int,
    name string,
    gender string,
    age int,
    class string
)
row format delimited fields terminated by ',';
--2、给students加载数据
load data local inpath '/home/hadoop/students.txt' into table test_db.students;
--3、查看数据是否映射成功
select * from students;
--4、全局排序 order by
select * from students order by id;
--5、分桶排序 cluster by
select * from students cluster by id;
--通过执行发现,此时排序结果完全相同,因为cluster by 的分桶数量是按照reducetask数量决定的
--6、修改reducetask数量为3
set mapreduce.job.reduces; --默认值是-1  代表适用场景自行判断reducetask数量
set mapreduce.jon.reduces = 3;
--7、修改后进行分桶排序
select * from students cluster by id;
--此时,按照id进行分桶,且按照id升序进行排序
--8、修改后进行全局排序
select * from students order by id;
--所以在数据量较大时,order效率远低于cluster by,在开发中我们尽量避免使用order by
--9、distribute  by (仅分桶) + sort by(仅排序)
--因为cluster by 具有局限性,分桶和排序字段必须相同,且只能使用升序排序,所以使用distribute by+sort  by 更加灵活
--需求:按照id进行分桶,按照年龄进行降序排序
select * from students distribute by id sort by age desc;
--sort by 是在桶内进行排序  而  order by 是全局排序,不能对同一个数据集使用
--同理:当我们使用相同的字段分桶且排序,并且升序排序时,distribute by + sort by 就等价于cluster by

为什么一般要在查询时分桶排序,不在建表时操作?

建表时分桶字段一定是经常用于连接或者查询的字段,有些字段我们不经常连接,偶尔使用一次且想提高连接效率,则可以使用该方法,分桶排序,排序效率比全局排序效率高,所以我们使用分桶排序代替全局排序。

正则匹配

正则匹配:就是使用正则表达式的语法规则去匹配符合规则的字符串信息

之前我们学过模糊查询like语法,但是在开发中几乎不用,因为查询效率太低,如果要进行模糊查询,我们会使用正则匹配,关键则时rlike

--正则匹配使用的关键词rlike
--需求一:从orders表中查找广东省的数据
--like _代表任意一个字符   %代表任意多个字符
select * from orders where userAddress like '广东省%';
--rlike .代表任意字符,*代表出现任意多次
select * from orders where userAddress rlike '广东.*';
--需求二:从orders表中查找惠州市的数据
select * from orders where userAddress like '%惠州市%';
select * from orders where  userAddress rlike '.*惠州市.*';
--需求三:查询订单中有7为数字的订单编号
select * from orders where orderNo like '_______';
--like 此处其实之哦按段了7位但是没有判断是否为数字
--rlike 正则表达式的灵活性,准确性更高,并且可以适配多种函数使用
select * from orders where orderNo rlike  '\\d{7}';

1、正则表达式是一种非常晦涩的语法,且在复杂的规则下,正则表达式可读性极差

2、但是几乎所有的编程语言都天然支持正则表达式,所以不好学,但逃不开、

3、正则表达式的学习目标就是可以根据网上的正则表达式进行常规修改即可

union连接查询

--union联合查询,是将数据纵向连接在一起的一种方式
--1、先将所需的数据查询出来,查询t_id=周杰轮 和 t_id=林均街的学院
--2、使用union联合查询,将两个结果纵向连接到一起
select * from text_db.course where t_id='周杰轮'
union
select * from text_db.course where t_id='林均街';
--3、如果我们查询两次周杰轮的数据,并且使用union联合查询进行连接,最终结果会有几条数据?
select * from text_db.course where t_id='周杰轮'
union
select * from text_db.course where t_id='周杰轮';
--union 会自动去重 等价 union distinct
--如果需要纵向连接且不希望去重可以使用union all
select * from text_db.course where t_id='周杰轮'
union all
select * from text_db.course where t_id='周杰轮';
--4、union联合查询时,上下两张表的字段数量和字段类型必须一致,字段值不需要相同
--字段名不一致,但是字段数量和数据类型一直们可以连接成功
select c_id,c_name from course
union
select c_id,t_id from course;
--如果字段数量不一致则联合查询失败
select * from corse
union
select c_id,t_id from course;
--如果字段的数据类型不一致则联合查询失败或者数据有误
select 10,c_name from course
union
select t_id,c_name from course;
--5、unoin联合查询后,数据顺序不是两个表一次书写的,二十随机排序,如果要对于联合查询排序,需要联合查询结束后再排序,否则顺序依然混乱
select c_id,c_name from course
unoin
select c_idmt_id from course
order by c_id;
--6、联合查询可以使用union连接多个表
select * from course where  t_id='周杰伦'
union 
select * from course where t_id='周杰伦'
union 
select * from course where t_id='林俊杰';

1、union联合查询会在连接后自动去重,如果不需要去重,则使用union all

2、union联合查询,会在查询后子哦当按照哈希值进行排序,我们无法控制,如果需要排序,在合并完成后排序

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值