首页 > 数据库 >HiveSQL(一)

HiveSQL(一)

时间:2022-10-19 01:11:30浏览次数:75  
标签:string int HiveSQL 分区 student table data

内容大纲:
1. 掌握HQL DDL 数据定义语言 //针对表的
数据类型
SerDe序列化机制
分隔符语法
内部表、外部表
数据存储路径
分区表
分桶表
alter修改表
2. 掌握HQL DML 数据操作语言 //针对表数据的
load加载数据
insert插入数据
多重插入
动态分区插入
数据导出

********************************* 具体内容 *********************************

  1. HQL DDL语句_建表语法详解
    概述:
    数据定义语言, 全称是 Data Definition Language, 主要是操作数据库, 数据表, 字段的.
    关键字:
    create, alter, drop
    HQL DDL建表语法完整格式解释:
    //详见图片.

  2. HQL DDL语句_数据类型详解
    概述:
    Hive中的数据类型指的是Hive表中的列字段类型。Hive数据类型整体分为两个类别:
    原生数据类型包括: //primitive data type
    数值类型: int, double,float
    时间类型: date
    字符串类型: string
    杂项数据类型; miscellaneous
    复杂数据类型包括: //complex data type
    数组: array //类似于Python中的列表
    映射: map //类似于Python中的字典
    结构: struct
    联合体: union

    注意事项:
    1. Hive不区分大小写.
    2. int 和 string 是使用的最多的数据类型.
    3. 复杂数据类型的使用通常需要 和 分隔符指定语法配合使用.

     4. 如果定义的数据类型和文件不一致, hive通常会尝试隐式转换, 但是不保证成功.
    

    名词解释:
    隐式转换: //也叫: 自动类型转换, 隐转
    概述:
    指的是 原生类型 从窄类型 到 宽类型的转换.
    例如:
    int => double //即: 10 => 10.0

     显式转换:	//也叫: 强制类型转换, 强转
     	格式:
     		cast(数值 as 目标数据类型)		//使用cast()函数实现.
     	例如:
     		cast("10.3" as double)			//结果是: 10.3
     		cast(10.3 as int)				//结果是: 10
     		cast("false" as double)			//结果是: NULL, 即: 如果强制转换失败, 则函数返回NULL
    

    更多Hive中的数据类型描述, 请参考:
    https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Types

  3. HQL DDL语句_SerDe, 原生数据类型案例
    SerDe解释:
    SerDe是Serializer、Deserializer的简称,目的是用于序列化和反序列化。
    序列化是对象转化为字节码的过程, 而反序列化是字节码转换为对象的过程。
    Hive使用SerDe(和FileFormat)读取和写入行对象。
    //简单记忆: 写 是 序列化, 读 是 反序列化.

    SerDe相关语法(多用,记清楚):
    在Hive的建表语句中,和SerDe相关的语法为:
    row format delimited/serde
    delimited: //使用默认的LazySimpleSerDe类来处理数据, 这个是我们用的最多的.

     		fields terminated by char				//字段分隔符
     		
     		collection items terminated by char		//列表分隔符
     		
     		map keys terminated by char				//映射分隔符
     		
     		lines terminated by char				//行分隔符
     		
     	serde:		//如果要用其它的SerDe类, 甚至是用户自定义的SerDe类规则, 则使用这种方式.
     	
     		with serdeproperties	//允许用户自定义SerDe规则, 目前用不到, 后期NoSQL阶段会用到.
    

    原生数据类型案例(入门demo,可不看):
    需求:
    文件archer.txt中记录了手游《王者荣耀》射手的相关信息,内容如下所示,其中字段之间分隔符为制表符\t,要求在Hive中建表映射成功该文件。
    //文件在 day08_hive\资料\sql脚本、数据集\hive练习数据集\honor of kings\hero\archer.txt

     步骤: 
     	1. 创建Hive表:
     		create database if not exists itheima;
     		use itheima;
     		create table t_archer(
     			id int comment "ID",
     			name string comment "英雄名称",
     			hp_max int comment "最大生命",
     			mp_max int comment "最大法力",
     			attack_max int comment "最高物攻",
     			defense_max int comment "最大物防",
     			attack_range string comment "攻击范围",
     			role_main string comment "主要定位",
     			role_assist string comment "次要定位"
     		) comment "王者荣耀射手信息"  
     		row format delimited fields terminated by "\t";
     	
     		desc t_archer;				//查看表结构信息, 即: 字段名, 数据类型, 描述信息
     		desc formatted t_archer;	//查看表结构信息, 详细信息.
     		
     	2. 把 archer.txt 文件上传到 HDFS的 t_archer 表下.
     		HDFS路径:  /user/hive/warehouse/itheima.db/t_archer
     	
     	3. 在Hvie中查询 t_archer 表的信息, 有数据即可.
     		select * from t_archer;
    
  4. HQL DDL语句_复杂数据类型案例(map案例,也可以不看,前提是不需要练习了)
    需求:
    文件hot_hero_skin_price.txt中记录了手游《王者荣耀》热门英雄的相关皮肤价格信息,内容如下,要求在Hive中建表映射成功该文件
    //文件在 day09_hive\资料\sql脚本、数据集\hive练习数据集\honor of kings\hot_hero_skin_price.txt

    步骤:
    1. 创建Hive表.
    create table t_hot_hero_skin_price(
    id int,
    name string,
    win_rate int,
    skin_price map<string,int>
    )
    row format delimited fields terminated by ','
    collection items terminated by '-'
    map keys terminated by ':';

     2. 把 archer.txt 文件上传到 HDFS的 t_hot_hero_skin_price 表下.
     		HDFS路径:  /user/hive/warehouse/itheima.db/t_hot_hero_skin_price
     
     3. 在Hvie中查询 t_hot_hero_skin_price 表的信息, 有数据即可.
     	select * from t_hot_hero_skin_price; 
     	
     4. 新的需求: 查询 孙悟空 大圣娶亲 这款皮肤的价格.
     	select name, skin_price['大圣娶亲'] from t_hot_hero_skin_price limit 1;
    
  5. HQL DDL语句_默认分隔符案例
    需求:
    //文件在 day09_hive\资料\sql脚本、数据集\hive练习数据集\honor of kings\team_ace_player.txt

    步骤:
    1. 创建Hive表.
    create table t_team_ace_player(
    id int,
    team_name string,
    ace_player_name string
    );

     2. 把 team_ace_player.txt 文件上传到 HDFS的 t_team_ace_player 表下.
     		HDFS路径:  /user/hive/warehouse/itheima.db/t_team_ace_player
     
     3. 在Hvie中查询 t_team_ace_player 表的信息, 有数据即可.
     	select * from t_team_ace_player; 
    

    结论:
    1. hive的默认分隔符是 \001, 在Linux中它是一个不可见字符,就是它在编码表中没有对应的字符. 在linux中显示为^A,在Notepad++中显示的是 SOH.
    2. \001 如果想在Linux中打印出来, 可以按下 Ctrl V + Ctrl A 实现.

  6. HQL DDL语句_关于Hive文件的存储路径的问题

    1. 存储路径由hive.metastore.warehouse.dir 属性指定。默认值是:/user/hive/warehouse

    2. 不管是内部表,还是外部表,在HDFS上的路径如下:
      /user/hive/warehouse/数据库名.db/表名

    3. 在建表的时候 可以使用location关键字指定表的路径在HDFS任意位置, 例如:
      create table t_team_ace_player_location(
      id int,
      team_name string,
      ace_player_name string
      ) location '/data/aaa'; //使用location关键字指定本张表数据在hdfs上的存储路径

      !!!/ location '/data' 的本质是,把我们的表建到/data/目录下,表对应的文件名更名为aaa,即:/aaa就表示我们这张表.(重点)

    4. 在实际开发中,最好集中维护管理Hive表数据,避免文件在HDFS随意存放。

  7. HQL DDL语句_内部表和外部表详解

    内部表:正常创建的表
    外部表:用external关键字创建的表,删除表的时候不会删除源文件,只删除元数据
    区别:
    1.删除表的时候,内部表的元数据连同源文件都会被删除.
    2.创建内部表直接写,默认的都是内部表,创建外部表需要加external关键字.

    外部表的好处:
    防止误操作删除表的时候 把表的数据一起删除。

    案例:
    //创建内部表
    create table student_inner(Sno int,Sname string,Sex string,Sage int,Sdept string) row format delimited fields terminated by ',';

     //创建外部表 关键字external
     create external table student_external(Sno int,Sname string,Sex string,Sage int,Sdept string) row format delimited fields terminated by ',';
    
     //上传文件到内部表、外部表中, 文件在: day08_hive\资料\sql脚本、数据集\hive练习数据集\honor of kings\students.txt
     hadoop fs -put students.txt /user/hive/warehouse/itheima.db/student_inner
     hadoop fs -put students.txt /user/hive/warehouse/itheima.db/student_external
     
     //查询表数据, 好像没啥区别 都能映射成功 数据也都在HDFS上
     select * from student_inner;
     select * from student_external;
    

    针对内部表、外部表 进行drop删除操作
    drop table student_inner; //内部表在删除的时候 元数据和数据都会被删除
    drop table student_external; //外部表在删除的时候 只删除元数据 而HDFS上的数据文件不会动

    结论:外部表只删除hive中的元数据,不会删除源文件,内部表则会把元数据和源文件都删除了.

    如何知道表是 内部表 还是 外部表呢?
    desc formatted 表名; 显示出的信息,找table_type字段就知道了
    //MANAGED_TABLE 内部表、受控表
    //EXTERNAL_TABLE 外部表

  8. HQL DDL语句_分区表的由来 分区的本质:分文件夹(分目录)

    具体见图片中图3.

    所有的数据源文件都集中在一起,每次查询数据的时候,都需要把所有的文件
    检索一下,即:满查询(全查询).效率相对较低.

    如何才能够减少全表扫描 而结果又正确。
    将文件分区(分文件夹),这样查询具体信息时可以只查单个文件夹中的文件,提高查询效率.

    分区表的目的: //详见图片

     分区字段必须是表中不存在的字段, 目的是: 把 整表  变成=> n个表  管理, 提高Hive的查询效率.
    
  9. HQL DDL语句_分区表的创建及添加数据

    1. 根据角色主定位字段进行分区 字段是role_main

    2. 分区表建表
      create table t_all_hero_part(
      id int,
      name string,
      hp_max int,
      mp_max int,
      attack_max int,
      defense_max int,
      attack_range string,
      role_main string,
      role_assist string
      ) partitioned by (role string)
      row format delimited fields terminated by "\t";

    3, 查询分区表 发现分区字段也显示出来了,说明分区后它会给我们补充分区字段.
    select * from t_all_hero_part;

    1. 分区表的数据加载 之 静态分区加载
      4.1 静态加载分区表数据
      load data local inpath '/export/data/hivedata/archer.txt' into table t_all_hero_part partition(role='sheshou');/role是分区字段, 它的值 就是分区后, 文件夹的名字.
      load data local inpath '/export/data/hivedata/assassin.txt' into table t_all_hero_part partition(role='cike');
      load data local inpath '/export/data/hivedata/mage.txt' into table t_all_hero_part partition(role='fashi');
      load data local inpath '/export/data/hivedata/support.txt' into table t_all_hero_part partition(role='fuzhu');
      load data local inpath '/export/data/hivedata/tank.txt' into table t_all_hero_part partition(role='tanke');
      load data local inpath '/export/data/hivedata/warrior.txt' into table t_all_hero_part partition(role='zhanshi');
      !!! /role是分区字段, 它的值 就是分区后, 文件夹的名字.

      4.2 查询一下验证是否加载成功
      select * from t_all_hero_part;

      4.3 思考:如果分区很多 一个一个加载,效率如何?
      因为静态分区的时候 分区值是用户手动写死的 有写错的风险,所以一般使用动态分区。
      静态分区就是插入数据的时候分区值是写死的,动态是根据插入的对应字段的值自动分区.

    2. 分区表的数据加载 之 动态分区加载
      5.1 设置允许动态分区、设置动态分区模式
      //动态分区
      set hive.exec.dynamic.partition=true; //注意hive3已经默认开启了

       set hive.exec.dynamic.partition.mode=nonstrict;  //关闭严格模式
       	//模式分为strict严格模式  nonstrict非严格模式, 严格模式要求 分区字段中至少有一个分区是静态分区。
       	//例如: partition(province='河南省', city)	 这里的province因为有固定值, 所以是静态分区, city没有值, 所以是动态分区.
      

      5.2 通过 insert + select 实现动态分区
      插入的数据来自于后面的查询语句返回的结果。查询返回的内容,其字段类型、顺序、个数要和待插入的表保持一致。

      5.3 案例
      5.3.1 创建一张新的分区表 t_all_hero_part_dynamic
      create table t_all_hero_part_dynamic(
      id int,
      name string,
      hp_max int,
      mp_max int,
      attack_max int,
      defense_max int,
      attack_range string,
      role_main string,
      role_assist string
      ) partitioned by (role string)
      row format delimited fields terminated by "\t";

       5.3.2 执行动态分区插入  	//注意 分区值并没有手动写死指定
       	insert into table t_all_hero_part_dynamic partition(role) 
       	select tmp.*, tmp.role_main from t_all_hero tmp;
      
       5.3.3 查询验证结果
       	select * from t_all_hero_part_dynamic;
      
  10. HQL DDL语句_多级分区表的用法
    记忆:
    实际开发中, 多分区一般最多只有2层分区, 且大多数都是按照日期划分的.

    相关操作:
    1. 查询指定表的分区.
    //创建多分区表.
    create external table student_part(
    Sno int,Sname string,Sex string,Sage int,Sdept string
    ) partitioned by(year string, month string)
    row format delimited fields terminated by ',';

    2. 查看该表的分区, 因为刚造的表, 所以没有分区. 
    	show partitions student_part;
    
    3. 手动添加分区. 
    	load data local inpath '/export/data/hivedata/students.txt' into table student_part partition(year="2020",month='01');
    
    	alter table student_part add partition(year="2020",month='03');
    	alter table student_part add partition(year="2021",month='01');
    	alter table student_part add partition(year="2021",month='05');
    
    4. 查看分区
    	show partitions student_part;
    
    5. 删除分区
    	alter table student_part drop partition(month='01');	-- 所有标记为1月的分区全部删除.
    

    总结:多级分区表就相当于树形结构罢了,目录下还有目录,没啥

  11. HQL DDL语句_分桶操作详解
    细节:
    分桶字段必须是表中存在的.
    分桶公式:
    分桶字段的哈希值 % 分桶个数 = ...
    分桶的目的是:
    1. 检查表的join操作, 提高查询效率.
    2. 方便我们进行数据抽样.

    案例:
    //源数据格式: 2021-01-28,Washburn,Wisconsin,55129,1288,19 统计时间,县,洲,县的编码,确诊人数,死亡人数
    1. 创建分桶表
    CREATE TABLE t_usa_covid19_bucket(
    count_date string,
    county string,
    state string,
    fips int,
    cases int,
    deaths int)
    clustered by(state) INTO 5 BUCKETS; //分桶的字段一定要是表中已经存在的字段

    	CREATE TABLE t_usa_covid19_bucket(
    		  count_date string,
    		  county string,
    		  state string,
    		  fips int,
    		  cases int,
    		  deaths int)
    	clustered by(state) sorted by(cases desc) INTO 5 BUCKETS; 		//按照洲分桶, 且分桶之后桶内按照确诊人数排序.
    
    2. 创建和该分桶表字段对应的 普通表.
    	CREATE TABLE t_usa_covid19(
    		  count_date string,
    		  county string,
    		  state string,
    		  fips int,
    		  cases int,
    		  deaths int)
    	row format delimited fields terminated by ',';
    
    3. 往普通表中添加数据. 
    	hadoop fs -put .....
    
    4. 查看普通表中的数据
    	select * from t_usa_covid19 limit 10;
    
    5. 把普通表的数据添加到分桶表中.
    	insert into t_usa_covid19_bucket select * from  t_usa_covid19;
    

    分桶图解:
    见图片图4

  12. HQL DDL语句_其他语句
    //查询类的:掌握, 其它操作大多理解或者了解, 因为Hive基本上查询操作居多, 更改操作较少.

    1. 创建数据库, 指定创建者的名字. //了解
      create database bigdata52 with dbproperties('createBy'='hangge');

    2. 查看数据库的信息.
      show databases; -- 查看所有数据库.
      show create database bigdata52; -- 查看某个数据库的创建信息.

    3. 删除数据库 //理解
      drop database bigdata52; //如果数据库是空库, 可以直接删.
      drop database itcast cascade; //如果数据库有数据表, 需要额外加关键字 cascade

    4. 查看表的信息.
      desc student_inner;
      desc formatted student_inner; -- 查看表的详细信息.
      show create table student_inner; -- 查看某个数据表的创建信息.

    5. 修改表名 //了解
      create table temp_my(id int, name string); //造表.
      alter table temp_my rename to tmp;

    6. 添加字段 //了解
      alter table tmp add columns(gender string);

    7. 关于分区的操作 //重点关注一下.
      show partitions student_part; //查看某表所有分区
      alter table student_part add partition(year='2020',month='10'); //添加分区.
      alter table student_part drop partition(year='2020',month='03'); //删除分区.

  13. HQL DML语句_load方式加载数据
    案例:
    演示DML相关操作: 数据操作语言, 主要是对表数据进行 更新操作(增, 删, 改).

    具体的HQL语句:
    show functions; //查看hive支持的所有函数.

    准备动作:
    //创建数据表, 3张表. 源数据格式: 95001,李勇,男,20,CS
    //建表student_local 用于演示从本地加载数据
    create table student_local(num int,name string,sex string,age int,dept string) row format delimited fields terminated by ',';

    //建表student_HDFS  用于演示从HDFS加载数据到非分区表
    create table student_HDFS(num int,name string,sex string,age int,dept string) row format delimited fields terminated by ',';
    
    //建表student_HDFS_p 用于演示从HDFS加载数据到分区表
    create table student_HDFS_p(num int,name string,sex string,age int,dept string) partitioned by(country string) 
    row format delimited fields terminated by ',';
    

    load data 四种情况:

    	-- 方式1: 从本地(Linux)加载数据到 Hive的 内部表/外部表/分桶表中.
    	load data local inpath '/export/data/hivedata/students.txt' into table student_load_linux;
    
    	-- 方式2: 从本地(Linux)加载数据到 Hive的 分区表中.
    
    	load data local inpath '/export/data/hivedata/students.txt' into table student_load_linux_partition partition(year='2022',month='06');
    
    
    	-- 方式3: 从HDFS文件系统中, 加载数据到Hive 内部表/外部表/分桶表中.
    	-- 导入数据, 不带local就是HDFS文件系统.
    	load data inpath '/hg/students.txt' into table student_load_hdfs;       -- 类似于 hadoop fs -mv.. 的操作, 就是: 剪切.
    
    	
    	-- 方式4: 从HDFS文件系统中, 加载数据到Hive 分区表.
    	-- 导入数据.
    	load data inpath '/hg/students.txt' into table student_load_hdfs_partition partition(year='2022',month='06');

标签:string,int,HiveSQL,分区,student,table,data
From: https://www.cnblogs.com/nanguyhz/p/16804789.html

相关文章