Hive入門&基本操作


Hive

什么是 Hive

  • Hive 是由 FaceBook 開源的,用於解決海量結構化日志數據的統計

  • Hive 是基於 Hadoop 的一個數據倉庫,可以將結構化日志數據映射為一張表,提供類 SQL 的查詢功能:HQL (Hive Query Language)

  • Hive 的本質是將 HQL 轉化為 MapReduce 程序(將 HQL 對應的功能,轉化為使用 MapReduce 來實現)

  • Hive 處理的數據存儲在 HDFS 上

  • Hive 分析數據的底層的默認實現是 MapReduce

  • 執行程序運行在 yarn 上

Hive 優缺點

優點

  • 采用類 SQL 的寫法,提供快速開發能力
  • 避免去寫 MapReduce 減少開發學習成本
  • Hive 執行延遲比較高,適用於數據分析,因此 Hive 優勢在於處理大數據,小數據的處理沒有優勢
  • Hive 支持自定義函數

缺點

  • 迭代式(將前一個的計算結果作為后一個計算的輸入)算法無法表達
  • 數據挖掘方面不擅長
  • Hive 自動生成的 MapReduce ,通常情況下不夠智能化

Hive 架構

Hive 與數據庫比較

  • Hive 除了采用類 SQL 的查詢語言外,與數據庫再無類似之處
  • Hive 是針對數據倉庫設計的,數據倉庫的內容通常是讀多寫少,不建議使用 Hive 對數據進行改寫,所有的數據都是在加載時就確定好的,若一定要使用 Hive 對數據進行改寫,可以先將數據下載下來,再進行修改,然后上傳到 Hive 的數據倉庫,但是效率極低,而數據庫的改寫效率則高得多
  • Hive 中沒有索引,查詢數據時,需要遍歷整張表,延遲較高,同時,Hive 默認使用的是 MapReduce 的計算框架,此框架本身具有高延遲,相反,數據庫的執行延遲很低
  • Hive 建立在集群上,支持的數據規模很大,對應的,數據庫的數據規模相對較小

Hive 的安裝 .(環境搭建重點 )

注: Hive 的安裝最好使用完全安裝的 Linux ,最小安裝的 Linux 在 安裝 MySQL 時會有各種問題

資源下載

安裝流程

  • 解壓 Hive 安裝包

  • 配置 Hive 環境變量

    • HIVE_HOME

      export HIVE_HOME={Hive 安裝路徑}
      export PATH=$PATH:$HIVE_HOME/bin

  • 初始化元數據庫(注:此步驟在配置 hive-site.xml 后再執行)

    • schematool -dbType derby -initSchema
  • 啟動 Hive

    • hive

Hive 使用.(數據分析重點)

簡單使用

  • show databases; 顯示數據庫
  • show tables; 顯示表
  • create table 表名 (字段名 字段類型); 創建表
  • insert into 表名 (字段名) values ( 字段值); 插入數據
  • select * from 表名; 查詢表信息
  • 補充
    • Hive 是基於 hdfs 的,存儲的表數據,默認在 hdfs 的 user / hive 目錄下可以找到

