1. 程式人生 > 其它 >【解決方案】助力電子商務平臺建設TSINGSEE青犀視訊實現AI全流程監管

【解決方案】助力電子商務平臺建設TSINGSEE青犀視訊實現AI全流程監管

hive 架構

hive 資料型別分基本資料型別 和集合資料型別

隱式轉換:

hive> select '1.0'+2;  // 數字字串轉double
OK
3.0
hive> select '1111' > 10;
hive> select 1 > 0.8;

顯式轉換:

hive> select cast('1111s' as int);
OK
NULL
hive> select cast('1111' as int);
OK
1111

集合資料型別:

集合測試:

hive> select array(1,2,3);
OK
[1,2,3
] -- 使用 [] 訪問陣列元素 hive> select arr[0] from (select array(1,2,3) arr) tmp; hive> select map('a', 1, 'b', 2, 'c', 3); OK {"a":1,"b":2,"c":3} -- 使用 [] 訪問map元素 hive> select mymap["a"] from (select map('a', 1, 'b', 2, 'c', 3) as mymap) tmp; -- 使用 [] 訪問map元素。 key 不存在返回 NULL hive> select mymap["x"
] from (select map('a', 1, 'b', 2, 'c', 3) as mymap) tmp; NULL hive> select struct('username1', 7, 1288.68); OK {"col1":"username1","col2":7,"col3":1288.68} -- 給 struct 中的欄位命名 hive> select named_struct("name", "username1", "id", 7, "salary", 12880.68); OK {"name":"username1","id":7,"salary":12880.68
} -- 使用 列名.欄位名 訪問具體資訊 hive> select userinfo.id > from (select named_struct("name", "username1", "id", 7, "salary", 12880.68) userinfo) tmp; -- union 資料型別 hive> select create_union(0, "zhansan", 19, 8000.88) uinfo;

Hive 預設分隔符:

Hive DDL:

建立資料庫:

