Hive數據庫操作


本篇目錄:

1. Hive數據結構

2. DDL操作

3. DML操作

4. UDF函數

Hive數據結構

除了基本數據類型(與java類似),hive支持三種集合類型

Hive集合類型數據

array、map、structs

hive (default)> create table test(
              > name string,
              > friends array<string>,    -- 創建array字段
              > children map<string,int>,  -- map字段
              > address struct<street:string,city:string>)  -- struct字段
              > row format delimited        -- 限制多個字段分段符
              > fields terminated by ','    -- 字段之間以','分割
              > collection items terminated by '_'  -- 字段內部用'_'分割(包括array、map)
              > map keys terminated by ':'          -- map內key-value用':'
              > lines terminated by '\n';           -- 不同行,用回車'\n'

按表格式,寫一份數據,傳到hdfs對應的hive-test表下,

Lili,bingbing_xinxin,Lucifa:18_Jack:19,Nanjing_Beijing

然后查詢數據庫,即可得到查詢結果;

test.name       test.friends        test.children           test.address
Lili        ["bingbing","xinxin"]   {"Lucifa":18,"Jack":19} {"street":"Nanjing","city":"Beijing"}
  • 所以Hive的數據,一定是要按設計的格式,嚴格排列才能讀取的!!!

查詢集合數據

hive (default)> select friends[0] from test;    -- 可以像java數組那樣訪問
OK
bingbing

查詢map數據

hive (default)> select children['Lucifa'] from test;    -- 只能用key來訪問
OK
18

查詢結構體數據

hive (default)> select address.street from test;        -- address.street訪問
OK
street
Nanjing

DDL操作

庫、表的增刪改查

數據庫

  1. 創建數據庫

    除了location參數,其他跟mysql一樣,支持like,desc

    hive (default)> create database if not exists hive;
    OK
    -- 同時HDFS增加文件/user/hive/warehouse/hive.db
    hive (default)> create database if not exists hive location /hive;
    OK
    -- 自定義創建的數據庫在HDFS的路徑
    -- 查看庫信息
    hive (default)> desc database hive;
    OK
    db_name comment location    owner_name  owner_type  parameters
    hive        hdfs://master:9000/user/hive/warehouse/hive.db  whr USER
  1. 修改數據庫

    無法修改數據庫名和目錄位置;

    alter

  2. 刪庫

    -- 庫必須為空
    hive (default)> drop database test;
    -- 強制刪除cascade
    hive (default)> drop database test cascade;

  1. 查看一下表信息

    hive (default)> show create table test;
    ​
    CREATE TABLE `test`(
      `name` string, 
      `friends` array<string>, 
      `children` map<string,int>, 
      `address` struct<street:string,city:string>)
    ROW FORMAT DELIMITED    --分隔符
      FIELDS TERMINATED BY ',' 
      COLLECTION ITEMS TERMINATED BY '_' 
      MAP KEYS TERMINATED BY ':' 
      LINES TERMINATED BY '\n' 
    STORED AS INPUTFORMAT   --輸入格式
      'org.apache.hadoop.mapred.TextInputFormat' 
    OUTPUTFORMAT            --輸出格式
      'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
    LOCATION                --存儲位置
      'hdfs://master:9000/user/hive/warehouse/test'
    TBLPROPERTIES (         
      'transient_lastDdlTime'='1569750450')
  2. 內部表(管理表)、外部表

    內部表:刪除,同時刪除元數據和hdfs數據;

    外部表:刪除,只會刪除元數據信息,不刪hdfs數據;

    修改student內部表為外部表:

    alter table student set tblproperties('EXTERNAL'='TRUE');--后面必須大寫

    修改外部表為內部表:

    alter table student set tblproperties('EXTERNAL'='False');

    查詢表類型

    desc formatted student;
  3. 分區表

    避免暴力掃描;

    一個分區就是hdfs上的一個獨立文件夾;Hive的分區就是hdfs的目錄分割;

    創建一個分區表:(在元數據PARTITIONS表中存有分區信息)

    hive (default)> create table dept_partition(
                  > deptno int,dname string, loc string)
                  > partitioned by (month string)   -- 以month分區,month默認也算作一個字段
                  > row format delimited fields terminated by '\t';

    加載數據:

    load data [local] inpath 'path'  [overwrite] into table [partition_psc];
    local:
        有==>從linux本地加載數據
        無==>從hdfs加載數據,相當於執行mv操作(無指的是沒有local參數時,而不是本地中沒有這個文件)
    overwrite
        有==>覆蓋掉表中原來的數據
        無==>在原來的基礎上追加新的數據
    查詢:
    -- 分區查詢where
    hive (default)> select * from dept_partition where month = '2019-9-31';

    單獨添加分區

    -- 可添加多個分區
    hive (default)> alter table dept_partition add partition(month='2019-9-29') partition(month='2019-9-28');

    刪除分區

    -- add改成drop,每個分區間加 ','
    hive (default)> alter table dept_partition drop partition(month='2019-9-29'),partition(month='2019-9-28');
    查看有多少分區
    hive (default)> show partitions dept_partition;
  4. 二級分區表:

    其實就是以兩個字段來分區

    hive (default)> create table dept_2(
                  > deptno int,dname string,loc string)
                  > partitioned by (month string,day string)
                  > row format delimited fields terminated by '\t';

    上傳數據

    在hdfs是顯示兩層目錄:/user/hive/warehouse/dept_2/month=2019-9/day=30/dept.txt

    -- 這里分區,要寫兩個
    hive (default)> load data local inpath '/home/whr/Desktop/dept.txt' into table dept_2 partition(month='2019-9',day='30');
  5. 分區表的數據加載的三種方式:

    (1)load命令,自動創建文件夾,以及元數據;(常用)

    (2)手動添加分區文件夾以及分區數據,需要修復元數據,才能查詢;(了解)

    這里會自動根據hdfs文件,來修復,如果說存在大量的沒有元數據的數據,可以用此命令;

    hive (default)> msck repair table dept_parition;

    (3)手動添加分區文件夾以及分區數據,使用添加分區命令,自動補充元數據;(常用)

    第三種例子:

    # 通過hadoop命令,創建了文件夾,並上傳數據
    $ hadoop fs -mkdir -p /user/hive/warehouse/dept_partition/month=2019-9-17
    $ hadoop fs -put '/home/whr/Desktop/dept.txt' /user/hive/warehouse/dept_partition/month=2019-9-17

    添加分區