MySQL 安裝

  • 查看是否安裝過 MySQL
    • rpm -qa | grep mariadb
  • 若安裝過,卸載
    • rpm -e --nodeps mariadb-libs
  • 解壓 MySQL
    • tar -xvf mysql-5.7.28-1.el7.x86_64.rpm-bundle.tar -C 【指定一個目錄】
  • 安裝 MySQL
    • 來到 MySQL 解壓目錄
    • 按照順序執行
      • rpm -ivh mysql-community-common-5.7.28-1.el7.x86_64.rpm
      • rpm -ivh mysql-community-libs-5.7.28-1.el7.x86_64.rpm
      • rpm -ivh mysql-community-libs-compat-5.7.28-1.el7.x86_64.rpm
      • rpm -ivh mysql-community-client-5.7.28-1.el7.x86_64.rpm
      • rpm -ivh mysql-community-server-5.7.28-1.el7.x86_64.rpm
    • 刪除 /etc/my.cnf 文件中 datadir 指向的目錄下的所有內容(如果有的情況下)
    • 初始化數據庫
      • mysqld --initialize --user=mysql
    • 查看臨時生成的 MySQL 密碼
      • cat /var/log/mysqld.log
    • 啟動 MySQL 服務
      • systemctl start mysqld
    • 登錄 MySQL 數據庫,使用之前臨時的 MySQL 密碼
      • mysql -u root -p
    • 修改 root 用戶的初始密碼
      • set password = password("新密碼");
    • 允許任意 ip 連接
      • update mysql.user set host='%' where user='root';
      • flush privileges;

Hive 配置元數據到 MySQL.( 環境搭建重點 )

  • 在 $HIVE_HOME/conf 目錄下新建 hive-site.xml

    • vim $HIVE_HOME/conf/hive-site.xml
  • 添加如下內容

    • <?xml version="1.0"?>
      <?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
      <configuration>
       <!-- jdbc 連接的 URL -->
       <property>
           <name>javax.jdo.option.ConnectionURL</name>
           <value>jdbc:mysql://主機名:3306/metastore?useSSL=false</value>
       </property>
       <!-- jdbc 連接的 Driver-->
       <property>
           <name>javax.jdo.option.ConnectionDriverName</name>
           <value>com.mysql.jdbc.Driver</value>
       </property>
       <!-- jdbc 連接的 username-->
       <property>
           <name>javax.jdo.option.ConnectionUserName</name>
           <value>root</value>
       </property>
       <!-- jdbc 連接的 password -->
       <property>
           <name>javax.jdo.option.ConnectionPassword</name>
           <value>mysql密碼</value>
       </property>
       <!-- Hive 元數據存儲版本的驗證 -->
       <property>
           <name>hive.metastore.schema.verification</name>
           <value>false</value>
       </property>
       <!--元數據存儲授權-->
       <property>
           <name>hive.metastore.event.db.notification.api.auth</name>
           <value>false</value>
       </property>
       <!-- Hive 默認在 HDFS 的工作目錄 -->
       <property>
           <name>hive.metastore.warehouse.dir</name>
           <value>/user/hive/warehouse</value>
       </property>
       <!-- 指定存儲元數據要連接的地址 -->
      <property>
      	<name>hive.metastore.uris</name>
      	<value>thrift://主機名:9083</value>
      </property>
      </configuration>
      
  • 登錄 MySQL ,創建元數據庫

    • create database metastore;
  • 將 mysql 驅動添加到 Hive 的 lib 目錄下

  • 初始化元數據庫

    • schematool -initSchema -dbType mysql -verbose
  • 啟動 Hive

    • hive
  • 使用 Hive 測試一下元數據庫

    • show tables;

總結補充

  • 關於元數據庫 & Hive & HDFS 的解析
    • Hive 中的創建的表,插入到數據等,實際上並不是直接放入元數據庫 MySQL 中的,而是存儲在 HDFS 文件系統上的,MySQL 元數據庫 metastore 中存儲的,實際上是創建的表和插入的數據在 HDFS 存儲時的文件路徑,在 MySQL 元數據庫 metastore 中,有 DBS 和 TBLS 兩張表,DBS 中存儲的是 Hive 創建的數據庫在 HDFS 中保存的路徑信息,TBLS 中保存的是 Hive 創建的表在 HDFS 中保存路徑的信息,當在 Hive 中執行查詢語句時,實際上就是在元數據庫的 DBS 和 TBLS 中找到對應的 HDFS 文件路徑,將數據庫和表對應的文件路徑拼接起來,就是 HDFS 文件系統上保存數據的位置
      • 例如,數據庫的元數據為: hdfs://master-3.x-wfb:8020/user/hive/warehouse 表的有元數據為: test,那么 test 表的數據在 HDFS 上保存的路徑就為: hdfs://master-3.x-wfb:8020/user/hive/warehouse/test
    • 通過上面的說明,可以看出,在 Hive 上,插入數據,創建表等操作的順序,可以隨意,只要保證元數據庫中有對應的元信息,HDFS 上有對應的路徑,路徑下有對應的數據即可,哪怕不創建表,只要在 HDFS 上有對應的數據,直接查詢也是可以的