-- 建立資料庫,在HDFS上儲存路徑為 /user/hive/warehouse/*.db
hive (default)> create database mydb;
hive (default)> dfs -ls /user/hive/warehouse;
-- 避免資料庫已經存在時報錯,使用 if not exists 進行判斷【標準寫法】
hive (default)> create database if not exists mydb;
-- 建立資料庫。新增備註,指定資料庫在存放位置
hive (default)> create database if not exists mydb2
comment 'this is mydb2'
location '/user/hive/mydb2.db';

檢視資料庫:

-- 檢視所有資料庫
show database;
-- 檢視資料庫資訊
desc database mydb2;
desc database extended mydb2;
describe database extended mydb2;

使用資料庫:

use mydb;

刪除資料庫:

-- 刪除一個空資料庫
drop database databasename;
-- 如果資料庫不為空,使用 cascade 強制刪除
drop database databasename cascade;  //慎用,防止刪庫跑路

建立表:

語法:

create [external] table [IF NOT EXISTS] table_name
[(colName colType [comment 'comment'], ...)]
[comment table_comment]
[partition by (colName colType [comment col_comment], ...)]
[clustered BY (colName, colName, ...)
[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];
CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS]
[db_name.]table_name
LIKE existing_table_or_view_name
[LOCATION hdfs_path];

欄位解釋:

1. CREATE TABLE。按給定名稱建立表,如果表已經存在則丟擲異常。可使用if not exists 規避。
2. EXTERNAL關鍵字。建立外部表,否則建立的是內部表(管理表)。
刪除內部表時,資料和表的定義同時被刪除;
刪除外部表時,僅僅刪除了表的定義,資料保留;
在生產環境中,多使用外部表;
3. comment。表的註釋
4. partition by。對錶中資料進行分割槽,指定表的分割槽欄位
5. clustered by。建立分桶表,指定分桶欄位
6. sorted by。對桶中的一個或多個列排序,較少使用

儲存子句:

ROW FORMAT DELIMITED
[FIELDS TERMINATED BY char]
[COLLECTION ITEMS TERMINATED BY char]
[MAP KEYS TERMINATED BY char]
[LINES TERMINATED BY char] | SERDE serde_name
[WITH SERDEPROPERTIES (property_name=property_value,
property_name=property_value, ...)]
7.stored as  TEXTFILE  ORC PARQUET
8.LOCATION。表在HDFS上的存放位置
9.AS。後面可以接查詢語句,表示根據後面的查詢結果建立表
  create table xxx as select ... 這種方式不會複製分割槽,分桶
10.like 複製表結構,不復制資料

內部表 & 外部表:

  •   內部表、管理表 表和資料繫結,一起刪除
  •   外部表,刪除表不影響資料
-- 內部錶轉外部表
alter table t1 set tblproperties('EXTERNAL'='TRUE');
-- 查詢表資訊,是否轉換成功
desc formatted t1;
-- 外部錶轉內部表。EXTERNAL 大寫,false 不區分大小
alter table t1 set tblproperties('EXTERNAL'='FALSE');
-- 查詢表資訊,是否轉換成功
desc formatted t1;

分割槽表:

  為了避免全表掃描,將資料儲存在不同子目錄中,每個子目錄對應一個分割槽

分割槽表建立與資料載入示例:

-- 建立表
create table if not exists t3(
id int
,name string
,hobby array<string>
,addr map<String,string>
)
partitioned by (dt string)
row format delimited
fields terminated by ';'
collection items terminated by ','
map keys terminated by ':';
-- 載入資料。
load data local inpath "/home/hadoop/data/t1.dat" into table
t3
partition(dt="2020-06-01");
load data local inpath "/home/hadoop/data/t1.dat" into table
t3
partition(dt="2020-06-02");

備註:分割槽欄位不是表中已經存在的資料,可以將分割槽欄位看成偽列

檢視分割槽:

show partitions t3;

新增分割槽並設定資料:

-- 增加一個分割槽,不載入資料
alter table t3 add partition(dt='2020-06-03');
-- 增加多個分割槽,不載入資料
alter table t3
add partition(dt='2020-06-05') partition(dt='2020-06-06');
-- 增加多個分割槽。準備資料
hdfs dfs -cp /user/hive/warehouse/mydb.db/t3/dt=2020-06-01
/user/hive/warehouse/mydb.db/t3/dt=2020-06-07
hdfs dfs -cp /user/hive/warehouse/mydb.db/t3/dt=2020-06-01
/user/hive/warehouse/mydb.db/t3/dt=2020-06-08
-- 增加多個分割槽。載入資料
alter table t3 add
partition(dt='2020-06-07') location
'/user/hive/warehouse/mydb.db/t3/dt=2020-06-07'
partition(dt='2020-06-08') location
'/user/hive/warehouse/mydb.db/t3/dt=2020-06-08';
-- 查詢資料
select * from t3

修改分割槽的hdfs 路徑:

alter table t3 partition(dt='2020-06-01') set location
'/user/hive/warehouse/t3/dt=2020-06-03';

刪除分割槽:

-- 可以刪除一個或多個分割槽,用逗號隔開
alter table t3 drop partition(dt='2020-06-03'),
partition(dt='2020-06-04');

分桶表:

  當單個的分割槽或者表的資料量過大,分割槽不能更細粒度的劃分資料,就需要使用分桶。

  分桶原理:分桶欄位.hashCode % 分桶個數

分桶表測試:

create table course(
id int,
name string,
score int
)
clustered by (id) into 3 buckets
row format delimited fields terminated by "\t";
-- 建立普通表 create table course_common( id int, name string, score int ) row format delimited fields terminated by "\t"; -- 普通表載入資料 load data local inpath '/home/hadoop/data/course.dat' into table course_common; -- 通過 insert ... select ... 給桶表載入資料 insert into table course select * from course_common; -- 觀察分桶資料。資料按照:(分割槽欄位.hashCode) % (分桶數) 進行分割槽

備註:

  • 分桶規則:分桶欄位.hashCode % 分桶數
  • 分桶表載入資料時,使用 insert... select ... 方式進行
  • 網上有資料說要使用分割槽表需要設定 hive.enforce.bucketing=true,那是Hive 1.x 以前的版本;Hive 2.x 中,刪除了該引數,始終可以分桶;

修改表 & 刪除表:

-- 修改表名。rename
alter table course_common
rename to course_common1;
-- 修改列名。change column
alter table course_common1
change column id cid int;
-- 修改欄位型別。change column
alter table course_common1
change column cid cid string;
-- The following columns have types incompatible with the
existing columns in their respective positions
-- 修改欄位資料型別時,要滿足資料型別轉換的要求。如int可以轉為string,但是
string不能轉為int
-- 增加欄位。add columns
alter table course_common1
add columns (common string);
-- 刪除欄位:replace columns
-- 這裡僅僅只是在元資料中刪除了欄位,並沒有改動hdfs上的資料檔案
alter table course_common1
replace columns(
id string, cname string, score int);
-- 刪除表
drop table course_common1;

資料匯入:

語法:
LOAD
DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]
  • LOCAL:
  1. LOAD DATA LOCAL ... 從本地檔案系統載入資料到Hive表中。本地檔案會拷 貝到Hive表指定的位置
  2. LOAD DATA ... 從HDFS載入資料到Hive表中。HDFS檔案移動到Hive表指定 的位置
  • INPATH:載入資料的路徑
  • OVERWRITE:覆蓋表中已有資料;否則表示追加資料
  • PARTITION:將資料載入到指定的分割槽

插入資料:

  常用於從普通表插入資料到分割槽表,或orc ,parquet 儲存格式的表

-- 插入資料
insert into table tabC
partition(month='202001')
values (5, 'wangwu', 'BJ'), (4, 'lishi', 'SH'), (3,
'zhangsan', 'TJ');
-- 插入查詢的結果資料
insert into table tabC partition(month='202002')
select id, name, area from tabC where month='202001';

-- 多表(多分割槽)插入模式   
from tabC
insert overwrite table tabC partition(month='202003')
select id, name, area where month='202002'
insert overwrite table tabC partition(month='202004')
select id, name, area where month='202002';  // from 提前,這樣可以減少hive sql的stage

建立表並插入資料:

-- 根據查詢結果建立表
create table if not exists tabD
as select * from tabC;

資料匯出:

-- 將查詢結果匯出到本地
insert overwrite local directory '/home/hadoop/data/tabC'
select * from tabC;
-- 將查詢結果格式化輸出到本地
insert overwrite local directory '/home/hadoop/data/tabC2'
row format delimited fields terminated by ' '
select * from tabC;
-- 將查詢結果匯出到HDFS
insert overwrite directory '/user/hadoop/data/tabC3'
row format delimited fields terminated by ' '
select * from tabC;
-- dfs 命令匯出資料到本地。本質是執行資料檔案的拷貝
dfs -get /user/hive/warehouse/mydb.db/tabc/month=202001
/home/hadoop/data/tabC4
-- hive 命令匯出資料到本地。執行查詢將查詢結果重定向到檔案 hive -e "select * from tabC" > a.log -- export 匯出資料到HDFS。使用export匯出資料時,不僅有數還有表的元資料信 息 export table tabC to '/user/hadoop/data/tabC4'; -- export 匯出的資料,可以使用 import 命令匯入到 Hive 表中 -- 使用 like tname建立的表結構與原表一致。create ... as select ... 結構可能不一致 create table tabE like tabc; import table tabE from ''/user/hadoop/data/tabC4'; -- 截斷表,清空資料。(注意:僅能操作內部表) truncate table tabE; -- 以下語句報錯,外部表不能執行 truncate 操作 alter table tabC set tblproperties("EXTERNAL"="TRUE"); truncate table tabC;

Hive DQL :

SELECT [ALL | DISTINCT] select_expr, select_expr, ...
FROM table_reference
[WHERE where_condition]
[GROUP BY col_list]
[ORDER BY col_list]
[CLUSTER BY col_list | [DISTRIBUTE BY col_list] [SORT BY
col_list]]
[LIMIT [offset,] rows]

基本查詢:

-- 省略from子句的查詢
select 8*888 ;
select current_date ;
-- 使用列別名
select 8*888 product;
select current_date as currdate;
-- 全表查詢
select * from emp;
-- 選擇特定列查詢
select ename, sal, comm from emp;
-- 使用函式
select count(*) from emp;
-- count(colname) 按欄位進行count,不統計NULL
select sum(sal) from emp;
select max(sal) from emp;
select min(sal) from emp;
select avg(sal) from emp;
-- 使用limit子句限制返回的行數
select * from emp limit 3;

where 子句:

  where 字句中不能使用列的別名

rlike 可以寫正則表示式。

group by 字句:

-- 計算emp表每個部門的平均工資
select deptno, avg(sal)
from emp
group by deptno;
-- 計算emp每個部門中每個崗位的最高薪水
select deptno, job, max(sal)
from emp
group by deptno, job;
  • where 針對表資料過濾
  • having 針對group by的結果過濾
  • group by 中不能使用別名

表連線:

1. 內連線: [inner] join
2. 外連線 (outer join)
- 左外連線。 left [outer] join,左表的資料全部顯示
- 右外連線。 right [outer] join,右表的資料全部顯示
- 全外連線。 full [outer] join,兩張表的資料都顯示

排序字句:

全域性排序 order by :

  1.   order by 子句出現在select語句的結尾;
  2.   order by子句對最終的結果進行排序;
  3.   預設使用升序(ASC);可以使用DESC,跟在欄位名之後表示降序;

  ORDER BY執行全域性排序,只有一個reduce;

-- 普通排序
select * from emp order by deptno;
-- 按別名排序
select empno, ename, job, mgr, sal + nvl(comm, 0) salcomm,
deptno
from emp
order by salcomm desc;
-- 多列排序
select empno, ename, job, mgr, sal + nvl(comm, 0) salcomm,
deptno
from emp
order by deptno, salcomm desc;
-- 排序欄位要出現在select子句中。以下語句無法執行(因為select子句中缺少
deptno):
select empno, ename, job, mgr, sal + nvl(comm, 0) salcomm
from emp
order by deptno, salcomm desc;

注意排序欄位需要出現在select語句中。

分割槽排序(distribute by):

  結合sort by 使用。 使得結果分割槽內有序。

-- 啟動2個reducer task;先按 deptno 分割槽,在分割槽內按 sal+comm 排序
set mapreduce.job.reduces=2;
-- 將結果輸出到檔案,觀察輸出結果
insert overwrite local directory '/home/hadoop/output/distBy'
select empno, ename, job, deptno, sal + nvl(comm, 0) salcomm
from emp
distribute by deptno
sort by salcomm desc;

當distribute by 與 sort by是同一個欄位時,可使用cluster by簡化語法;

   cluster by 只能是升序,不能指定排序規則;

-- 語法上是等價的
select * from emp distribute by deptno sort by deptno;
select * from emp cluster by deptno;

Hive 函式:

-- 顯示自帶函式的用法
desc function upper;
desc function extended upper;

日期相關函式:

-- 當前前日期
select current_date;
select unix_timestamp();
-- 建議使用current_timestamp,有沒有括號都可以
select current_timestamp();
-- 時間戳轉日期
select from_unixtime(1505456567);
select from_unixtime(1505456567, 'yyyyMMdd');
select from_unixtime(1505456567, 'yyyy-MM-dd HH:mm:ss');
-- 日期轉時間戳
select unix_timestamp('2019-09-15 14:23:00');
-- 計算時間差
select datediff('2020-04-18','2019-11-21');
select datediff('2019-11-21', '2020-04-18');
-- 查詢當月第幾天
select dayofmonth(current_date);
-- 計算月末:
select last_day(current_date);
-- 當月第1天:
select date_sub(current_date, dayofmonth(current_date)-1)
-- 下個月第1天:
select add_months(date_sub(current_date,
dayofmonth(current_date)-1), 1)
-- 字串轉時間(字串必須為:yyyy-MM-dd格式)
select to_date('2020-01-01');
select to_date('2020-01-01 12:12:12');
-- 日期、時間戳、字串型別格式化輸出標準時間格式
select date_format(current_timestamp(), 'yyyy-MM-dd
HH:mm:ss');
select date_format(current_date(), 'yyyyMMdd');
select date_format('2020-06-01', 'yyyy-MM-dd HH:mm:ss');

-- 計算emp表中,每個人的工齡
select *, round(datediff(current_date, hiredate)/365,1) workingyears from emp;

字串相關函式:

-- 轉小寫。lower
select lower("HELLO WORLD");
-- 轉大寫。upper
select lower(ename), ename from emp;
-- 求字串長度。length
select length(ename), ename from emp;
-- 字串拼接。 concat / ||
select empno || " " ||ename idname from emp;
select concat(empno, " " ,ename) idname from emp;
-- 指定分隔符。concat_ws(separator, [string | array(string)]+)
SELECT concat_ws('.', 'www', array('lagou', 'com'));
select concat_ws(" ", ename, job) from emp;
-- 求子串。substr
SELECT substr('www.lagou.com', 5);
SELECT substr('www.lagou.com', -5);
SELECT substr('www.lagou.com', 5, 5);
-- 字串切分。split,注意 '.' 要轉義
select split("www.lagou.com", "\\.");

數學相關函式:

-- 四捨五入。round
select round(314.15926);
select round(314.15926, 2);
select round(314.15926, -2);
-- 向上取整。ceil
select ceil(3.1415926);
-- 向下取整。floor
select floor(3.1415926);

條件函式:

-- if (boolean testCondition, T valueTrue, T valueFalseOrNull)
select sal, if (sal<1500, 1, if (sal < 3000, 2, 3)) from emp;
-- CASE WHEN a THEN b [WHEN c THEN d]* [ELSE e] END
-- 將emp表的員工工資等級分類:0-1500、1500-3000、3000以上
select sal, if (sal<=1500, 1, if (sal <= 3000, 2, 3)) from
emp;
-- CASE WHEN a THEN b [WHEN c THEN d]* [ELSE e] END
-- 複雜條件用 case when 更直觀
select sal, case when sal<=1500 then 1
when sal<=3000 then 2
else 3 end sallevel
from emp;
-- 以下語句等價
select ename, deptno,
case deptno when 10 then 'accounting'
when 20 then 'research'
when 30 then 'sales'
else 'unknown' end deptname
from emp;
select ename, deptno,
case when deptno=10 then 'accounting'
when deptno=20 then 'research'
when deptno=30 then 'sales'
else 'unknown' end deptname
from emp;

-- COALESCE(T v1, T v2, ...)。返回引數中的第一個非空值;如果所有值都為
NULL,那麼返回NULL
select sal, coalesce(comm, 0) from emp;
-- isnull(a) isnotnull(a)
select * from emp where isnull(comm);
select * from emp where isnotnull(comm);
-- nvl(T value, T default_value)  // 如果value 為null,則賦值 default_value
select empno, ename, job, mgr, hiredate, deptno, sal + nvl(comm,0) sumsal from emp;
-- nullif(x, y) 相等為空,否則為a
SELECT nullif("b", "b"), nullif("b", "a");

UDTF 函式:

  一行輸 入,多行輸出。