实训笔记8.22

这篇具有很好参考价值的文章主要介绍了实训笔记8.22。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

8.22笔记

一、Hive的HQL语法重点问题

1.1 DDL

1.1.1 Hive中数据表的分类问题

Hive中数据表的分类只是用来告诉我们Hive底层在HDFS上存储的文件的规则和规范

1.1.2 特殊的数据类型

array、map、struct

Hive数据表可以指定底层的存储格式的分隔符问题row format

1.2 DML

Hive中默认不支持批量的删除和更新操作

  1. 增加数据
    1. 装载数据
    2. 追加和覆盖
  2. 删除数据(只能删除所有数据或者某个分区的数据)–truncate
  3. 数据导入和导出问题

1.3 DQL

1.3.1 查询语法和MySQL大部分都是一致的
  1. 排序问题

    1. 全局排序:DQL查询语法转换的MR底层只有一个reduce任务
      order by

    2. 局部排序:DQL查询语法转换的MR底层可以有多个reduce任务,每个reduce的输出有序,整体没有顺序sort by

      如果要使用sort by进行局部排序,那么需要设置Hive底层的转换的MR程序的reduce任务数大于1

      set mapreduce.job.reduces=num>1

      注意:如果我们只是使用了sort by进行排序,并且reduce的任务数大于1,那么mr程序计算的时候底层会对数据进行分区,分区数就是reduce的任务数,默认情况下,如果只使用了sort by,那么分区机制我们是无法控制

      如果我们在局部排序的时候还想控制每个分区的数据,可以在sort by之前增加上一个distribute By 字段,Distribute By和sort by结合使用的,是用于负责控制分区规则的。分区规则是根据我们指定的分区字段的hash值和分区数取余数。

      如果Distribute By和sort by的字段一样,我们可以使用cluster by替代上述两个操作

  2. 连接查询

    Hive支持了全外连接full join

1.4 讲了三个数据库的可视化工具

1.4.1 navicat

界面特别好看的,收费的

一般只能连接RDBMS关系型数据库,连接底层不是基于JDBC

1.4.2 dbeaver
1.4.3 chat2db

增加了AI大模型

1.4.2~1.4.3:都是免费的,底层都是基于JDBC连接数据库
因此这两个软件不仅可以连接常见的RDBMS,还可以连接大数据环境:Hive、Spark等等

二、Hive中重点问题:Hive函数的使用

Hive中提供了很多的自带函数,自带函数有大部分都是为了统计分析设计的。Hive中的函数大部分都是一个Java类

2.1 函数分为两种

UDF:一对一函数
UDTF:一对多函数
UDAF:多对一函数

2.1.1 内置函数
  1. 如何查看系统自带的内置函数

show functions;

desc function 函数名;