使用元數據服務的方式訪問 Hive.( 了解即可 )

  • 在 Hive-site.xml 中添加如下配置信息

    • <!-- 指定存儲元數據要連接的地址 -->
      <property>
       <name>hive.metastore.uris</name>
       <value>thrift://主機名:9083</value>
      </property>
      
  • 啟動 metastore

    • hive --service metastore
    • 注: 啟動后,該窗口不能再操作,需要新起一個窗口
  • 啟動 Hive

    • hive
  • 注: 該操作只是為外部提供一個調用的端口,使得外部可以通過該端口連接到 Hive

使用 JDBC 方式訪問 Hive.( 了解即可 )

注: 上面的元數據和JDBC連接方式都只做演示,為了后續方便操作,將 hive-site.xml 中涉及到的配置文件注釋掉即可

補充: Hive 其他命令操作

  • exit; (退出 hive)
  • dfs -ls 指定路徑 (查看 hdfs 文件目錄)
  • set; (查看當前所有的配置信息)

Hive 常用交互命令

  • hive -e "sql 語句;" (不進入 hive ,直接執行 sql 語句)
  • hive -f 【sql 文件路徑】(執行 sql 文件)
  • hive -f 【sql 文件路徑】> 【文件路徑】(將執行的結果存入指定文件中)
  • cat .hivehistory (查看當前用戶在 hive 中執行的所有命令,需要進入當前用戶家目錄)

補充

  • select count(*) from 表名; 沒有運行 MR 任務的原因
    • 在 MySQL 的元數據中,保存了表的行數,因此,不會運行 MR 任務
  • select count(*) from 表名; 查詢結果與實際不符的原因
    • 若是直接使用 hadoop fs -put 命令向表對應的 HDFS 文件系統中添加的數據,那么,MySQL 的表中元數據沒有更新,查詢的結果也就不相符

Hive 數據類型

  • 基本數據類型

    • 補充

      • 對於時間類型 TIMESTAMP ,只要將字符串寫成 yyyy-MM-dd,Hive 就能自動轉換為時間類型
  • 集合數據類型

    • 補充

      • 集合數據類型之間支持嵌套
  • 案例實操

    • 源數據

      • songsong,bingbing_lili,xiao song:18_xiaoxiao song:19,hui long guan_beijing
        yangyang,caicai_susu,xiao yang:18_xiaoxiao yang:19,chao yang_beijing

    • 建表

      • create table test2(
        name string,
        friends array ,
        children map<string, int>,
        address struct<street:string, city:string>
        )
        row format delimited fields terminated by ',' // 字段之間使用 ,分割
        collection items terminated by '_' // 集合(包括 array 和 struce 以及 map )元素之間使用 _ 分割
        map keys terminated by ':' // map 的 key 和 value 之間使用 : 分割
        lines terminated by '\n'; // 每一行數據使用 \n 分割,默認就為 \n

    • 插入數據

      • 直接將文件上傳到 test2 表 在 hdfs 對應的路徑即可
    • 補充

      • 三種集合的訪問方式
        • select friends[數組下標],children['key 值'],address.元素名 from test2
      • 查看完整的創建表
        • show create table 表名
      • 查看創建數據庫的完整語句
        • show create database 數據庫名

DDL 數據定義

DDL:數據定義語言,用來創建 & 修改 & 刪除數據庫,表,視圖,索引等

