Hive
首先,我們來介紹一下什麼是Hive。有些人不僅會想,Hive不就是寫SQL的嗎。沒錯,Hive和SQL的語法結構很像,其實,二者沒有多大區別,甚至可以這樣講,Hive就是寫SQL。但是,問題就來了–它真正的就是SQL了嗎?它和SQL數據庫有什麼區別?和其他的關傳統的系型數據庫又有什麼區別和關係呢?一系類問題,別急,我們慢慢來分析。
1、Hive 由 Facebook 實現並開源
2、是基於 Hadoop 的一個數據倉庫工具
3、可以將結構化的數據映射爲一張數據庫表
4、並提供 HQL(Hive SQL)查詢功能
5、底層數據是存儲在 HDFS 上
6、Hive的本質是將 SQL 語句轉換爲 MapReduce 任務運行
7、使不熟悉 MapReduce 的用戶很方便地利用 HQL 處理和計算 HDFS 上的結構化的數據,適用於離線的批量數據計算。
數據倉庫之父比爾·恩門(Bill Inmon)在 1991 年出版的“Building the Data Warehouse”(《建 立數據倉庫》)一書中所提出的定義被廣泛接受——數據倉庫(Data Warehouse)是一個面 向主題的(Subject Oriented)、集成的(Integrated)、相對穩定的(Non-Volatile)、反映歷史 變化(Time Variant)的數據集合,用於支持管理決策(Decision Making Support)。
Hive 依賴於 HDFS 存儲數據,Hive 將 HQL 轉換成 MapReduce 執行,所以說 Hive 是基於 Hadoop 的一個數據倉庫工具,實質就是一款基於 HDFS 的 MapReduce 計算框架,對存儲在 HDFS 中的數據進行分析和管理。
Hive的產生背景
大數據時代的到來,海量的數據對於傳統的關係型數據庫來說維護起來成本非常高,那該如何是好呢?這時候Hive就誕生了,最開始是facebook開源,最初用於解決海量結構化的日誌數據統計問題;ETL (Extraction-Transformation-Loading )工具構建在Hadoop之上的數據倉庫;數據計算使用MR ,數據存儲使用HDFS。
Hive 定義了一種類 SQL 查詢語言,叫做HQL;類似SQL,但不完全相同,通常用於進行離線數據處理(採用MapReduce);可認爲是一個HQL MR的語言翻譯器。
Apache Hive數據倉庫軟件可以使用SQL方便地閱讀、編寫和管理分佈在分佈式存儲中的大型數據集。結構可以投射到已經存儲的數據上。提供了一個命令行工具和JDBC驅動程序來將用戶連接到Hive。產生背景有以下幾個方面:
- MapReduce編程的不便性
- HDFS上的文件缺少某些字段
Hive 在Hadoop生態系統的位置
Hive體系架構
說了這麼多,你對Hive的瞭解是不是高多了,那麼問題來了,我們爲什麼要使用Hive呢?它有什麼獨特之處嗎?使用 MapReduce不好嗎?那麼第一,我們來講講直接使用 MapReduce所面臨的問題:
- 人員學習成本太高;
- 項目週期要求太短;
- MapReduce實現複雜查詢邏輯開發難度太大;
而使用Hive的方面:
- 它有更友好的接口,操作接口採用類 SQL 的語法,提供快速開發的能力。
- 學習成本的成本更低,避免了寫 MapReduce,減少開發人員的學習成本。
- 有更好的擴展性,可自由擴展集羣規模而無需重啓服務,還支持用戶自定義函數。
我們再來說說Hive的優缺點:
優點
- 可擴展性,橫向擴展,Hive 可以自由的擴展集羣的規模,一般情況下不需要重啓服務。橫向擴展:通過分擔壓力的方式擴展集羣的規模;縱向擴展:一臺服務器cpu i7-6700k 4核心8線程,8核心16線程,內存64G => 128G
- 延展性,Hive 支持自定義函數,用戶可以根據自己的需求來實現自己的函數
- 良好的容錯性,可以保障即使有節點出現問題,SQL 語句仍可完成執行
缺點
- Hive 不支持記錄級別的增刪改操作,但是用戶可以通過查詢生成新表或者將查詢結 果導入到文件中(當前選擇的 hive-2.3.2 的版本支持記錄級別的插入操作)。
- Hive 的查詢延時很嚴重,因爲 MapReduce Job 的啓動過程消耗很長時間,所以不能 用在交互查詢系統中。
- Hive 不支持事務(因爲不沒有增刪改,所以主要用來做 OLAP(聯機分析處理),而 不是 OLTP(聯機事務處理),這就是數據處理的兩大級別)。
總結:
Hive 具有 SQL 數據庫的外表,但應用場景完全不同,Hive 只適合用來做海量離線數 據統計分析,也就是數據倉庫。
Hive使用起來也非常容易,一起來看看它有哪些函數吧。
關係函數
-
等值比較: =
- 語法:A=B。如果表達式A與表達式B相等,則爲TRUE;否則爲FALSE
-
不等值比較: <>
- 語法:A <> B。如果表達式A爲NULL,或者表達式B爲NULL,返回NULL;如果表達式A與表達式B不相等,則爲TRUE;否則爲FALSE
-
小於比較:<
- 語法: A < B。 如果表達式A爲NULL,或者表達式B爲NULL,返回NULL;如果表達式A小於表達式B,則爲TRUE;否則爲FALSE
-
小於等於比較: <=
- 語法: A <= B。如果表達式A爲NULL,或者表達式B爲NULL,返回NULL;如果表達式A小於或者等於表達式B,則爲TRUE;否則爲FALSE
-
大於等於比較: >=
- 語法:A >= B。如果表達式A爲NULL,或者表達式B爲NULL,返回NULL;如果表達式A大於或者等於表達式B,則爲TRUE;否則爲FALSE
-
空值判斷:IS NULL
- 語法:A IS NULL。如果表達式A的值爲NULL,則爲TRUE;否則爲FALSE
-
非空判斷: IS NOT NULL
- 語法: A IS NOT NULL。 如果表達式A的值爲NULL,則爲FALSE;否則爲TRUE
-
LIKE比較: LIKE
- 語法:A[NOT] LIKE B。如果字符串A或者字符串B爲NULL,則返回NULL;如果字符串A符合表達式B的正則語法,則爲TRUE;否則爲FALSE。B中字符”_”表示任意單個字符,而字符”%”表示任意數量的字符。
舉例: select * from dw.topic_order where partition_pay_date = ‘2016-04-22’ and client_type like ‘ip%’ ##能夠匹配以ip開頭的所有字符串。
注意:對特殊字符進行轉譯時,注意要使用兩個反斜槓\
- 語法:A[NOT] LIKE B。如果字符串A或者字符串B爲NULL,則返回NULL;如果字符串A符合表達式B的正則語法,則爲TRUE;否則爲FALSE。B中字符”_”表示任意單個字符,而字符”%”表示任意數量的字符。
-
JAVA的LIKE/REGEXP操作:RLIKE/REGEXP
- 語法: A RLIKE/REGEXP B。如果字符串A或者字符串B爲NULL,則返回NULL;如果字符串A符合JAVA正則表達式B的正則語法,則爲TRUE;否則爲FALSE
舉例:select * from dw.topic_order where partition_pay_date = ‘2016-04-22’ and client_type rlike/regexp ‘^android.*’
注意:通配符‘%’在rlike/regexp函數中,只能匹配一個’%'字符,’‘也只能匹配一個’‘字符
- 語法: A RLIKE/REGEXP B。如果字符串A或者字符串B爲NULL,則返回NULL;如果字符串A符合JAVA正則表達式B的正則語法,則爲TRUE;否則爲FALSE
日期函數
- UNIX時間戳轉日期函數:from_unixtime
- 語法: from_unixtime(bigint unixtime[, string format])。轉化UNIX時間戳(從1970-01-01 00:00:00 UTC到指定時間的秒數)到當前時區的時間格式
舉例:select from_unixtime(1323308943,‘yyyyMMdd’) from dual; ##返回值爲20111208
- 語法: from_unixtime(bigint unixtime[, string format])。轉化UNIX時間戳(從1970-01-01 00:00:00 UTC到指定時間的秒數)到當前時區的時間格式
- 日期轉年函數: year
- 語法: year(string date)。 返回日期中的年。
- 日期轉月函數:month
- 語法:month (string date)。返回日期中的月份。
- 日期轉天函數: day
- 語法:day (string date)。返回日期中的天。
- 日期轉小時函數: hour
- 語法:hour (string date)。 返回日期中的小時。
- 日期轉分鐘函數: minute
- 語法:minute (string date)。返回日期中的分鐘。
舉例:select minute(‘2011-12-08 10:03:01’) from dual; ##返回值爲3
- 語法:minute (string date)。返回日期中的分鐘。
- 日期轉秒函數: second
- 語法:second (string date)。 返回日期中的秒。
舉例:select second(‘2011-12-08 10:03:01’) from dual; ##返回值爲1
- 語法:second (string date)。 返回日期中的秒。
- 日期轉周函數: weekofyear
- 語法:weekofyear (string date)。返回日期在當前的週數。
舉例:select weekofyear(‘2011-12-08 10:03:01’) from dual; ##返回值爲49
- 語法:weekofyear (string date)。返回日期在當前的週數。
- 日期比較函數:datediff
- 語法:datediff(string enddate, string startdate)。返回結束日期減去開始日期的天數。
舉例:select datediff(‘2012-12-08’,‘2012-05-09’) from dual; ##返回值爲213
- 語法:datediff(string enddate, string startdate)。返回結束日期減去開始日期的天數。
- 日期增加函數:date_add
- 語法:date_add(string startdate, int days)。 返回開始日期startdate增加days天后的日期。
舉例:select date_add(‘2012-12-08’,10) from dual; ##返回值爲2012-12-18
- 語法:date_add(string startdate, int days)。 返回開始日期startdate增加days天后的日期。
- 日期減少函數:date_sub
- 語法:date_sub (string startdate, int days)。 返回開始日期startdate減少days天后的日期。
舉例:select date_sub(‘2012-12-08’,10) from dual; ##返回值爲2012-11-28
- 語法:date_sub (string startdate, int days)。 返回開始日期startdate減少days天后的日期。
條件函數
- If函數:if
- 語法:if(boolean testCondition, T valueTrue, T valueFalseOrNull)
說明:當條件testCondition爲TRUE時,返回valueTrue;否則返回valueFalseOrNull。
舉例:select if(app_name = ‘group’,object_id,null) as deal_id from dw.topic_order where partition_pay_date = ‘2016-04-22’
- 語法:if(boolean testCondition, T valueTrue, T valueFalseOrNull)
- 非空查找函數:COALESCE
- 語法:COALESCE(T v1, T v2, …)
說明:返回參數中的第一個非空值;如果所有值都爲NULL,那麼返回NULL
舉例:select coalesce(uuid,’’) as uuid from dw.topic_order where partition_pay_date = ‘2016-04-22’
- 語法:COALESCE(T v1, T v2, …)
- 條件判斷函數:CASE
- 語法:CASE a WHEN b THEN c [WHEN d THEN e]* [ELSE f] END
說明:如果 a 等於 b ,那麼返回 c ;如果 a 等於 d ,那麼返回 e ;否則返回 f
舉例:select object_id,user_id,uuid, case when client_type like ‘ip%’ then 'ios’when client_type like ‘andr%’ then ‘android’ else ‘other’ end as utm_mediumfrom dw.topic_order where partition_pay_date = ‘2016-04-22’
注意:相對而言,case when是最全的條件函數,可以用於判斷多種條件;次之是if函數,屬於二分判斷;最後是coalesce函數,該函數只能對空值和非空進行判斷。
- 語法:CASE a WHEN b THEN c [WHEN d THEN e]* [ELSE f] END
統計函數
- 個數統計函數:count
- 語法:count(), count(expr), count(DISTINCT expr[, expr_.])。count()統計檢索出的行的個數,包括NULL值的行;count(expr)返回指定字段的非空值的個數;count(DISTINCT expr[, expr_.])返回指定字段的不同的非空值的個數
- 總和統計函數:sum
- 語法:sum(col), sum(DISTINCT col)。sum(col)統計結果集中col的相加的結果;sum(DISTINCT col)統計結果中col不同值相加的結果
- 平均值統計函數:avg
- 語法:avg(col), avg(DISTINCT col)。avg(col)統計結果集中col的平均值;avg(DISTINCT col)統計結果中col不同值相加的平均值
- 最小值統計函數:min
- 語法:min(col)。 統計結果集中col字段的最小值
- 最大值統計函數:max
- 語法:max(col)。統計結果集中col字段的最大值
- 中位數函數:precentile語法: percentile(BIGINT col, p)。求準確的第pth個百分位數,p必須介於0和1之間,但是col字段目前只支持整數,不支持浮點數類型。
以上就是Hive的函數聲明,還有很多,我這裏就只列出來我覺得很重要的一部分,看着是不是很像SQL對吧,哈哈哈。其實也不難的。那麼,我們來說說它和數據庫的異同。
由於Hive採用了SQL的查詢語言HQL,因此很容易將Hive理解爲數據庫。其實從結構上來看,Hive和數據庫除了擁有類似的查詢語言,再無類似之處。數據庫可以用在Online的應用中,但是Hive是爲數據倉庫而設計的,清楚這一點,有助於從應用角度理解Hive的特性。