desc function extended 函数名;

  1. Hive中常见的一些内置函数的用法

    1. 数学函数:UDF

      函数名 说明
      abs(x) 返回x的绝对值
      ceil(x) 向上取整,返回比x大的正整数中最小的那一个
      floor(x) 向下取整
      mod(a,b) a%b
      pow(a,b) a^b
      round(x,[n]) 四舍五入 如果不传递n 代表小数点不保留,如果n>=1 代表小数点后保留n位
      sqrt(x) 根号x
    2. 字符串函数

      函数名 说明
      concat 直接拼接,拼接需要传递多个参数,会把多个参数拼接起来,如果有一个参数为null值,那么结果直接为null
      concat_ws 可以拼接的分隔符,传递的第一个参数是一个分隔符,如果拼接了null值,null值不计算
      lpad |rpad(str,x,pad) 在str左/右边以指定的pad字符填充字符串到指定的x长度
      ltrim|rtrim|trim(str) 去除空格
      length(x) 返回字符串的长度
      replace(str,str1,replacestr) 将字符串中指定字符串替换成为另外一个字符串
      everse(str) 字符串反转
      split(str,x):array 字符串切割
      substr|substring(str,n,[num]),截取字符串
    3. 日期

      函数名 说明
      current_date() 返回当前的日期 年月日
      current_timestamp() 返回当前时间
      date_format(date,“格式”) 格式化时间的
      datediff(date,date1) 返回这两个时间的差值(天)
    4. 条件判断函数

      函数名
      if
      case when then [when then] … else end
    5. 特殊函数

      1. 和数组、集合操作有关的函数

        函数内部需要传递一个数组,或者返回值是一个数组类型的函数

        函数名 说明
        split(str,spea):array
        collect_set(列名):array 将一列中的所有行的数据封装为一个数组 列转行 不允许重复
        将一列中的所有行的数据封装为一个数组 列转行 允许重复
        array(ele…):array
        map(key,value,key,value,key,value…):map
        concat_ws(spe,array(string)):String 将一个数组中的所有字符串以指定的分隔符拼接得到一个全新的字符串
        explode(array,map集合) 多行多列的数据 炸裂函数 行转列的函数
        如果传递的是array,那么结果是一列多行
        如果传递的是map集合,那么结果就是两列多行

        collect_set(列名):array、collect_list(列名):array

        列转行函数
        将一列的多行数据转换成为一行数据
        UTAF

      2. 和字符串有关的特殊函数:(字符串必须得是URL)

        1. URL的概念

          URL是叫做统一资源定位符,是用来表示互联网或者主机上的唯一的一个资源的
          URL整体上主要有如下几部分组成的:
          协议:http/https、ftp、file、ssh
          host:主机名、域名、ip地址
          port:端口号
          path:资源路径
          queryParam:参数 ?key=value&key=value…

          例子:

          http://192.168.35.101:9870/index.html?name=zs&age=20

          https://www.baidu.com/search/a?key=valueURL

          中,如果没有写端口号,那么都是有默认端口,http:80 https:443 ssh:22

        2. parse_url(urlstr,"特殊字符"):string一次只能提取URL的一个成分

        3. parse_url_tuple(urlstr,"特殊字符"...):每一个成分当作一列单独展示,函数可以将一个数据转换成为一行多列的数据函数多了一个特殊字符:QUERY:key

          parse_url_tuple(urlstr,"特殊字符"...) as (列名...)

          2、3:

          hive提供用来专门用来解析URL的函数:从URL中提取URL组成成分
          特殊字符代表的是URL的组成成分,特殊字符有如下几种:
          HOST:提取URL中的主机名、IP地址
          PATH,:提取URL中资源路径
          QUERY, 提取URL中的所有请求参数
          PROTOCOL, 提起URL中的请求协议
          AUTHORITY,
          FILE,
          USERINFO,
          REF,

      3. 侧视图

        1. 侧视图Lateral View专门用来和UDTF函数结合使用,用来生成一个虚拟表格,然后这个虚拟表格一行数据会生成一个,虚拟表格是动态的,一行数据会生成一个虚拟表格,生成的虚拟表格和当前行做一个笛卡尔乘积,得到一些我们普通SQL无法实现的功能
        2. 侧视图使用场景:一个表格中,某一行的某一列是一个多字段组成的数据,我们想把多字段的列拆分开和当前行结合得到一个多行的结果。
      4. 开窗函数 overselect子语句中

        1. 开窗函数指的是在查询表数据时,将表按照指定的规则拆分成为多个虚拟窗口(并没有真实的拆分、类似于分组),然后可以在窗口中得到一些只有分组之后才能得到一些信息,然后将信息和原始数据结合起来,实现在同一个查询中既可以得到基础字段,还可以得到聚合字段。既需要普通字段还需要一些聚合信息的时候,开窗函数就是最完美的选择。

        2. 语法:

          函数(参数) over(partition by 列名 order by 字段) as 别名-列名

        3. 可以和窗口函数结合使用的主要有三种类型的函数

          1. first_value(col)|last_value(col) over(partition by 列名 order by 字段) as 别名-列名

          2. 聚合函数

            sum/avg/count/max/min over(partition by 列名) as 列别名

          3. 排名函数

            row_number()/rank()/dense_rank() over(partition by 列名 order by 字段) as 列别名

            排名函数的作用就是对数据开窗之后,查询到某一行数据之后,看一下这行数据在所属窗口的排名-位置,然后根据位置打上一个序号,序号从1开始

            函数名 说明
            row_number() 序号是从1开始依次递增,如果两行数据排名一致,也会依次编号
            rank() 序号是从1开始依次递增,如果两行数据排名一致,两行编号一样的 跳排名
            dense_rank() 序号是从1开始依次递增,如果两行数据排名一致,也会依次编号,不会跳排名
          4. 使用场景:求不同组中排名topN的数据信息

2.2 用户自定义函数

用户自定义函数就是我们觉得hive内置函数不满足我们的需求,我们可以自定义函数实现我们想要的功能

2.2.1 Hive自定义函数的步骤

(Hive底层也都是Java,自定义函数也是编写Java代码的)

  1. 创建一个Java项目

  2. 引入编程依赖

    1. 创建lib目录,自己找jar包放到lib目录下,然后lib目录add as library hive的安装目录的lib目录下
    2. 使用maven然后根据gav坐标引入依赖
  3. 编写对应的函数类:UDF、UDTF、UDAF
    大部分自定义都是UDF和UDTF函数

  4. 将编写好的Java代码打成jar包

  5. 将jar包上传到HDFS上

  6. 通过create function …从jar包以全限定类名的方式创建函数

  7. 注意:自定义的函数创建的时候有两种创建方式
    create [temporary] function function_name as “全限定类名” using jar “jar包在hdfs上的路径”

    1. 临时函数:只对本次会话有效
      只可以通过show functions查看,元数据库不会记录
    2. 永久函数:永久生效
      无法通过show functions查看,但是可以通过Hive的元数据库的FUNS表中查看
2.2.2 自定义UDF函数
2.2.3 自定义UDTF函数
2.2.4 删除自定义函数

drop function 函数名

【注意】用户自定义函数有一个特别重要的问题,自定义函数和数据库绑定的。只能在创建函数的数据库使用函数。如果要在其他数据库下使用,需要在其他数据库下把函数重新创建一遍即可。文章来源地址https://www.toymoban.com/news/detail-669180.html

三、相关代码

-- 查看hive自带的所有函数
show functions;
-- 查看某个函数的用法
desc function abs;
-- 查看某个函数的详细用法
desc function extended parse_url;

select sqrt(8);

create table demo(
	name string
);
insert into demo values("zs"),("ls"),("ww");
select * from demo;
select concat_ws("-",collect_set(name)) from demo;



select concat_ws("-",name) from demo;
select concat_ws("-","zs","ls",null);

select rpad("zs",10,"-");

select ltrim("    z   s     ");
select rtrim("    z   s     ");
select trim("    z    s     ");

select replace("2022-10-11","-","/");
select reverse("zs");
select split("zs-ls-ww","-");

select substring("zs is a good boy",9);

select current_timestamp();
select date_format("2022-10-11 20:00:00","HH")
select datediff(current_date(),"2000-10-11");

select if(1>2,"zs","ls");
select 
   CASE 10
   when 10 then "zs"
   when 20 then "ls"
   else "ww"
   END

select 
   CASE 
   	when 1>2 then "zs"
   	when 1<2 then "ls"
   	else "ww"
   END
   
select explode(array(1,2,3,4,5));
select map("name","zs","age","20","sex","man");
select explode(map("name","zs","age","20","sex","man"));

select parse_url("http://www.baidu.com:80/search/a?name=zs&age=30","QUERY");
select parse_url_tuple("http://www.baidu.com:80/search/a?name=zs&age=30","QUERY","PATH","HOST","QUERY:sex") 
as (query,path,host,sex);

-- 侧视图的使用
create table test(
   name string,
   age int,
   hobby array<string>
);

insert into test values("zs",20,array("play","study")),("ls",30,array("sleep","study"));
select * from test;

select name,age,hobby,temp.hb from test
lateral view explode(hobby) temp as hb;

-- 开窗函数的使用
create table student(
	student_name string,
	student_age int,
	student_sex string
);

insert into student values("zs",20,"man"),("ls",20,"woman"),("ww",20,"man"),("ml",20,"woman"),("zsf",20,"man");

select * from student;

-- 查询不同性别的总人数
select student_sex,count(1) from student group by student_sex;
-- 查询表中所有的学生信息,并且每个学生信息后面需要跟上这个学生所属性别组的总人数
select 
   student_name,
   student_age,
   student_sex,
   row_number() over(partition by student_sex order by student_name desc) as sex_count
from student;

-- 排名函数的使用场景
create table employees(
   employees_id int,
   employees_name string,
   employees_dept int,
   employees_salary double
);

insert into employees values(1,"zs",1,2000.0),
							(2,"ls",1,1800.0),
							(3,"ww",1,1700.0),
							(4,"ml",1,2000.0),
							(5,"zsf",1,1900.0),
							(6,"zwj",2,3000.0),
							(7,"qf",2,2500.0),
							(8,"cl",2,2500.0),
							(9,"jmsw",2,2000.0);

select * from employees;
-- 获取每个部门薪资排名前二的员工信息
-- 部门分组 薪资降序排序  排名窗口函数  给每一行数据打上一个序号
select * from(
	select 
	   *,
	   DENSE_RANK() over(partition by employees_dept order by employees_salary desc) as salary_rank
	from employees
) as b
where salary_rank <=2;
package com.sxuek.udf;

import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;

/**
 * 类就是从一个字符串中找大写字符个数的函数
 * UDF
 */