創建數據庫

  • 直接創建一個數據庫
    • create database 數據庫名
  • 創建數據庫時,判斷是否存在
    • create database if not exists 數據庫名 location '數據庫在 hdfs 上的路徑'
  • 創建數據庫到指定的 hdfs 文件路徑
    • create database if not exists 數據庫名 location '數據庫在 hdfs 上的路徑'

查詢數據庫

  • 顯示所有數據庫
    • show databases;
  • 過濾顯示數據庫
    • show databases like '數據庫名(支持正則)';
  • 顯示數據庫信息
    • desc database '數據庫名';
  • 顯示數據庫詳細信息
    • desc database extended '數據庫名';
  • 切換當前數據庫
    • use '數據庫名';

修改數據庫

  • 修改數據庫屬性
    • alter database 數據庫名 set dbproperties("屬性名"="屬性值");
    • 例如: alter database stu set dbproperties("createTime"="2020-10-23");

刪除數據庫

  • 刪除空數據庫
    • drop database 空數據庫名
  • 強制刪除數據庫
    • drop database 數據庫名 cascaed;

創建表

  • 建表語句解析

    • CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name
      [(col_name data_type [COMMENT col_comment], ...)]
      [COMMENT table_comment]
      [PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)]
      [CLUSTERED BY (col_name, col_name, ...)
      [SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS]
      [ROW FORMAT row_format]
      [STORED AS file_format]
      [LOCATION hdfs_path]
      [TBLPROPERTIES (property_name=property_value, ...)]
      [AS select_statement]
      /*
      EXTERNAL: 外部的,Hive 的表有內外之分
      COMMENT 注釋:表的注釋
      PARTITIONED BY: 分區表
      CLUSTERED BY: 分桶表
      SORTED BY (col_name [ASC|DESC], ...) INTO num_buckets BUCKETS: 分桶表
      ROW FORMAT 行格式: 定義行的格式
      STORED AS 文件格式: 定義文件格式
      LOCATION hdfs路徑: 指定表在 hdfs 上的存儲路徑
      TBLPROPERTIES (屬性名=屬性值, ...): 表的額外屬性
      AS select_statement: 從查詢出來的結果創建表,創建的表自帶查詢出的數據
      */
      
  • 內 | 外部創建表 & 區別

    • Hive 默認創建的表都是管理表,也叫內部表,Hive 會或多或少的控制這些數據的生命周期,默認情況下,表中的數據被存放在由配置項所定義的 hdfs 路徑的子路徑下,刪除表時,對應路徑下的數據也被刪除,管理表不適合與其他工具共享數據
    • 外部表,顧名思義,表是外部的,Hive 並非完全擁有這份數據,刪除表時,只會刪除該表在元數據庫中對應的元數據,而 hdfs 上保存的數據並為被刪除
  • 內 | 外部表轉換 & 查看

    • 內 | 外部表轉化
      • alter table 表名 set tblproperties('EXTERNAL'='FALSE'); 修改為內部表
      • alter table 表名 set tblproperties('EXTERNAL'='TRUE'); 修改為外部表
    • 查看表的類型
      • desc formatted 表名
    • 內部表轉外部表
      • alter table 表名 set tblproperties ("EXTERNAL"="TRUE");
    • 外部表轉內部表
      • alter table 表名 set tblproperties("EXTERNAL"="FALSE");

以指定分隔符分割字段創建表

  • 創建表
    • create table test4(id int,name string) row format delimited fields terminated by ','; 創建字段之間以逗號分割的表
  • 插入數據
    • insert into test4 values (1001,'zhangsan');
    • 對應的,在 hdfs 中,數據保存的格式,字段之間也是以逗號分割,同樣的,直接創建一個同樣分割符格式的文件存放到表對應的 hdfs 路徑上,也能被以同樣格式創建的表所讀取並且能夠查詢到,相反的,不同格式的數據,若和表存放在同樣路徑下,分割后的字段數據,不能轉換和不存在的值,都用 NULL 表示,就算存在能夠轉換的值,轉換出的結果,因為分隔符不符,數據也可能不相符

修改刪除表

  • 修改表名字
    • alter table 表名 rename to 新表名;
  • 增加 | 修改 | 替換表的列信息
    • 修改列
      • alter table 表名 change 舊列名 新列名 新列名數據類型;
    • 增加和替換
      • alter table 表名 add | replace clumns (列名,數據類型);
      • 注: add 代表在所有字段后增加一列字段,replace 代表替換表中所有字段(replace 的字段,會覆蓋表中的所有字段,也就是說,可以通過 replace 刪除增加修改表中的某一個字段)
  • 刪除表
    • drop table 表名;

DML 數據操作

DML: 數據操作語言,對數據的增 & 刪 & 改操作

向表中裝載數據

  • load data [local] inpath '導入的數據的路徑' [overwrite] into table 表名 [partition (partcol1=val1,…)];
    • local 代表在本地加載文件,不加則在 hdfs 上查找,將 hdfs 上對應的文件移動到表對應的路徑下
    • overwrite 代表是否重新覆蓋表中的內容,不加則不覆蓋其中的內容
    • partition (partcol1=val1,…) 上傳到分區

基本插入數據

  • insert into table 表名 values (值1,值2 ...),(值1,值2);

基本模式插入

  • 以查詢的方式插入數據
    • insert into table 表名 查詢語句
    • insert overwrite table 表名 查詢語句
    • 補充
      • into 向表中添加數據
      • overwrite 覆蓋表中的數據

查詢語句創建表並導入數據

  • create table if not exists 表名 as select * from 表名

建表時通過 Location 指定表在 hdfs 上的路徑

  • create table 表名 (id int,name string) row format delimited fields terminated by '/t' location 'hdfs 上的路徑';

Import 導入數據

Insert 導出數據

  • 導出到本地
    • insert overwrite local directory '本地路徑' 查詢語句;
  • 格式化導出到本地
    • insert overwrite local directory '本地路徑' row format delimited fields terminated by '分割符' 查詢語句;
  • 將查詢結果導出到 hdfs 上
    • insert overwrite directory '本地路徑' row format delimited fields terminated by '分割符' 查詢語句;

清除表中的數據

  • truncate table student;
    • truncate 只能清除管理表(內部表)中的數據,外部表不能清除

查詢

單表查詢 & 常用函數 & 運算符

  • 查詢全表 & 指定列 & 注意事項

    • 查詢全表
      • select * from 表名
    • 查詢指定列
      • select 列名 form 表名
    • 注意事項
      • 在 linux 命令行,不能直接使用 tab 進行 sql 格式的調整
  • 別名 & 運算符 & 常用函數

    • 別名
      • select 列名 列別名 from 表名
    • 運算符
      • +,-,*,/,%
    • 常用函數
      • count(); 計數
      • max(); 最大值
      • min(); 最小值
      • sum(); 求和
      • avg(); 平均值
  • 聚合函數 Limit & Where

    • Limit 限制返回的行數
      • select * from 表名 limit 5; 只返回前五行
      • select * from 表名 limit 0,5; (偏移量從 0 開始,代表第一行,返回前 5 條記錄)
    • Where 限制查詢的條件
      • select * from 表名 where 查詢條件
  • 比較運算和邏輯運算符

  • group by & having 分組

    • 按照某字段分組

      • select 字段1,字段2 from 表名 group by 字段1;
      • 若只按照一個字段進行分組,那么其余字段的值就只能有一種情況,否則,分組條件就必須加上其余字段
      • 分組的實質就是將字段值相同的作為一個組,將不同字段之間不同的值的組合都呈現出來,例如,若使用了 count() 函數,則相同組的 count() 函數的值就會累加,類似於 MR 程序中 wordCount 的執行原理
    • 對分組后的字段進行條件限制

      • select 字段1,字段2 from 表名 group by 字段1 having 字段1 > 1000;
    • 補充

      • group by 子句必須出現在 where 子句之后,‎order by 子句之前. having 語句必須在 order by 子句之后。(where 先執行,再 group by 分組;group by 先分組,having 再執行;order by 子句在 group by 之后,having 之前)
      • 通過 where 篩選結果,group by 進行分組,order by 進行排序,再使用 having 進行數據的過濾
      • having 彌補了 where 不能和聚合函數(對一組值進行計算,返回單一結果)使用的缺陷

多表查詢

join 語句
  • 內連接 join
    • 只有進行連接的兩個表中都存在與連接條件相匹配的數據才會被保留下來
      • select e.empno,e.ename,d.deptno from emp e join dept d on e.deptno = d.deptno
  • 左外連接 left join
    • 以 left join 左邊的表為准,根據 on 條件返回結果,當右邊表存在不滿足左邊表的字段時,該字段以 NULL 代替
      • select e.empno, e.ename, d.deptno from emp e left join dept d on e.deptno = d.deptno;
    • 當使用了 where 子句時,left join 左邊表滿足 where 子句的數據將會被返回
  • 右外連接
    • 以 right join 右邊的表為准,根據 on 條件返回結果,當左邊表存在不滿足右邊表的字段時,該字段以 NULL 代替
      • select e.empno, e.ename, d.deptno from emp e right join dept d on e.deptno = d.deptno;
    • 當使用了 where 子句時,right jion 右邊表滿足 where 子句的數據將會被返回
  • 全外連接
    • 以 full join 兩邊的表為准,根據 on 條件返回結果,任意表中存在不滿足的字段時,該字段以 NULL 代替
      • select e.empno, e.ename, d.deptno from emp e full join dept d on e.deptno = d.deptno;
    • 當使用 where 子句時,若子句條件以左邊表為准,那么查詢的是左表獨有的數據,若子句條件以右表為准,那么查詢出的數據為右表獨有數據,若子句條件包含兩張表且用 and 連接,查詢的是兩張表共有的數據,若以 or 連接,則查詢出的是兩張表所有的數據
  • 笛卡爾積(表A的每一行與表B之間的每一行數據都連接上了,總共的連接數是 A 表行數 * B 表行數)
    • 笛卡爾積會在下面的條件下產生
      • 省略了連接條件
      • 連接條件無效
      • 所有表的所有行本來就是相互對應的

排序

常用排序

  • order by 全局排序,只使用一個 reduce 來執行排序任務
    • order by asc 升序(默認)
    • order by desc 降序
    • order by 子句在 select 語句結尾使用
    • order by 字段1,字段2 按照多個列排序
  • sort by 對於大規模的數據,order by 的全局排序並不適用,使用 sort by 可以對每一個 reduce 產生一個排序文件
    • 使用方法
      • 設置 reduce 個數
        • set mapreduce.job.reduces = reduce 個數;
      • 查看設置的 reduce 個數
        • set mapreduce.job.reduces;
      • 使用 order by 子句進行分區排序
        • select e.deptno,e.empno,e.ename from emp order by e.deptno
        • 按照 deptno 字段進行升序排序,將排序的文件分為 (reduce 個數) 個分區,Hive 中,在不指定分區規則的情況下,使用的分區方式是隨機的,也就是說,被排序的數據被放到那個分區中也是隨機的
  • distribute by 按照某一字段進行分區
    • select * from emp distribute by ename sort by deptno;
      • 按照 ename 字段進行分區,每個分區內,按照 deptno 進行排序
  • cluster by 當 sort by 和 distribute by 依照的字段相同時使用 cluster by
    • 一下兩種寫法等價
      • select * from emp distribute by empno sort by empno;
      • select * from emp cluster by empno;

分區

分區簡介

  • 分區實際上就是將一張表的內容分為多個部分,對於小數據量的表,該操作對執行效率的影響不大,但是當數據量大時,分區后的表,可以指定在那個分區進行查詢,避免了查詢時,直接查詢全表,效率極低
  • 每個分區對於的實際上就是 hdfs 上的一個文件夾,該文件夾中保存的是該分區中的表數據

創建分區表

  • 數據准備

    • 分區1

      10 ACCOUNTING 1700
      20 RESEARCH 1800

      分區2

      30 SALES 1900
      40 OPERATIONS 1700

      分區3

      50 TEST 2000
      60 DEV 1900

  • 創建分區表

    • hive (default)> create table dept_partition( deptno int, dname string, loc string) partitioned by (day string) row format delimited fields terminated by '\t';
      • partitioned by (day string)
        • 該字段是一個分區字段,意為該表屬於那個分區
  • 加載數據到分區表

    • load data local inpath '/opt/software/dept3.txt' overwrite into table dept_par partition (day = '2020-10-25');
      • 加載數據時,需要使用 partition (分區字段 = '字段值'); 來指定該數據加載到表的那個分區中
  • 單分區查詢

    • select * from dept_par where day = '2020-10-23';
  • 多分區聯合查詢

    • select * from dept_par where day = '2020-10-23' or day = '2020-10-24';
  • 全部分區查詢

    • select * form dept_par;

分區的增 & 刪 & 改

  • 增加單個分區
    • alter table dept_partition add partition(day='20200404');
  • 增加多個分區
    • alter table dept_partition add partition(day='2020-10-26') partition(day='2020-10-27');
      • 多個分區使用空格隔開
  • 刪除單個分區
    • alter table dept_partition drop partition (day='2020-10-23'); 刪除分區后,分區中的表數據也被刪除,hdfs 上也是一樣
  • 刪除多個分區
    • alter table dept_partition drop partition (day='2020-10-28'),partition (day='2020-10-27'); 刪除分區后,分區中的表數據也被刪除,hdfs 上也是一樣
      • 多個分區使用逗號隔開
  • 查看表的分區
    • show partition dept_par;

二級分區

  • 創建二級分區表
    • create table dept_par2 (deptno int,dname string,loc string) partitioned by (day string,hour string) row format delimited fields terminated by '\t';
      • 二級分區表中,分區字段有兩個,第二個字段就代表二級分區
  • 查詢二級分區
    • 全表查詢
      • select * from dept_par2;
    • 分區查詢(既包括二級分區,也可以單查一級分區)
      • select * from dept_par2 where day = '2020-10-28' and hour = '10';

使得 HDFS 文件系統與分區表產生關聯

  • 若根據分區在 HDFS 上的目錄結構,直接新建一個目錄並傳入文件,預期能夠通過查詢語句查詢出分區中的數據,實際上,通過查詢語句查詢出的數據中,並沒有該數據,原因在於,MySQL 的元數據庫中,並沒有保存該分區的元數據
  • 解決辦法
    • msck repair table dept_partition2; 使用分區修復命令,修復指定表的分區
    • alter table dept_partition2 add partition(day='201709',hour='14'); 直接添加對應的分區
    • load data local inpath '/opt/module/hive/datas/dept_20200401.log' into table dept_partition2 partition(day='20200401',hour='15'); 創建文件夾后,通過 load 將數據加載到分區中

動態分區

  • 略,可查看尚硅谷原筆記

分桶表

  • 略,可查看尚硅谷原筆記

函數

系統內置函數

  • show funcations; 查詢系統內置的函數
  • desc function 函數名; 顯示函數的用法
  • desc function extended 函數名; 顯示函數的詳細用法(包括函數的使用例子)

空字段賦值

  • NVL 函數
    • nvl(value,defaultValue);
      • 如果 value 的值為 null,則填充默認值 defaultValue
    • select 字段1,字段2,nvl(字段1,-1) from emp; (默認值也可以使用另外一個字段來代替)

CASE WHEN THEN ELSE END

  • case 字段
    when 條件
    then 符合條件執行
    else 不符合條件執行
    end 必須以 end 結尾

  • 使用演示(查詢男女人數,以 dept_id 划分)

    • select
      dept_id,
      sum(case sex when '男' then 1 else 0 end) male_count,
      sum(case sex when '女' then 1 else 0 end) female_count
      from
      emp_sex
      group by dept_id;

拼接字符串

  • concat('hello-','-world' ...); 返回字符串連接后的結果: hello--world

  • select concat_ws('-','hello','world'); 以第一個參數為分隔符,返回拼接的字符串

    • 若該函數的分隔符為 null ,則返回值也為 null,分隔符可以和參數相同
    • 若后續參數中有值為 null,該函數會直接跳過
    • 參數字符串,可以直接使用字符串的數組代替
  • collect_set(字段); 將字段的值進行去重,匯總,產生 Array 類型的字段

    • 該函數只接受基本數據類型
  • 案例實操

    • 數據源

      • name conste blood_type

        孫悟空 白羊座 A
        大海 射手座 A
        宋宋 白羊座 B
        豬八戒 白羊座 A
        鳳姐 射手座 A
        蒼老師 白羊座 B

    • 建表

      • create table person_info( name string, constellation string, blood_type string) row format delimited fields terminated by "\t"; load data local inpath "/opt/module/hive/data/person_info.txt" into table person_info;
    • 需求

      • 按照血型和星座,將相同的人集合起來
    • 查詢語句

      • select con_blo,concat_ws('|',collect_set(t1.name)) name_arr from (select concat_ws(',',conste,blood_type) con_blo,name from persion)t1 group by con_blo;
      • 語句分析
        • 通過多表查詢,先從表中查出每一行數據的血型和星座(使用 concat_ws() 函數用指定分隔符連接后整體作為一個字段 con_blo)以及姓名作為 t1 表,然后將 t1 表作為嵌套,查詢其中的 con_blo 和 name 字段,其中,name 字段使用 concat_ws() 函數,同時使用 collect_set() 函數將 t1 表中查詢出的 name 聚合起來並用指定分隔符分隔,最后,以 con_blo 作為分組,就查詢出了相同星座血型的人並將他們集合起來

數值處理函數

  • 對給定的數取到指定精度(四舍五入)
    • select round(10/3,6); 將 10/3 的值取到小數點后六位
  • 向上取整
    • select ceiling(10.123); 值為 11,出現小數時,直接1向上取整
  • 向下取整
    • select floor(10.123); 值為 10,出現小數時,直接向下取整

Explode 函數

  • 將 hive 中的 Array 和 Map 拆分成多行數據,例如 [1,2,3,4,5] 拆分為 1,
    2,
    3,
    4,
    5

其他常用函數

常用字符串操作函數
upper: 轉大寫
select upper('low');

lower: 轉小寫
select lower('low');

length: 長度
select length("atguigu");

trim: 前后去空格
select trim(" atguigu ");

lpad: 向左補齊,到指定長度
select lpad('atguigu',9,'g');

rpad: 向右補齊,到指定長度
select rpad('atguigu',9,'g');

regexp_replace:使用正則表達式匹配目標字符串,匹配成功后替換!
SELECT regexp_replace('2020/10/25', '/', '-');

集合操作
size: 集合中元素的個數
select size(friends) from test3;

map_keys: 返回map中的key
select map_keys(children) from test3;

map_values: 返回map中的value
select map_values(children) from test3;

array_contains: 判斷array中是否包含某個元素
select array_contains(friends,'bingbing') from test3;

sort_array: 將array中的元素排序
select sort_array(friends) from test3;

grouping_set:多維分析


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM