數(shù)據(jù)倉庫常見面試問題
一、如何建設(shè)一個好的數(shù)據(jù)模型
從建模方法論以及一個好的數(shù)據(jù)模型的幾大標(biāo)準(zhǔn)兩方面進(jìn)行闡述。
1.建模方法論
1)范式建模:多用于數(shù)據(jù)貼源層
2)維度建模:多用于dw層設(shè)計靜態(tài)報表
步驟:
選擇業(yè)務(wù)過程-》確認(rèn)粒度-》確認(rèn)維度-》確認(rèn)事實
舉例統(tǒng)計指標(biāo):
每天md5認(rèn)證申請的申請次數(shù),通過次數(shù),申請人數(shù),通過人數(shù)
業(yè)務(wù)過程:對應(yīng)的是業(yè)務(wù)流程中借款申請之前的md5身份證提交認(rèn)證的過程,對應(yīng)的是APP server業(yè)務(wù)系統(tǒng)中的md5申請表,核心字段有申請人id,身份證號,姓名,性別,住址,用戶類型,客戶經(jīng)理,身份證圖片url,申請時間等。
確認(rèn)粒度:確認(rèn)粒度也就是確認(rèn)事實表的一行記錄所代表的含義是什么,原則是粒度越細(xì)越好,粒度越細(xì)代表還原的業(yè)務(wù)細(xì)節(jié)就越豐富,支撐的指標(biāo)也就更多。比如這里根據(jù)統(tǒng)計的幾個指標(biāo)就可以將粒度確定為一條md5申請記錄
確認(rèn)維度:確認(rèn)維度也就是確認(rèn)事實所發(fā)生的環(huán)境信息,一般根據(jù)場景代入以及5w1h原則找維度,也就是走一遍流程,比如提交md5申請,可以定義為誰什么時間在什么地方通過什么設(shè)備提交了一條申請記錄,那這里可以確定的維度信息就有用戶id,性別,日期,地區(qū),設(shè)備等。對于簡單的維度比如性別這種我們會直接退化到事實表中,其它大部分維度直接從業(yè)務(wù)庫同步或者簡單加工即可,有一些時候比如日期這種維度表可能就需要自定義,比如有時候需要按季度,月份,星期去統(tǒng)計,這個時候定義一張日期表比較方面,可以減少代碼中大量的case when判斷邏輯。
3)領(lǐng)域建模:多用于dw層設(shè)計動態(tài)報表
建模步驟:
找到這個領(lǐng)域全鏈路過程涉及的業(yè)務(wù)過程,每一個或多個業(yè)務(wù)過程劃分為子域,每個業(yè)務(wù)過程進(jìn)行事件編碼,作為后續(xù)的二級分區(qū)字段。而對于每一個子域內(nèi)部的建模過程還是跟維度建模過程一樣(選擇業(yè)務(wù)過程-》確認(rèn)粒度-》確認(rèn)維度-》確認(rèn)事實)。
舉例:
用戶借貸行為事件領(lǐng)域模型:解決個人申請貸款,授信,放款審批,放款通過以及還款全鏈路的運營分析,導(dǎo)出動態(tài)報表。
用戶借貸行為事件領(lǐng)域模型是我優(yōu)化的一個模型,是之前的同事基于前瞻性的考慮,圍繞用戶申請貸款,授信,放款審批,放款通過,還款等全鏈路流程設(shè)計的模型,后面運營分析云平臺也確實有用到了,
但是那個模型跑的很慢,需要3個多小時,而且在ck做自定義事件查詢的時候速度也很慢,所以我后面進(jìn)行了優(yōu)化。我一般的優(yōu)化思路分為以下幾步
1)先看資源能不能協(xié)調(diào)
2)看看調(diào)優(yōu)參數(shù)能不能起作用
3)sql邏輯有沒有值得優(yōu)化的地方
4)然后再考慮模型上能不能優(yōu)化
5)最后模型上不能優(yōu)化了再去考慮架構(gòu)上是不是能優(yōu)化
最后定位這個問題的核心關(guān)鍵點是在于模型設(shè)計上的問題,之前的同事是直接將多個業(yè)務(wù)過程直接橫向通過用戶id將進(jìn)行關(guān)聯(lián),會涉及上層事實表的join,所以會特別慢。
所以我的方式是把借貸行為整個鏈路的業(yè)務(wù)過程進(jìn)行了縱向拆分。具體是基于用戶實體+行為事件進(jìn)行建模,借貸行為事件作為一個大域,其中的每個業(yè)務(wù)過程作為子域,
對每一個子域的行為事件進(jìn)行編碼,比如申請借款事件編碼為‘LoanApply’,風(fēng)控申請事件編碼為‘riskApply’,這樣的話多業(yè)務(wù)過程通過縱向劃分進(jìn)行了解耦。
在代碼上體現(xiàn)的就是,表字段還是包含每個業(yè)務(wù)過程的度量值和統(tǒng)計維度,分區(qū)是由原來的一級日期分區(qū),變成了二級分區(qū),一級分區(qū)是日期,二級分區(qū)是事件編碼,比如說
現(xiàn)在往表里面插入的是申請貸款行為事件數(shù)據(jù),那就計算申請貸款行為事件相應(yīng)的字段,然后其它事件的字段取0即可,這樣就避免了多個業(yè)務(wù)過程之間事實表的join,新增一條事件也不會影響原來的
邏輯,做到了業(yè)務(wù)過程內(nèi)部高內(nèi)聚,業(yè)務(wù)過程之間低耦合。最后整個模型的跑批時間從原來的3個小時降低到了40分鐘。
2.設(shè)計一個好的數(shù)據(jù)模型要考量的幾點
1)準(zhǔn)確性高
準(zhǔn)確性即要保證最好統(tǒng)計指標(biāo)的數(shù)據(jù)質(zhì)量,如何保證?
①理解業(yè)務(wù)需求,也就是熟悉業(yè)務(wù),統(tǒng)一指標(biāo)口徑
②保證貼源層數(shù)據(jù)的準(zhǔn)確性
數(shù)據(jù)貼源層要考慮的是數(shù)據(jù)的完整性,主要是同步過來的數(shù)據(jù)中核心字段是否為空,是否有臟數(shù)據(jù)需要清洗過濾,以及數(shù)據(jù)記錄數(shù)是否一致。
③保證統(tǒng)計邏輯準(zhǔn)確性
編碼規(guī)范,測試。
在編寫算法之前,先獲取適量的生產(chǎn)數(shù)據(jù)用于后續(xù)測試。
開發(fā)環(huán)境編碼時:
編碼的時候我的習(xí)慣是對于那些比較復(fù)雜的邏輯,我會通過with語法或者cache創(chuàng)建臨時表的方式分階段編寫,每個階段用生產(chǎn)數(shù)據(jù)進(jìn)行測試。這樣有兩個好處,一是條理清晰,分階段測試,保證一個大邏輯里面每一小部分的代碼正確,也就保證了整體邏輯的正確性。二是后續(xù)如果有問題,便于后續(xù)的問題定位,方便維護(hù)。
開發(fā)環(huán)境測試完畢后,再提交到測試環(huán)境測試,最后再上線到生產(chǎn)環(huán)境,由相應(yīng)的驗收人員進(jìn)行測試。
2)穩(wěn)定性好
穩(wěn)定性則是支持任務(wù)的重復(fù)跑批,且跑批結(jié)果穩(wěn)定一致。在代碼中的體現(xiàn)是盡量多用insert overwrite而不是insert into
3)復(fù)用性高
復(fù)用性好也就是我們設(shè)計的模型要被盡量多的下游任務(wù)使用。一個模型復(fù)用性高那它所還原的業(yè)務(wù)細(xì)節(jié)必須很豐富,就對應(yīng)我們設(shè)計事實表的時候粒度越細(xì)越好,同時選擇盡可能多的維度供下游使用。
4)可拓展性強
可拓展性強指后續(xù)如果有需求添加變更,不用改動或者大幅度改動原有的數(shù)據(jù)模型,在原有邏輯上進(jìn)行拓展即可。一個模型拓展性強則盡量讓業(yè)務(wù)過程之間進(jìn)行解耦,領(lǐng)域建模就是很不錯的方式。
5)規(guī)范性
規(guī)范性則是我們設(shè)計模型的表命名要規(guī)范,能夠見名知意,看名字就知道這個模型屬于哪一個主題域,是干什么用的,方便后續(xù)模型的使用和維護(hù)。