public class FindUpperCount extends GenericUDF {
    /**
     * 初始化方法,方法是用来判断函数参数的
     *   指定函数参数的个数以及函数参数的类型
     * @param objectInspectors   函数参数的类型和个数的一个数组
     * @return  方法的返回值代表的是函数执行完成之后的返回值类型
     * @throws UDFArgumentException
     */
    @Override
    public ObjectInspector initialize(ObjectInspector[] objectInspectors) throws UDFArgumentException {
        /**
         * 1、判断参数的类型和个数是否满足需求
         */
        //数组的长度就是函数参数的个数
        int length = objectInspectors.length;
        if (length != 1){
            throw new UDFArgumentException("function only need one param");
        }else{
            //ObjectInspector是一个Hive数据类型的顶尖父类 参数的类型
            ObjectInspector objectInspector = objectInspectors[0];
            //PrimitiveObjectInspectorFactory是Hive中所有基础数据类型的工厂类
            //返回函数的执行完成之后输出的结果类型  整数类型
            return PrimitiveObjectInspectorFactory.javaIntObjectInspector;
        }
    }

    /**
     * 方法就是函数实现的核心逻辑方法
     * @param deferredObjects   函数传递的参数
     * @return 返回值就是函数执行完成之后的返回结果 返回结果必须和initialize的返回值类型保持一致
     * @throws HiveException
     */
    @Override
    public Object evaluate(DeferredObject[] deferredObjects) throws HiveException {
        //获取函数传递的那一个参数
        DeferredObject deferredObject = deferredObjects[0];
        //get方法是获取封装的参数值
        Object o = deferredObject.get();
        String str = o.toString();
        int num = 0;
        for (char c : str.toCharArray()) {
            if (c >= 65 && c <= 90){
                num++;
            }
        }
        return num;
    }

    /**
     * HQL的解析SQL的输出----没有用处
     * @param strings
     * @return
     */
    @Override
    public String getDisplayString(String[] strings) {
        return "";
    }
}

package com.sxuek.udtf;

import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDTF;
import org.apache.hadoop.hive.serde2.objectinspector.*;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;

import java.util.ArrayList;
import java.util.List;

/**
 *  输入参数有两个:
 *     字符串
 *     分隔符
 *  输出结果 一列多行的结果
 *     word
 *     zs
 *     ls
 */
public class SplitPlus extends GenericUDTF {
    /**
     * 作用:
     *   1、校验输入的参数
     *   2、返回UDTF函数返回的列的个数、名字、类型
     * @param argOIs  当作一个数组来看,里面多个参数组成的
     * @return
     * @throws UDFArgumentException
     */
    @Override
    public StructObjectInspector initialize(StructObjectInspector argOIs) throws UDFArgumentException {
        List<? extends StructField> allStructFieldRefs = argOIs.getAllStructFieldRefs();
        if (allStructFieldRefs.size() != 2){
            throw new UDFArgumentException("function need two params");
        }else{
            /**
             * 返回一列多行 UDTF函数也可以返回多行多列
             */
            //返回的列的名字 是一个集合 集合有几项  代表UDTF函数返回几列
            List<String> columnNames = new ArrayList<>();
            columnNames.add("word");

            //返回的列的类型 集合的个数必须和columnNames集合的个数保持一致
            List<ObjectInspector> columnTypes = new ArrayList<>();
            columnTypes.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);

            //构建StandardStructObjectInspector,需要两个List集合 List<String> List<ObjectInspector>
            StandardStructObjectInspector standardStructObjectInspector = ObjectInspectorFactory.getStandardStructObjectInspector(columnNames,columnTypes);
            return standardStructObjectInspector;
        }
    }

    /**
     * UDTF函数执行的核心逻辑
     *   结果的输出需要借助forward方法
     * @param objects 函数的输入参数
     * @throws HiveException
     */
    @Override
    public void process(Object[] objects) throws HiveException {
        String str = objects[0].toString();
        String split = objects[1].toString();
        String[] array = str.split(split);
        for (String s : array) {
            //一行输出需要输出一次  如果输出一行数据 那么只需要调用一次forward方法即可
            /**
             * 如果一行数据有多列,可以先创建一个List集合,List<Object> 集合中把一行的多列值全部加加进来
             */
            forward(s);
        }
    }

    /**
     * close用于关闭一些外部资源
     * @throws HiveException
     */
    @Override
    public void close() throws HiveException {

    }
}

