一、數(shù)據(jù)倉庫
1旅掂、數(shù)據(jù)倉庫定義姑丑?
關(guān)于數(shù)據(jù)倉庫(Data Warehouse, DW)的定義比較常見的一種是數(shù)據(jù)倉庫之父比爾·恩門在1991年出版的《建立數(shù)據(jù)倉庫》一書中所提出的定義:
數(shù)據(jù)倉庫是一個面向主題的、集成的辞友、相對穩(wěn)定的栅哀、反映歷史變化的數(shù)據(jù)集合震肮,用于支持管理決策。
還有一種常見的描述是:
數(shù)據(jù)倉庫是將源系統(tǒng)數(shù)據(jù)抽取留拾、轉(zhuǎn)化戳晌、清洗,存儲到維度模型中的系統(tǒng)痴柔,為分析決策提供查詢沦偎、分析的支持。
所以數(shù)據(jù)倉庫到底是什么咳蔚?看完定義描述依舊不知道 =_=||豪嚎。
《數(shù)據(jù)倉庫入門,看這這一篇就夠了》一文中對數(shù)據(jù)倉庫的解釋是這樣的:
數(shù)據(jù)倉庫是面向分析的存儲系統(tǒng)
也就是說數(shù)倉是存數(shù)據(jù)的谈火,企業(yè)的各種數(shù)據(jù)往里面塞侈询,主要目的是為了有效分析數(shù)據(jù),后續(xù)會基于它產(chǎn)出供分析挖掘的數(shù)據(jù)糯耍,或者數(shù)據(jù)應用需要的數(shù)據(jù)
回過頭來理解 面向主題的扔字、集成的、相對穩(wěn)定的温技、反映歷史變化革为。
面向主題的——數(shù)據(jù)倉庫通過一個個主題域?qū)⒍鄠€業(yè)務(wù)系統(tǒng)的數(shù)據(jù)加載到一起
集成的——數(shù)據(jù)倉庫會將不同源數(shù)據(jù)庫中的數(shù)據(jù)匯總到一起
相對穩(wěn)定的——數(shù)據(jù)倉庫中的數(shù)據(jù)一般僅執(zhí)行查詢操作,很少會有刪除和更新舵鳞。但是需定期加載和刷新數(shù)據(jù)震檩。
反映歷史變化——數(shù)據(jù)被加載后一般情況下將被長期保留,因此數(shù)據(jù)倉庫包含來自其時間范圍不同時間段的數(shù)據(jù)
這四個描述就是反應數(shù)據(jù)倉庫存儲數(shù)據(jù)的特點蜓堕,各種來源的數(shù)據(jù)按主題長期的存儲抛虏,用于分析決策。
2俩滥、數(shù)據(jù)倉庫和數(shù)據(jù)庫的差別是什么?
主要差別是在以下兩方面:
- 實時性差異——關(guān)系數(shù)據(jù)庫都是為實時查詢的業(yè)務(wù)進行設(shè)計的贺奠,而數(shù)據(jù)倉庫則是為海量數(shù)據(jù)做分析挖掘設(shè)計的霜旧,實時性要求不高;
- 存儲能力和計算能力擴展——數(shù)據(jù)倉庫在存儲能力和計算能力上更好儡率,而關(guān)系數(shù)據(jù)庫在這個方面要差很多挂据。
3、數(shù)據(jù)倉庫和hive的關(guān)系儿普?
提到數(shù)據(jù)倉庫經(jīng)常聽到hive崎逃。hive是什么?hive和數(shù)據(jù)倉庫的關(guān)系是什么眉孩?
(1)hive是什么?
Hadoop是一個能夠?qū)Υ罅繑?shù)據(jù)進行分布式處理的軟件框架个绍,Hive 是 Hadoop 中的一個重要子項目勒葱,是基于Hadoop的一個數(shù)據(jù)倉庫工具(存數(shù)據(jù)的工具)
(2)Hive內(nèi)部結(jié)構(gòu)
CLI, WebUI為hive的用戶接口;
元數(shù)據(jù)存儲在mysql巴柿,主要數(shù)據(jù)存儲在HDFS凛虽;
Hive定義了一種類似SQL的查詢語言(HQL),將SQL轉(zhuǎn)化為MapReduce任務(wù),利用MapReduce 進行計算[2]
(3)數(shù)據(jù)倉庫與hive關(guān)系
數(shù)據(jù)倉庫比較流行的工具有:AWS Redshift, Greenplum, Hive等广恢。
之前提到數(shù)據(jù)倉庫將各種來源的數(shù)據(jù)按主題長期的存儲凯旋,至于存數(shù)據(jù)用紙盒子、塑料盒子钉迷、鐵盒子都是可選的至非,hive就是存數(shù)據(jù)的一種盒子。
二糠聪、hive的操作
在實際生產(chǎn)環(huán)境中已經(jīng)形成了離線以Hive為主荒椭,Spark為輔, 實時處理用Flink的大數(shù)據(jù)架構(gòu)體系及Impala, Es,Kylin等應用查詢引擎枷颊。
以下采用Spark on Hive模式(即使用Hive作為Spark的數(shù)據(jù)源戳杀,用Spark來讀取HIVE的表數(shù)據(jù),數(shù)據(jù)仍存儲在HDFS上)匯總基礎(chǔ)sql操作夭苗。
1信卡、創(chuàng)建/刪除數(shù)據(jù)
(1)無中生有
創(chuàng)建一個包含id,name,age,class信息的表,要求id题造、age為數(shù)值型傍菇,name、class為字符型界赔。
# 表格框架
spark.sql("create table IF NOT EXISTS student(id int, name string,age int,class string) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'")
# 插入行數(shù)據(jù)
spark.sql("insert into student values(1,'小明',23,'奧數(shù)')")
spark.sql("insert into student values(2,'小紅',33,'英語')")
spark.sql("insert into student values(3,'小紅',13,'語文')")
spark.sql("insert into student values(4,'小朱',43,'體育')")
spark.sql("insert into student values(6,'Lily',13,'英語')")
spark.sql("insert into student values(7,'Mark',53,'英語')")
# 效果查看
spark.sql("select * from student").show()
(2)查詢建表
原創(chuàng)建表挺麻煩的丢习,查詢建表更方便一些。
spark.sql("create table if not exists student2 select id, name from student")
spark.sql("select * from student2").show()
(2)drop 刪除表格
如果不想要student2這張表淮悼,使用drop table刪除咐低。
spark.sql("drop table student2")
2、函數(shù)操作
(1)日期相關(guān)函數(shù)
想要在表格上新增一列日期信息袜腥。
unix_timestamp()為獲取當前時間戳的函數(shù)(格式為:1572853933)见擦,from_unixtime函數(shù)轉(zhuǎn)換時間戳為日期格式。
spark.sql("create table if not exists student2 as select *,from_unixtime(unix_timestamp(),'yyyy-MM-dd HH:mm:ss') as date from student")
spark.sql("select * from student2").show()
# 取時間范圍的數(shù)據(jù)(取昨天的數(shù)據(jù))
# Hive SQL中的[datediff(endDate, startDate)函數(shù)返回的是2個日期的天數(shù)差值
# CURRENT_DATE為當前時間
spark.sql("select CURRENT_DATE").show() # 查看當前日期
spark.sql("select * from student2 where datediff(CURRENT_DATE,date)=1").show()
(2)row_number 數(shù)據(jù)表去重
表格有兩個小紅存在羹令,想根據(jù)name對數(shù)據(jù)去重鲤屡。
hive中使用row_number()對表格去重「3蓿“row_number() over (partition by name order by id desc) ” 根據(jù)name去重酒来,根據(jù)id排序
spark.sql("select * from (select id,name,age,row_number() over (partition by name order by id desc) as rn from student) t where t.rn = 1").show()
(3)group by 統(tǒng)計各類及數(shù)量
想要知道有多少類學科,每類學科有多少人肪凛?
spark.sql("select class,count(1) from student group by class").show()
(4)and/or 多條件檢索
檢索name為小紅堰汉,age大于30的數(shù)據(jù)信息辽社。
spark.sql("select * from student where name='小紅' and age>30").show()
(5)Concat組裝新信息
Concat()將多個字符串連接成一個字符串
spark.sql("create table if not exists student3 as select *, concat(name,'編號為',id,',年齡為',age,'衡奥,教授',class) as info from student")
spark.sql("select * from student3").show()
(6)join 黑名單匹配/過濾
已知學校存在一個黑名單庫爹袁,想要只查看匹配黑名單的信息
# 先創(chuàng)建黑名單
spark.sql("create table IF NOT EXISTS blackStudent(name string) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'")
spark.sql("select * from blackStudent").show()
spark.sql("insert into blackStudent values('小明')")
spark.sql("insert into blackStudent values('小紅')")
spark.sql("insert into blackStudent values('王菲')")
spark.sql("insert into blackStudent values('江山')")
spark.sql("insert into blackStudent values('肖戰(zhàn)')")
spark.sql("insert into blackStudent values('王一博')")
# 匹配黑名單,inner join取兩張表的合并部分
spark.sql("select * from student inner join blackStudent on student.name=blackStudent.name").show()
想要過濾黑名單的成員信息然后存儲成一張新表
# left outer join 以左表 student為核心做匹配矮固,去未匹配成功(null)的信息
spark.sql("create table student4 select id, student.name,age,class from student left outer join blackStudent on student.name=blackStudent.name where blackStudent.name is null")
spark.sql("select * from student4").show()
4失息、udf
UDF(user-defined function),當hive自帶的函數(shù)無法滿足數(shù)據(jù)預處理档址,支持自建函數(shù)盹兢。
def mymodel(age):
if age>20:
result=0
else:
result=1
return result
from pyspark.sql.types import IntegerType
spark.udf.register('mymodel',mymodel,IntegerType()) # 函數(shù)返回值類型為integer
spark.sql("select * from student3 where mymodel(age)>0").show()
三、大規(guī)模數(shù)據(jù)處理
Spark 是專為大規(guī)模數(shù)據(jù)處理而設(shè)計的快速通用的計算引擎守伸,傳統(tǒng)基于本地python計算的模式在面對大規(guī)模數(shù)據(jù)量時性能和時間都無法保障绎秒,基于spark的機器學習很重要哦。
參考資料
[1] 數(shù)據(jù)倉庫入門尼摹,看這這一篇就夠了:https://zhuanlan.zhihu.com/p/39611221
[2] hive簡介:https://www.shiyanlou.com/courses/reports/1385266/
[3] Spark是否能替代Hive:https://blog.csdn.net/ys_230014/article/details/83210800