-- 添加分區
hive (default)> alter table dept_partition add partition(month='2019-9-17');
OK
Time taken: 0.1 seconds
-- 查詢所有分區
hive (default)> show partitions dept_partition;
OK
partition
month=2019-9-17 --存在
month=2019-9-30
month=2019-9-31 

DML數據操作

  1. 添加數據:

    (1)load

    (2)insert(不管數據是否重復,只管追加,多次insert,追加重復數據)

    hive (default)> insert into table test
                  > select id,name from mess;   -- 從mess表查詢,插入test
    -- 會執行MR程序            
    2019-09-30 14:53:55,879 Stage-1 map = 0%,  reduce = 0%
    2019-09-30 14:54:01,365 Stage-1 map = 100%,  reduce = 0%, Cumulative CPU 2.68 sec        

    (3)overwrite(重復->覆蓋;不重復->追加)

    hive (default)> insert overwrite table test
                  > select * from mess;

    (4)as select(在創建表的時候,導入數據)

    hive (default)> create table pika
                  > as select id,name from test;
    (5)location(創建的時候通過location,指定加載數據路徑)
    hive (default)> create table jieni(
                  > id int,name string)
                  > location 'user/hive/warehouse/mess/dept.txt';   --hdfs文件目錄

    (6)import(講數據導入Hive表中,很少用,前提有export數據,需要export的數據格式)

    • 必須列完全相同並且是個空表,才能導入;

  2. 數據導出

    (1)insert(insert到本地,可以認為是導出)

    -- 導出到本地,也可以導出到hdfs(刪掉local)
    hive (default)> insert overwrite local directory '/home/whr/Desktop/data' select * from test;
    -- 導出數據為一個目錄,數據在000000_0文件中,並且沒有分隔符

    (2)用hadoop命令,下載數據

    (3)export導出(少用)

    (4)sqoop導出:實現MySql和HDFS(Hive)數據之間導入導出;

  3. 清空表:truncate

    只會清除數據,表結構不變,只能刪除內部表(管理表),不能刪除外部表

至於查詢操作,基本上與MySql一致,不再贅述;

自定義函數UDF

可以分為三種:

  • UDF:自定義函數;一進一出

    public class MyUDF extends UDF {
        public int evaluate(int data){
            return data+5;
        }
    }
  • UDTF:自定義Table函數;一進多出;

    public class MyUDTF extends GenericUDTF {
        private List<String> dataList = new ArrayList<>();
        // 定義輸出數據的列名和數據類型
        @Override
        public StructObjectInspector initialize(StructObjectInspector argOIs)
                throws UDFArgumentException {
            // 定義輸出數據的列名
            List<String> fieldName = new ArrayList<>();
            fieldName.add("word");
            // 定義輸出數據的類型
            List<ObjectInspector> fieldOIs = new ArrayList<>();
            fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
            //
            return ObjectInspectorFactory.getStandardStructObjectInspector(fieldName, fieldOIs);
        }
        /**
         * 函數處理邏輯:函數需要兩個參數:
         * 1.args[0]:一個字符數組,
         * 2.args[1]:字符數組的分隔符
         * 使用方法:select myudtf('hello,word,qqq,new',',');
         */
        @Override
        public void process(Object[] args) throws HiveException {
            /**
             * 1.獲取數據
             * 2.獲取分隔符
             * 3.切分數據
             * 4.輸出數據
             */
            String data = args[0].toString();
            String splitKey = args[1].toString();
            String[] words = data.split(splitKey);
            for (String word : words) {
                dataList.clear();
                dataList.add(word);
                forward(dataList);
            }
        }
        @Override
        public void close() throws HiveException {
        }
    }
  • UDAF:自定義聚合函數;多進一出;

使用:

# 添加jar包,建議添加到hive/lib下,不需要add,可以直接使用
hive (default)> add jar /home/whr/Desktop/notes/Hadoop_notes/Hive_code/target/MyUDTF.jar;
# 創建函數
hive (default)> create function myudtf as 'UDF.MyUDTF';
# 傳參
hive (default)> select myudtf('hello,word,qqq,new',',');
OK
word # 這里是自定義的列名
hello
word
qqq
new

 


免責聲明!

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



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