到了这里,关于实训笔记8.22的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【大数据】Hive SQL语言(学习笔记)

    1)数据库结构 默认的数据库叫做default,存储于HDFS的:/user/hive/warehouse 用户自己创建的数据库存储位置:/user/hive/warehouse/database_name.db 2)创建数据库 comment:数据库的注释说明语句 location:指定数据库在HDFS存储位置,默认/user/hive/warehouse/dbname.db with dbproperties:用于指定一些数

    2024年02月07日
    浏览(46)
  • 黑马大数据学习笔记4-Hive部署和基本操作

    p48、51、52 https://www.bilibili.com/video/BV1WY4y197g7/?p=48 Hive是分布式运行的框架还是单机运行的? Hive是单机工具,只需要部署在一台服务器即可。 Hive虽然是单机的,但是它可以提交分布式运行的MapReduce程序运行。 我们知道Hive是单机工具后,就需要准备一台服务器供Hive使用即可。

    2024年02月14日
    浏览(48)
  • 【Python大数据笔记_day05_Hive基础操作】

     用户在hive上编写sql语句,hive把sql语句转化为MapReduce程序去执行 用户接口:         包括CLI、JDBC/ODBC、WebGUI,CLI(command line interface)为shell命令行;Hive中的Thrift服务器允许外部客户端通过网络与Hive进行交互,类似于JDBC或ODBC协议。WebGUI是通过浏览器访问Hive。         --Hive提供

    2024年01月22日
    浏览(32)
  • ubuntu22.04安装MySQL、Hive及Hive连接MySQL操作

    这篇文章主要讲述的是ubuntu22.04上数据仓库Hive的安装和使用 建议按照文章实践前稍微通读下全文 相关命令: sudo apt-get install mysql-server sudo apt-get install mysql-client 在终端中输入 sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf 修改mysql的配置文件 [mysqld]之后,任意新建一行,添加文本 skip-gr

    2024年02月11日
    浏览(44)
  • 嵌入式培训机构四个月实训课程笔记(完整版)-Linux系统编程第八天-Linux sqlite3数据库(物联技术666)

       更多配套资料CSDN地址:点赞+关注,功德无量。更多配套资料,欢迎私信。 物联技术666_嵌入式C语言开发,嵌入式硬件,嵌入式培训笔记-CSDN博客 物联技术666擅长嵌入式C语言开发,嵌入式硬件,嵌入式培训笔记,等方面的知识,物联技术666关注机器学习,arm开发,物联网,嵌入式硬件

    2024年01月25日
    浏览(66)
  • Sqoop导出hive/hdfs数据到mysql中---大数据之Apache Sqoop工作笔记006

    然后我们看看数据利用sqoop,从hdfs hbase中导出到mysql中去   看看命令可以看到上面这个   这里上面还是mysql的部分,然后看看 下面--num-mappers 这个是指定mapper数 然后下面这个export-dir这里是,指定hdfs中导出数据的目录 比如这里指定的是hive的一个表/user/hive/warehouse/sttaff_hive 然后下

    2024年02月03日
    浏览(47)
  • 实训笔记7.13

    我的故事你说,我的文字我落,我值几两你定,我去何方我挑。 九个核心文件的修改 3.1 HDFS的组成 NameNode DataNode SecondaryNameNode 3.2 HDFS的命令行操作方式 hdfs dfs -xxxx xxxxx 3.3 HDFS的JavaAPI操作方式 FileSystem类

    2024年02月16日
    浏览(45)
  • 实训笔记6.26

    我的故事你说,我的文字我落,我值几两你定,我去何方我挑。 2.1 Java多线程 2.1.1 一些概念知识 程序、进程、线程 单核CPU和多核CPU 并行和并发 2.1.2 多线程的创建方式 继承Thread类,重写run方法 实现Runnable接口,重写run方法 实现Callable接口,重写call方法 使用线程池 缓存线程

    2024年02月11日
    浏览(34)
  • 华为实训课笔记

    ping 基于ICMP协议,用来进行可达性测试 ping +目的IP地址/设备域名(主机名) 如果能收到 reply 回复,则表示双方可以正常通信。一次正常的数据通信必须是有去有回。 Huawei 用户视图,只能做查询和一些简单的资源调用,还有配置保存 Huaweisystem-view 进入系统视图 [Huawei] 系统视

    2024年02月04日
    浏览(35)
  • 实训笔记6.5

    我的故事你说,我的文字我落,我值几两你定,我去何方我挑。 Java基本语法 1、Java的安装和环境变量的配置 JDK、JRE、JVM的区别 环境变量的配置 2、Java的标识符、和保留字 包名:纯小写 类名:大驼峰命名法 方法名和属性名:小驼峰命名法 static final 修饰的属性名:全

    2024年02月08日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包