點擊上方藍色字體,選擇“設為星標”回復”資源“獲取更多資源
什么是數倉
從字面上來看,數據倉庫就是一個存放數據的倉庫,它里面存放了各種各樣的數據,而這些數據需要按照一些結構、規則來組織和存放。這里我們會遇到一個問題就是同樣是存放數據的倉庫,那數據庫和數據倉庫是一樣的嗎?
數據庫 VS 數據倉庫
數據庫就是我們常用的關系型數據庫(MySQL、、...),還有什么非關系型數據庫,它主要存放業務數據,那數據倉庫有有些什么數據呢?說到他們的區別,我們一般會提到OLTP和OLAP。
他們的區別,面試時也會提到,主要從幾個點談談就行。
數據倉庫其實是一套體系,他不是一門什么技術,而是整合了很多已有的技術,來更好地組織和管理數據。傳統數倉的話,主要是基于關系型數據庫,后面還有一些分布式的數據庫像,還有很多公司會提供基于硬件的一整套解決方案。在傳統數倉開發時,由于硬件的性能有限,所以有很多的要求,而隨著硬件價格的下降、云服務器的廣泛使用,還有大數據技術的成熟發展,數倉的很多場景都變了,有些規則都不需要去嚴格遵守了,這樣也可以剩下很多的成本。
再往前幾年,數倉這個東西是有點兒神秘的,感覺很高大上,而現在,起碼在互聯網公司來說gp數據庫創建臨時表,誰都知道數倉,誰都知道數據平臺,誰都可以來說兩句,已經大眾化了。記得以前面數倉的話,總有幾個必備的面試題:
就目前互聯網數倉這一崗位,感覺更加偏重業務+建模思想,面試不太好考察這些內容的,去年招聘的時候,就是問些基本問題,聊聊以往主要的工作內容,還會問問SQL題,真的想了解下建模的話,還是找本書借鑒性的看看,還是很有益處的。
傳統數倉與互聯網數倉
在傳統數據平臺要背后有一個完整數據倉庫團隊去服務業務方,業務方嗷嗷待哺的等待被動方式去滿足。中低層數據基本不會對業務方開放,所以不管數據模型采用何種建模方式,主要滿足當時數據架構規劃即可。
互聯網業務的快速發展使得大家已經從經營、分析的訴求重點轉為數據化的精細運營上,如何做好精細化運營問題上來,當資源不夠時用戶就叫喊,甚至有的業務方會挽起袖子來自己參與到從數據整理、加工、分析階段。
此時呢,原有建設數據平臺的多個角色(數據開發、模型設計)可能轉為對其它非專業使用數據方,做培訓、咨詢與落地,寫更加適合當前企業數據應用的一些方案與開發些數據產品等。
在互聯網數據平臺由于數據平臺變為自由開放,大家使用數據的人也參與到數據的體系建設時,基本會因為不專業性,導致數據質量問題、重復對分數據浪費存儲與資源、口徑多樣化、編碼不統一、命名問題等等原因。數據質量逐漸變成一個特別突出的問題。
數倉架構
現在說數倉,更多的會和數據平臺或者基礎架構搭上,已經融合到整個基礎設施的搭建上。這里呢,我們不說各種組件之間的配合,我們就簡單說下數倉的分層架構。
說到數倉建模,就得提下經典的2套理論:
范式建模
Inmon提出的集線器的自上而下(EDW-DM)的數據倉庫架構。
維度建模
提出的總線式的自下而上(DM-DW)的數據倉庫架構。
數倉的建模或者分層,其實都是為了更好的去組織、管理、維護數據,實際開發時會整合2種方式去使用,當然,還有些其他的,像Data Vault模型、模型,暫時還沒有應用過,就不說了。
維度建模,一般都會提到星型模型、雪花模型,星型模型做OLAP分析很方便。
數倉分層
簡單點兒,直接ODS+DM就可以了,將所有數據同步過來,然后直接開發些應用層的報表,這是最簡單的了;當DM層的內容多了以后,想要重用,就會再拆分一個公共層出來,變成3層架構,最近看了本阿里的書,《大數據之路》,里面有很多數倉相關的內容,很不錯,參考后,目前使用的分層模式如下:
按照這種分層方式,我們的開發重心就在dwd層,就是明細數據層,這里主要是一些寬表,存儲的還是明細數據;到了dws層,我們就會針對不同的維度,對數據進行聚合了,按道理說,dws層算是集市層,這里一般按照主題進行劃分,屬于維度建模的范疇;ads就是偏應用層,各種報表的輸出了。
指標字典
前面我們說過,數倉是一套體系,一個建設過程,它整合了很多的方法論,并不是一門新的技術。這里我們說說數倉中的指標體系,指標也不是數倉或者數據平臺中特有的, 很多場景都會有指標這個概念。
這里我們說的指標,其實就是KPI(Key ),關鍵績效指標。
企業關鍵績效指標(KPI:Key )是通過對組織內部流程的輸入端、輸出端的關鍵參數進行設置、取樣、計算、分析,衡量流程績效的一種目標式量化管理指標,是把企業的戰略目標分解為可操作的工作目標的工具,是企業績效管理的基礎。KPI可以使部門主管明確部門的主要責任,并以此為基礎,明確部門人員的業績衡量指標。
數據平臺的作用是為分析、決策提供支持,來時刻關注企業的運營情況的。那我們怎樣來看公司的運營情況呢?就是看KPI,公司層面有公司最關注的KPI,比如:日活、GMV、訂單量等等;不同的部門又有不同的關注KPI,比如:新用戶數、復夠人數等等,有了KPI,我們就可以根據KPI來考察部門的表現,也就是績效。這也是數字化轉型嘛,所有的管理、績效都數字化。
就數據平臺來說,指標算是元數據的一種,指標的維護和管理是有套路的,下面就簡單分享下關于指標的管理-指標字典。
指標字典
指標字典,其實就是對指標的管理,指標多了以后,為了共享和統一修改和維護,我們會在Excel中維護所有的指標。當然,Excel對于共享和版本控制也不是很方便,有條件的話,可以開發個簡單的指標管理系統,再配合上血緣關系,就更方便追蹤數據流轉了。
指標編碼
為了方便查找和管理,我們會對指標定義一套編碼
指標類型
基礎指標:不能再進一步拆解的指標,可以直接計算出來的指標,如“訂單數”、“交易額” 衍生指標:在基礎指標的基礎上,通過某個特殊維度計算出的指標,如“微信訂單數”、“支付寶訂單數” 計算指標:通過若干個基礎指標計算得來的指標,在業務角度無法再拆解的指標,如“售罄率”、“復購率”
業務口徑
指標最重要的就是,明確指標的統計口徑,就是這個指標是怎么算出來的,口徑統一了,才不會產生歧義
指標模板
除了上面,我們說到的幾點,還有一些基本的,像“指標名稱”、計算公式,就組成了指標的模板
以前的話,我們還會有責任部門,就是說這個指標是哪個部門負責維護的,這個KPI是哪個部門來關注和承擔。說到指標,就離不開維度,我們后面會說說維度的故事。
指標的梳理和管理
一開始指標的梳理是很麻煩的,因為要統一一個口徑,需要和不同的部門去溝通協調;還有可能會有各種各樣的指標出現,需要去判斷是否真的需要這個指標,是否可以用其他指標來替代;指標與指標之間的關系也需要理清楚。
而且第一版指標梳理好之后,需要進行推廣和維護,不斷地迭代,持續推動,讓公司所有部門都統一站在一個視角關注問題。
最重要的維度之日期維度
日期維度是我們最常用的維度,平臺初始,最先初始化的可能就是日期維度,這里我們就簡單介紹下日期維度。
什么是日期維度
我們日常生活,數據的產生都和日期有關,每一分、每一秒都會產生數據,數據分析也離不開日期。
日期維度就是一張固化的日歷,一年365天,每一天都有,我們打開電腦中的日歷:
這里面有的,我們都可以固化下來,像周幾、農歷、年、月、日、節假日,我們都可以固化下來,方面我們分析的時候使用。
日期維度的結構
日期維度可以盡可能多的包含日期詳細信息,這樣在分析的時候可以直接使用,還要結合公司的一些特殊情況,像一些特殊展示的日期格式。
除了上面的基本的日期,平時用的還有有些拓展信息
可能還有些農歷信息、農歷年份等,公司自定義周的開始日期、結束日期等,和日期相關的所有內容都可以加進來進行維護。
數據初始化,我們可以使用Java、或者SQL,通過常用的日期函數基本可以滿足我們的數據需求,用SQL初始化,需要使用有循環控制語句的,如:MySQL、PG都行,Hive的話要結合Shell或者來使用。
一般不需要初始化太多年的數據,只要覆蓋公司業務數據就好了,還有節假日信息每年都需要結合國務院發布的信息就行維護。
平時我們還會分析小時數據,一般不會把他放在日期表中,而是會單獨放在一張小時維度表里,需要的時候一起使用就行了。
命名規范
話說,沒有規矩不成方圓。在搭建數據平臺的時候,在數據組內部,一定要先制定好各種規范,越早越好,并且不斷的監督大家是否按照約定執行。一旦讓大家自由發揮,后期想要統一或者重構,會浪費很大的人力成本和時間成本,記住,這都是坑。
這里以我目前公司的一些經驗,分享下。
關于項目
常規來說,數倉的建設是按照數倉分層模型開發的。也有會按照業務線來分層,在各自業務線下重新分層,單獨開發的。我這里使用的是阿里云的,這是阿里提供的數據平臺,一整套開發環境,用起來還是很方便的,省去了自建平臺的麻煩。里面有一個項目的概念,一開始本來打算直接根據分層模型的設計來創建項目,但是由于某種原因,改成了按照業務線來創建項目。對于這個項目名,一定要想好,不管根據什么來設計,都需要想清楚,想明白,定了以后就不要再改了,也沒法改。
關于詞根
我忘記是不是叫“詞根”了,先寫著,后面找本書確認下。詞根屬于數倉建設中的規范,屬于元數據管理的范疇。哦,現在都把這個劃到數據治理的一部分。
正常來說,完整的數倉建設是包含數據治理的,只是現在談到數倉偏向于數據建模,而談到數據治理,更多的是關于數據規范、數據管理。
接著說我們的主角-詞根。
我們學習英語的時候應該有了解過詞根這個東西,它就是最細粒度的最簡單的一個詞語,我們主要用來規范中文和英文的映射關系。我們公司一部分業務是關于貨架的,英文名是:rack,rack就是一個詞根,那我們就在所有的表、字段等用到的地方都叫rack,不要叫成別的什么。這就是詞根的作用,用來統一命名,表達同一個含義。指標體系中有很多“率”的指標,都可以拆解成XXX+率,率可以叫rate,那我們所有的指標都叫做XXX+rate。詞根可以用來統一表名、字段名、主題域名等等。
表名
表名需要見名知意,通過表名就可以知道它是哪個業務域,干嘛用的,什么粒度的數據。
常規表是我們需要固化的表,是正式使用的表,是目前一段時間內需要去維護去完善的表。規范:分層前綴[dwd|dws|ads|bi]業務域主題域XXX粒度 業務域、主題域我們都可以用詞根的方式枚舉清楚,不斷完善,粒度也是同樣的,主要的是時間粒度、日、月、年、周等,使用詞根定義好簡稱。
中間表一般出現在Job中,是Job中臨時存儲的中間數據的表,中間表的作用域只限于當前Job執行過程中,Job一旦執行完成,該中間表的使命就完成了,是可以刪除的(按照自己公司的場景自由選擇,以前公司會保留幾天的中間表數據,用來排查問題)。規范: [0~9|dim] 是我們任務中目標表的名字,通常來說一個任務只有一個目標表。這里加上表名,是為了防止自由發揮的時候表名沖突,而末尾大家可以選擇自由發揮,起一些有意義的名字,或者簡單粗暴,使用數字代替,各有優劣吧,謹慎選擇。通常會遇到需要補全維度的表,這里我喜歡使用dim結尾。
中間表在創建時,請加上 ,如果要保留歷史的中間表,可以加上日期或者時間戳
drop table if exists table_name;
create table_name as xxx;
臨時表是臨時測試的表,是臨時使用一次的表,就是暫時保存下數據看看,后續一般不再使用的表,是可以隨時刪除的表。規范: 只要加上tmp開頭即可,其他名字隨意, 注意tmp開頭的表不要用來實際使用,只是測試驗證而已。
維度表是基于底層數據,抽象出來的描述類的表。維度表可以自動從底層表抽象出來,也可以手工來維護。規范: 維度表,統一以dim開頭,后面加上,對該指標的描述,可以自由發揮。
手工表是手工維護的表,手工初始化一次之后,一般不會自動改變,后面變更,也是手工來維護。一般來說,手工的數據粒度是偏細的,所以,暫時我們統一放在dwd層,后面如果有目標值或者其他類型手工數據,再根據實際情況分層。規范:dwd _ 業務域 xxx 手工表,增加特殊的主題域,,表示手工維護表
指標
指標的命名也參考詞根,避免出現同一個指標,10個人有10個命名方法。
具體操作結合公司實際情況,規范及早制定。
數據治理
廣義數據倉庫的建設包含很多的解決方案,其中就包含數據治理,數據治理也是貫穿整個項目始終的,是一件長久的事情。現在很多人都把數據倉庫簡單的理解成數據建模了。
數據治理包含很多的事情,我也沒做過,所以在網上找些資料分享下。
為什么要做數據治理
隨著數據量越來越大,數據成為一種資產,我們需要更好地管理這些數據,更好地體現數據的價值,這就需要數據治理。其實在搭建數據平臺的時候,我們遇到的一系列問題都可以通過數據治理來解決:
數據治理(Data ),是一套持續改善管理機制,通常包括了數據架構組織、數據模型、政策及體系制定、技術工具、數據標準、數據質量、影響度分析、作業流程、監督及考核流程等內容。
簡單來說就是有很多流程和標準,像“元數據管理”、“主數據管理”、“數據質量”都包含其中。
通過數據治理來解決我們使用數據的過程中遇到的問題。
這部分內容你可以參考:
關于增量
很多初學者或者沒有做個ETL這件事兒的同學對這個增量是有誤解的,尤其是在和業務開發同學對接的時候,他們對這個增量的理解也是有偏差的。
先來說說他們以為的增量是什么。他們以為“增量,就是按照時間增量去拿就好了,增量同步,你就把增量后的數據給我好了,不要總是全量同步。” 按道理說,這么做思路是對的,但是不嚴謹,而且會出錯,下面我們就一步一步看看。
1.什么是增量
增量是相對于全量來說的,它們都是處于“同步數據”這個場景下的,比如說業務系統的數據同步到數倉,數倉的數據同步給業務系統,都會使用同步的方式,這都是相對于我們開發來說的,從數據庫級也是可以同步的,這里我們就不介紹了。
全量同步,就是說把數據全部同步過去,100條就同步100條,1萬條就同步1萬條,1億條就同步1億條,大家也應該會發現這種方式存在的問題,在數據量小的時候,全量同步簡單方便易執行,而當數據量大了以后,尤其是歷史數據不會經常變化的時候,全量同步就會浪費大量的資源和時間,嚴重影響同步效率。
--全量同步一般先delete,然后insert
delete from tmp_a;
insert into tmp_a xxx;
-- 或者直接 insert overwrite
insert overwrite table tmp_a xxx;
SQL語法可能不太一樣,差不多就是這個意思,哈哈
記住一定要刪除或者覆蓋插入,不然數據可就越來越多了。
選擇增量同步的幾個場景:
使用增量同步,對表有一些要求,比如,需要有,字段 表示記錄創建時間,表示記錄更新時間,增量的話,只需要把變化的數據拿過來就行了(使用),注意:這里還需要有一個主鍵,主鍵是用來覆蓋數據的。
這里和不同的業務場景有關系,有的記錄創建后不會再更新,類似于流水數據,這種數據直接增量拿過來就好,可以不進行刪除操作;但是有的數據是會更新的,當已經同步過來的數據發生了變化,數倉側也是需要同步發生變化的。
2. 怎么做增量
增量同步也是要做一次初始化的,初始化是全量來的。
假設我們有這樣一張表:
create table tmp_a(
id bigint,
create_time datetime,
update_time datetime
);
一般離線場景下,都會選擇在業務量最少的時候去做同步操作,而這個時間大部分都是在半夜凌晨的時候,所以大部分同步都是從0點以后開始,同步昨天的數據,也就是常說的T+1了。
假設3月1號創建了如下4條記錄,數倉會在2號凌晨進行同步
2號的時候,新增了1條記錄,并且有一條記錄更新了gp數據庫創建臨時表,按照增量規則,我們會拿到兩條記錄
拿到增量數據之后,我們需要將增量的數據合并到我們數倉的表中
新增的數據,可以直接插入,但是更新的數據,我們需要把原紀錄更新掉,或者先刪除再插入,以前我們還會記錄一個數據插入的狀態,如果是更新的,就記一個“”,如果是插入的就記一個“”,到了這里,應該知道為啥需要有主鍵了吧,如果沒有主鍵,你咋知道這條記錄到底變沒變過。
使用增量,一般需要兩套表,一套表用來存增量數據,一套用來存完整的全量數據。
3.
不管是增量還是全量,我都比較喜歡加一個時間戳字段,用來標識記錄的插入時間,這個尤其是在對比增量數據的時候,排查數據問題很有用。
4. 我們公司的同步機制
我們呢,一創業公司,數據量不算多,使用的都是阿里云的工具,一開始為了方便,所有的數據,都是全量來的,剛看了眼數據量又10幾T吧,其中很多是歷史數據。
雖然我們是全量來的,但是為了捕捉記錄數據的變化,用的是pt(分區)的方式,每天都是一個全量快照,這也是現在存儲便宜的一種處理方法,簡單粗暴。我剛來的時候,就提過搞成增量,被拒絕了,后來也沒有人來搞這個,表太多了,修改起來成本太高。
5. 基于Hive的增量
Hive現在也算是標配了,上面說的增量方案,可能還是基于關系型數據庫的,在Hive上,由于運算能力更強大,可以不考慮數據量的問題,所以衍生出來幾種方案。主要原因還是Hive上對于操作的支持問題,盡量不要有。
我們依然每天獲取增量數據,然后將增量數據插入到每個分區中,每個分區都是當天的增量數據,當然數據變化的話,同一個主鍵的記錄會出現在多個分區中,所以如果我們要獲取最新的完整版數據,可以使用根據主鍵和時間排序,獲取最新版本的全量數據
使用full join的方式,將增量數據和歷史全量數據,進行關聯,然后取出最新完整版數據
這個和full join的方式類似,感覺這個更美觀嚴謹一些,以前在GP上面做增量也用的這種方式。
6. 拉鏈表
說到增量,也需要提一下拉鏈表,拉鏈表以前用的多一些,感覺在互聯網公司用的很少,基本都使用分區的方式處理掉了。拉鏈表其實就是記錄數據的每一次變化,處理起來稍微有點兒麻煩,這個以前好像寫過,等我找找貼過來。
上下游約定
由于數倉的特性和定位,它就需要強依賴上游的業務系統,當然也會有一些下游系統,所以定好上下游的規范,變更的通知機制是非常有必要的。
感覺好像寫過上下游的事情,剛才沒找到,這里就再重新寫寫。
上游
這里說的主要是基于小公司,類似我目前所在的創業公司為例,像發展成熟的大公司,各種流程規定、容錯監控類的機制都很完善,對于這些場景,我說的可能就不適用了。
對于數倉來說,最重要的就是數據了,數倉中的數據,主要來源是業務系統,就是公司各種業務數據,所以數倉需要不斷的將業務系統數據同步到自身平臺來,所以一旦上游業務系統發生變化,數倉也要同步變化,不然,這種同步操作很可能失敗。
上游的表結構經常會發生變化,新增字段、修改字段、刪除字段(除非真的不用這個字段了,通常會選擇標識為棄用)。表結構最好要維護清楚,表名、字段名、字段類型、字段描述,都整理清楚,不使用的字段要么刪除,要么備注好,當業務頻繁發生變化或者迭代優化的時候,很容易出現,我寫了半天的代碼,最后發現表用的不對,字段用的不對,這就尷尬了。
對于這種變化,人工處理的話,就是手動在數倉對應的表中增加、修改字段,然后修改同步任務;這個最好可以搞成自動化的,比如,自動監控上游表結構的變更,變化后,自動去修改數倉中的表結構,自動修改同步任務。
業務系統中會有很多的常量,用來標識一些狀態或者類型,這種值經常會新增,數倉中會對這些值做些處理,比如轉換成維度,會翻譯成對應的中文,而實際上這種映射關系,我們是不知道的,只有業務開發才知道,所以最好可以讓他們維護一張枚舉值表,我們去同步這張表。
正常來說,,當這條記錄插入后,就不會再變了,但是某種情況下,哈哈,開發同學會去更新它;,當這條記錄變化后,這個時間也要變,有的開發同學不去更新它......
所以在做增量操作的時候,一定和開發說好這兩個字段的定義和使用場景。
有些場景下,我們需要刪除某些數據,一般不會物理刪除,會通過一個字段來做邏輯刪除,請和開發同學溝通好,使用固定的一個字段,并確認該字段雙方的理解是一致的,不然后面又很多坑。
下游
說完了上游,我們說說下游,對于數倉來說,一般的郵件、報表、可視化平臺都是下游,所以當我們在數倉中進行某些重構、優化操作的時候,也需要通知他們。
主要就是對數倉模型做好維護,表的使用場景、字段描述等。
對上游的要求,自己也要做好,因為自己也是上游。
任務注釋
這一篇說說注釋,注釋總是讓人又愛又恨。
沒有注釋,誰知道你這些代碼是用來干嘛的,從代碼角度來看,你想做的是A,而實際上需求確是B,具體干啥得靠猜;代碼有注釋,也不一定就可以高枕無憂,注釋可能是最初版的需求,改了幾版后,代碼早就變了,注釋沒有變,注釋和代碼不匹配,誰知道該以哪個為準啊。
我們的數倉都是基于阿里云的,使用了它的作為離線工具,所有的代碼都在這上面,所以這里簡單介紹下,在阿里云上的任務,幾點注釋規范。
-- @name p_dwd_rack_machine
-- @description 貨架寬表
-- @target rack.dwd_rack_machine
-- @source owo_ods.kylin__machine_release_his
-- @source owo_ods.kylin__machine_device_his
-- @author yuguiyang 2017-12-25
-- @modify
@name:任務的名字,我們的任務名一般都是以 p_目標表名,后來阿里的升級后,推薦是任務名和表名保持一致。
@:任務描述,該任務的主要內容 @:目標表名,一般一個任務只輸出一個目標表
@:來源表,就是任務中使用的底層表,這里也可以省略,從血緣關系中可以直接看到,而且很容易漏更新
@:創建者,和創建日期, @:內容變更記錄,變更人,變更日期,變更原因 ,這個從版本控制中也可以找到,但是這些這里更直觀一些。
留個微信,朋友圈更新大數據領域最新動態&面試題等,好友位有限,先到先得。