一文讀懂?dāng)?shù)據(jù)建模的類型

如果您仍在直接提取數(shù)據(jù):從日志中Select *,并希望您的分析能夠跟上,那么是時(shí)候重新考慮您的方法了。可擴(kuò)展、可靠的數(shù)據(jù)工程——Airbnb、Netflix 和 Uber 等頂級(jí)科技公司所實(shí)踐的那種——依賴的不僅僅是基本的模式。它始于數(shù)據(jù)建模技術(shù),這些技術(shù)可以優(yōu)化管道、加快查詢速度,并使您的工程工作更順暢、更易于維護(hù)。
數(shù)據(jù)建模是將原始、混亂的數(shù)據(jù)轉(zhuǎn)換為可靠、可擴(kuò)展系統(tǒng)的藍(lán)圖。它能讓您設(shè)計(jì)出易于維護(hù)、查詢速度快且值得信賴的數(shù)據(jù)管道!
在本文中,您將了解經(jīng)驗(yàn)豐富的數(shù)據(jù)工程師用來理順混亂流程的強(qiáng)大數(shù)據(jù)建模策略。這些模式對(duì)于構(gòu)建強(qiáng)大的數(shù)據(jù)系統(tǒng)至關(guān)重要——無論是從零開始還是改進(jìn)舊有工作流程。


1.主鍵
假設(shè)你經(jīng)營著一家小型冰淇淋店,并保存了一份顧客名單。你可能有多個(gè)名叫Alex的顧客,但你不想在記錄銷售額時(shí)混淆他們。因此,你給每個(gè)顧客分配了一個(gè)唯一的 ID 號(hào):

這里,Customer_Key是主鍵——它是唯一標(biāo)識(shí)此表中每一行的列。即使兩個(gè)人的名字相同,他們的Customer_Key也總是不同的。
因此,在數(shù)據(jù)庫中,主鍵是表中的一列或多列的組合,用于唯一標(biāo)識(shí)該表中的每一行。
關(guān)鍵規(guī)則:
唯一性——沒有兩行可以具有相同的主鍵值。
非空— 主鍵必須始終有一個(gè)值(不能為空)。
穩(wěn)定性——它不應(yīng)該頻繁改變。
2.外鍵
在我們的冰淇淋店中,我們已經(jīng)在顧客名單中為每個(gè)顧客提供了一個(gè)唯一的 ID——他們的Customer_Key 。
現(xiàn)在,在我們記錄每筆購買的銷售記錄中,我們不必每次都寫“Alice Johnson”或“Bob Smith”。相反,我們只需寫上他們的Customer_Key。

銷售表
并將客戶詳細(xì)信息存儲(chǔ)在其他表中:

客戶表
這里Customer_Key是將銷售表鏈接到客戶表的外鍵。
外鍵是一個(gè)表中與另一個(gè)表中的主鍵相匹配的列,從而在兩者之間建立鏈接。
關(guān)鍵規(guī)則
匹配主鍵— 外鍵列中的每個(gè)值都必須存在于引用表的主鍵列中(除非允許 NULL)。
可以重復(fù)——與主鍵不同,相同的外鍵值可以出現(xiàn)在多行中(例如,同一個(gè)客戶多次購買)。
可以為 NULL — 如果關(guān)系是可選的,則外鍵可以為空。
現(xiàn)在我們了解了主鍵和外鍵,讓我們更深入地了解它們是如何組合在一起的。
3.事實(shí)表
在我們的冰淇淋店里,每當(dāng)有人買冰淇淋時(shí),你就把它寫在記錄本上:
日期:2025–08–13
口味: 巧克力
數(shù)量:2勺
價(jià)格:6美元
這個(gè)筆記本基本上是你的事實(shí)表——它是你記錄所有可測量事件(在本例中是銷售額)的地方。
在數(shù)據(jù)庫世界中,事實(shí)表存儲(chǔ)定量的、可測量的數(shù)據(jù)——可以計(jì)數(shù)、求和或計(jì)算平均值的數(shù)據(jù)。
因此,如果我們根據(jù)冰淇淋店筆記本中的銷售數(shù)據(jù)制作一個(gè)事實(shí)表,它可能看起來像這樣:

代表銷售額的事實(shí)表。
這里,Date_Key、Product_Key和Customer_Key是外鍵,分別鏈接到日期、產(chǎn)品和客戶表。Quantity和Sales_Amount是事實(shí)——我們想要測量和分析的實(shí)際數(shù)字。
到目前為止,我們先畫一個(gè)圖,稍后在介紹維度細(xì)節(jié)、SCD 和模式類型時(shí),我們可以繼續(xù)擴(kuò)展這個(gè)圖:
Date_Key ------ Product_Key ------ Customer_Key .........(外鍵) \ | / \ | / Sales_Fact Table
4.維度表
我們有銷售事實(shí)表,其中每一行使用外鍵記錄一次銷售:
|日期_Key |產(chǎn)品_Key |客戶_Key |數(shù)量|銷售_Amount | | --------- | ------------ | ------------- | -------- | ------------- | | 20250813 | 12 | 301 | 2 | 6.00 |
但這些關(guān)鍵數(shù)據(jù)只是數(shù)字而已。要真正理解銷售情況,我們需要知道:
代表什么日期20250813?
代表什么產(chǎn)品12?
誰是顧客301?
這就是維度表的作用所在——它們保存了所有的描述性細(xì)節(jié)。
維度表是數(shù)據(jù)倉庫中的表,用于存儲(chǔ)有關(guān)業(yè)務(wù)實(shí)體的描述性屬性(文本或分類信息)。
例如:客戶維度表:
|Customer_Key (PK) |姓名 |城市 |忠誠度狀態(tài) | | 301 |愛麗絲·約翰遜| 紐約 |金牌 |
| 302 |鮑勃 史密斯|波士頓 |銀牌 |
Customer_Key是這里的主鍵。
該表描述客戶但不包含銷售數(shù)字。
那么,我們再畫一下圖,里面有事實(shí)表,維度表,主鍵,外鍵。

冰淇淋店數(shù)據(jù)倉庫——事實(shí)表和鏈接維度。
現(xiàn)在我們已經(jīng)介紹了所有基礎(chǔ)知識(shí),讓我們想象一下這樣一種情況:我們想要跟蹤客戶及其最喜歡的口味。隨著時(shí)間的推移,一些客戶會(huì)改變他們喜歡的口味,我們需要決定如何在維度表中處理這些變化。所以,這就是 SCD 發(fā)揮作用的地方。
5.緩慢變化維度(SCD)
在數(shù)據(jù)倉庫中,維度表通常包含隨時(shí)間變化的屬性。正確管理這些變化對(duì)于準(zhǔn)確的報(bào)告和分析至關(guān)重要。根據(jù)維度屬性變化的處理方式,SCD 可分為不同類型。最常見的類型是類型 1、類型 2 和類型 3。
假設(shè)Bob 把他最喜歡的口味從 草莓 改為 薄荷。讓我們看看每種 SCD 類型如何處理這個(gè)問題:
| 客戶 ID | 姓名 | 最喜歡的口味 |
| 101 | 愛麗絲 | 香草 | | 102 | 鮑勃 | 草莓 | | 103 | 查理 | 巧克力 |
a. SCD 類型 1 — 覆蓋。
類型 1 只是用新值覆蓋舊值。
沒有保留任何歷史記錄,因此我們只能看到最新的信息。
當(dāng)歷史數(shù)據(jù)不重要時(shí)使用它。
因此,Bob 更改后的表格(類型 1):

SCD 類型 1:鮑勃以前最喜歡的口味“草莓”消失了。
b. SCD 類型 2 — 添加新行。
類型 2為每個(gè)更改添加一個(gè)新行。
這允許完整的歷史跟蹤。
通常包括StartDate、EndDate或CurrentFlag來識(shí)別活動(dòng)記錄。
因此,Bob 更改后的表格(類型 2):

SCD 類型 2:現(xiàn)在我們知道了鮑勃以前的口味以及他喜歡它的時(shí)間段。
c. SCD 類型 3 — 添加新列。
類型 3通過為先前的值添加新列來保留有限的歷史記錄。
僅可跟蹤一次先前的更改。
比類型 2 簡單,但不保留完整的歷史變化。
因此,Bob 更改后的表格(類型 3):

SCD 類型 3:我們可以看到 Bob 當(dāng)前和之前的風(fēng)格,但除此之外的舊歷史則無法追蹤。
6.數(shù)據(jù)倉庫模式
我們已經(jīng)介紹了如何管理不斷變化的數(shù)據(jù)。假設(shè)我們的冰淇淋店想要分析銷售情況、追蹤顧客偏好并高效管理庫存。為此,我們需要一種結(jié)構(gòu)化的方法來組織數(shù)據(jù),以便回答以下問題:
哪種口味最受歡迎?
哪些顧客購買巧克力最多?
本周我們的草莓冰淇淋庫存夠嗎?
這就是模式和數(shù)據(jù)建模發(fā)揮作用的地方。
在數(shù)據(jù)倉庫的背景下,模式就像定義數(shù)據(jù)組織方式的藍(lán)圖。它顯示了事實(shí)表(記錄交易或事件的位置)與維度表(描述實(shí)體,例如客戶、產(chǎn)品或位置)之間的關(guān)系。
把它想象成一張地圖:模式告訴你一切事物的位置和它們是如何連接的,這樣你就可以快速找到見解。

為什么是 Schemas ?????????????????????
現(xiàn)在我們有了基礎(chǔ),我們可以探索不同的模式類型——星型、雪花型和星系型——并看看我們的冰淇淋店如何使用每一種模式類型來回答業(yè)務(wù)問題。
a. 星型模式。
想象一下,我們的冰淇淋店想要了解其銷售情況。諸如“哪種口味的冰淇淋賣得最好?”或“Alice 這周買了多少個(gè)冰淇淋?”之類的問題應(yīng)該能夠快速回答。星型模式非常適合這類問題,因?yàn)樗砸环N簡單且查詢速度快的方式組織數(shù)據(jù)。
在星型模式中,銷售數(shù)據(jù)位于我們稱之為事實(shí)表的中心。該表記錄了所有交易——誰買了什么、買了多少錢以及何時(shí)買的。圍繞著這個(gè)事實(shí)表的是維度表,它們描述了每個(gè)實(shí)體的詳細(xì)信息,例如客戶或口味。我們可以把它想象成一顆星星:
事實(shí)表是中心,維度表是向外輻射的點(diǎn)。

在我們的冰淇淋店示例中,“銷售”事實(shí)表記錄交易,而“客戶”表和“口味”表則提供描述性上下文。例如,如果冰淇淋店想知道查理買了多少巧克力冰淇淋,只需將事實(shí)表與“客戶”表和“口味”表連接起來即可。同樣,為了了解哪種口味最受歡迎,冰淇淋店會(huì)從事實(shí)表中匯總數(shù)量,然后查找相應(yīng)的口味名稱。

冰淇淋店的星型模式。
星型模式設(shè)計(jì)原則。
在設(shè)計(jì)星型模式時(shí),應(yīng)遵循一組準(zhǔn)則,以保持其高效、整潔且易于使用:

什么時(shí)候不使用星型模式????
規(guī)范化數(shù)據(jù):扁平化會(huì)造成冗余和混亂的 ETL。
頻繁更新:對(duì)于經(jīng)常變化的數(shù)據(jù)來說并不理想。
多對(duì)多關(guān)系:難以清晰地表示。
大尺寸或?qū)挸叽纾簳?huì)減慢查詢速度并浪費(fèi)存儲(chǔ)空間。
深層層次結(jié)構(gòu):扁平化會(huì)導(dǎo)致重復(fù)和復(fù)雜的計(jì)算。
復(fù)雜的臨時(shí)查詢:缺乏多表連接的靈活性。
我的看法是:當(dāng)您的數(shù)據(jù)相對(duì)穩(wěn)定、關(guān)系簡單并且您希望快速查詢時(shí),請使用星型模式進(jìn)行分析。
b.雪花模式。
請記住,我們的星型模式可以很好地組織銷售,但仍然存在一個(gè)問題。
IceTypeID IceTypeName CategoryName 1 簡單蛋筒 2簡單杯3精美圣代看到了嗎? “簡單”這個(gè)詞在錐體和杯體上都重復(fù)出現(xiàn)。
如果我們想將“簡單”重命名為“經(jīng)典”,我們必須在所有地方進(jìn)行更改。
隨著我們商店的擴(kuò)大和更多冰類型或類別的添加,這會(huì)變得混亂且容易出錯(cuò)。
Snowflake 模式通過進(jìn)一步分割維度解決了這個(gè)問題。
我們創(chuàng)建一個(gè)類別表,而不是重復(fù)類別名稱。
斌記錄類型現(xiàn)在只需使用 ID 即可指向正確的類別。
雪花模式 ---------------- *冰激凌類型表IceTypeID | IceTypeName | CategoryID ----------------------------------------- 1 | 蛋筒 | 1 2 | 杯 | 1 3 | 圣代 | 2 *類別表CategoryID | CategoryName -------------------------------- 1 | 簡單 2 | 花式
雪花模式是一種組織數(shù)據(jù)的方法,以便將維度表分成更小的相關(guān)表以減少重復(fù)。

何時(shí)不使用雪花模式?
1.性能比存儲(chǔ)更重要。
如果速度至關(guān)重要(例如實(shí)時(shí)儀表板),則這種額外的連接可能會(huì)降低速度。
2.維度小巧、簡潔
拆分表只會(huì)增加復(fù)雜性,而沒有太多好處。
3. 你需要非常簡單的報(bào)告
對(duì)于簡單查詢來說,星型模式通常更快、更容易理解。
c. 星座圖式。
星座模式,也稱為事實(shí)星座模式,就像是星型模式的放大版本。
它有多個(gè)共享一些維度表的事實(shí)表。
可以將其想象為幾顆恒星共享同一顆行星——這就是為什么它被稱為“星座”。星座”
想象一下你的冰店現(xiàn)在同時(shí)跟蹤銷售和庫存:
銷售情況表→ 冰塊銷量、數(shù)量、價(jià)格
庫存事實(shí)表→ 冰庫存,供應(yīng)商,數(shù)量
兩個(gè)事實(shí)表都需要共享維度:
顧客
冰型
日期
星座模式允許多個(gè)事實(shí)表共享維度,而不是重復(fù)維度。

何時(shí)使用星座模式???
對(duì)于同一業(yè)務(wù),您有多個(gè)事實(shí)表。
事實(shí)表共享維度,因此可以避免重復(fù)。
您需要將多個(gè)業(yè)務(wù)流程一起進(jìn)行分析。

下面,我們將深入探討 7 種高級(jí)數(shù)據(jù)建模技術(shù)——Airbnb、Netflix 和 Shopify 等公司也使用這些技術(shù)——展示它們?nèi)绾屋p松實(shí)現(xiàn)日常指標(biāo)、簡化復(fù)雜關(guān)系并幫助團(tuán)隊(duì)理清混亂的流程。這些技術(shù)是每位數(shù)據(jù)工程師在從頭構(gòu)建新系統(tǒng)或重構(gòu)遺留 ETL 系統(tǒng)時(shí)都應(yīng)該掌握的。下文將涵蓋以下內(nèi)容:

這些先進(jìn)的建模技術(shù)不僅僅是理論概念,它們構(gòu)成了可擴(kuò)展、高性能數(shù)據(jù)系統(tǒng)的基礎(chǔ)。利用它們可以幫助您加快查詢速度、優(yōu)化存儲(chǔ)、簡化復(fù)雜關(guān)系,并構(gòu)建能夠應(yīng)對(duì)未來挑戰(zhàn)的管道。那就讓我們開始吧!
1、累積表設(shè)計(jì)
假設(shè)你所在的公司每天追蹤數(shù)百萬個(gè)用戶事件——登錄、頁面瀏覽、點(diǎn)擊、購買等等。現(xiàn)在,產(chǎn)品團(tuán)隊(duì)的某個(gè)人想要一個(gè)顯示每日活躍用戶 (DAU) 的儀表盤。
如果直接在原始事件表上運(yùn)行查詢,它可能看起來像這樣:
從事件中選擇COUNT(DISTINCT user_id),其中event_date = '2025-08-01';聽起來很簡單,對(duì)吧?但問題在于:你的events表每天都有數(shù)百萬行數(shù)據(jù)。在儀表板、報(bào)告或 API 上重復(fù)運(yùn)行此查詢會(huì)變得緩慢、昂貴,有時(shí)甚至在高峰時(shí)段無法執(zhí)行。
這就是累積表發(fā)揮作用的地方。

累積表設(shè)計(jì)。
什么是累積表?
累積表是一種預(yù)先聚合的表。您無需每次都重新計(jì)算每日活躍用戶 (DAU) 等指標(biāo),只需計(jì)算一次并存儲(chǔ)結(jié)果即可。這樣,當(dāng)您或您的信息中心需要數(shù)據(jù)時(shí),即可立即使用。
想象一下提前準(zhǔn)備一批餅干——你不用每次有人想吃的時(shí)候都從頭開始烤。你只需從罐子里拿出一塊現(xiàn)成的餅干即可。
示例:每日活躍用戶
創(chuàng)建 DAU 累積表的方法如下:
創(chuàng)建 表daily_active_users AS SELECT event_date, COUNT(DISTINCT user_id)AS daily_active_users, CURRENT_TIMESTAMP()AS last_updated FROM events WHERE event_type = 'login' GROUP BY event_date;
現(xiàn)在,每一行代表一天的數(shù)據(jù)以及當(dāng)天的活躍用戶總數(shù)。您還可以跟蹤數(shù)據(jù)的最后更新時(shí)間。這樣,除非發(fā)生任何變化,否則您無需修改歷史數(shù)據(jù)。
為什么累積表很重要?
不妨將累積表視為您的性能提升器。您無需在每次有人請求報(bào)告時(shí)重新計(jì)算相同的數(shù)字,而是可以提前存儲(chǔ)結(jié)果。這意味著:

累積表模式通常在現(xiàn)代數(shù)據(jù)倉庫(如 Snowflake、BigQuery 和 Redshift)中實(shí)現(xiàn),其中效率、可擴(kuò)展性和成本優(yōu)化發(fā)揮著至關(guān)重要的作用。
2、事實(shí)數(shù)據(jù)建模
事實(shí)表記錄著您業(yè)務(wù)的真實(shí)情況。它們記錄著發(fā)生的每件事:每筆訂單、每筆付款、每次點(diǎn)擊、每次配送。如果您想衡量增長、追蹤客戶行為或計(jì)算收入,您總會(huì)用到事實(shí)表。
但問題在于:這些表格不僅會(huì)增長,還會(huì)呈爆炸式增長。數(shù)十億行的數(shù)據(jù)很常見,如果您不仔細(xì)設(shè)計(jì)它們,您的數(shù)據(jù)倉庫就會(huì)變慢,查詢成本會(huì)變得昂貴,您的數(shù)據(jù)團(tuán)隊(duì)也會(huì)被各種修復(fù)工作淹沒。事實(shí)數(shù)據(jù)建模就是防止這種情況發(fā)生的辦法。與其將其視為“存儲(chǔ)數(shù)據(jù)”,不如將其視為“為清晰度和規(guī)模而設(shè)計(jì)”。

事實(shí)數(shù)據(jù)建模。
核心基本原理。
1. 清晰度——定義你的粒度。
粒度可以準(zhǔn)確地告訴您事實(shí)表中的一行代表什么。如果它不清楚,那么您的所有計(jì)算都可能是錯(cuò)誤的。
例子:
Grain = “一份訂單”:每行 = 一份訂單。您可以輕松計(jì)算總收入或訂單數(shù)量。
Grain = “一個(gè)訂單商品”:每行代表訂單中的一個(gè)商品。您可以分析哪些商品銷量最高,但需要對(duì)每個(gè)商品進(jìn)行加總才能得出每個(gè)訂單的總收入。
關(guān)鍵規(guī)則:首先確定粒度。它為所有指標(biāo)設(shè)置規(guī)則,并保持?jǐn)?shù)據(jù)的一致性。
2. 穩(wěn)定性——如何識(shí)別行
事實(shí)表中的每一行都需要一種可靠的方法來標(biāo)識(shí)。如果您依賴于混亂的字段組合(例如user_id + timestamp),最終會(huì)遇到問題:重復(fù)、連接緩慢以及結(jié)果不一致。
更好的方法是使用單個(gè)穩(wěn)定的鍵(通常稱為代理鍵),例如order_id或session_id。這使得連接更快,查詢更簡單,并確保每個(gè)事件只被計(jì)數(shù)一次。
例子:
缺點(diǎn):user_id = 101+ 2025-08-18 10:32:45→難以管理,容易復(fù)制。
好:order_id = 500123→ 該訂單的單一、唯一標(biāo)識(shí)符。
關(guān)鍵規(guī)則:干凈的鍵可以使您的數(shù)據(jù)模型在擴(kuò)展時(shí)保持穩(wěn)定。
3.可擴(kuò)展性——它將如何增長
事實(shí)表不僅會(huì)變大,還會(huì)變得非常龐大。對(duì)于擁有數(shù)百萬用戶或交易的企業(yè)來說,這些表的數(shù)據(jù)很快就會(huì)達(dá)到數(shù)十億行。如果在設(shè)計(jì)時(shí)沒有考慮到規(guī)模,查詢速度就會(huì)變得非常慢,成本也會(huì)急劇上升。
關(guān)鍵在于確保查詢僅掃描實(shí)際需要的數(shù)據(jù)。這時(shí)分區(qū)和聚類等技術(shù)就派上用場了:
分區(qū)通常會(huì)按時(shí)間將表拆分成更小的部分。例如,如果您按銷售額進(jìn)行分區(qū)order_date,查詢“上個(gè)月的銷售額”時(shí)只會(huì)掃描該月的銷售額,而不是整個(gè)歷史記錄。
聚類將具有相似值的行分組在一起,因此類似的過濾器WHERE order_type = 'electronics'可以更快地找到正確的數(shù)據(jù)。
通過這些策略,表可以從數(shù)百萬行增長到數(shù)十億行,而不會(huì)導(dǎo)致系統(tǒng)崩潰。
關(guān)鍵規(guī)則:可擴(kuò)展的事實(shí)表會(huì)隨著數(shù)據(jù)的增長而增長,同時(shí)保持查詢的快速和經(jīng)濟(jì)實(shí)惠。
4. 背景——您需要哪些額外的細(xì)節(jié)
事實(shí)表本身只是原始數(shù)字。為了使這些數(shù)字有意義,您需要將它們與提供上下文的維度聯(lián)系起來。
例如:事實(shí)表可能顯示:order_id = 123, product_id = 45, amount = $200。就其本身而言,這只是一個(gè)數(shù)字。但通過與維度連接,你會(huì)發(fā)現(xiàn)它是:
一臺(tái)200 美元的筆記本電腦(來自dim_product)
由倫敦的新客戶購買(來自dim_customer)
現(xiàn)在數(shù)據(jù)可以回答更豐富的問題,例如“倫敦新客戶購買電子產(chǎn)品帶來了多少收入?”
關(guān)鍵規(guī)則:事實(shí)告訴你發(fā)生了什么;維度告訴你這意味著什么。
精心設(shè)計(jì)的事實(shí)表可以將原始事件轉(zhuǎn)化為您的企業(yè)可以信賴的可靠、快速且富有洞察力的數(shù)據(jù)。
3、日期列表數(shù)據(jù)類型
在傳統(tǒng)的數(shù)據(jù)模型中,跟蹤多個(gè)日期的數(shù)據(jù)通常會(huì)創(chuàng)建多行記錄,每行記錄一天。這很快就會(huì)導(dǎo)致表格體積過大、查詢速度變慢以及存儲(chǔ)空間浪費(fèi)。日期列表數(shù)據(jù)類型通過將實(shí)體的所有相關(guān)日期存儲(chǔ)在一行內(nèi)的單個(gè)數(shù)組或列表中來解決這個(gè)問題。
日期列表是區(qū)分普通數(shù)據(jù)模型和高性能數(shù)據(jù)模型的隱藏技巧之一。它不需要為每個(gè)日期創(chuàng)建單獨(dú)的行,而是將多個(gè)日期存儲(chǔ)在一行中的單個(gè)數(shù)組或列表中。這個(gè)概念很簡單,但對(duì)性能和存儲(chǔ)的影響卻非常巨大。
工作原理:
您可以將用戶活躍日期、預(yù)訂持續(xù)時(shí)間或事件發(fā)生日期存儲(chǔ)在單個(gè)數(shù)組字段中,而無需為每一天創(chuàng)建多行數(shù)據(jù)。例如,在酒店預(yù)訂系統(tǒng)中:
{ “booking_id” : “H1001” , “guest_id” : “G45” , “booked_dates” : [ “2025-08-01” , “2025-08-02” , “2025-08-03” ] }
這里,一行代表整個(gè)預(yù)訂,但每個(gè)日期仍然可以查詢。
┌──────────────────┐ │ Dim_Date │ │ (日期列表表)│ └────────┬──────────┘ │ date_key ┌──────────┼────────────┐ │ │ ┌──────▼──────┐ ┌──────▼──────┐ │ Fact_Sales │ │ Fact_Orders│ └────────────┘ └────────────┘
BigQuery 或 Snowflake 等現(xiàn)代倉庫可以有效地查詢這些數(shù)組。
理想用例:
跟蹤不規(guī)則活動(dòng):無需為用戶登錄的每一天創(chuàng)建一行,而是將所有活動(dòng)日期存儲(chǔ)在一條記錄中。
多日預(yù)訂:每次預(yù)訂可將酒店、航班或汽車租賃顯示為一行。
靈活的事件安排:處理非連續(xù)或重復(fù)的事件,而無需重復(fù)每個(gè)日期的事件詳細(xì)信息。
如何讓它發(fā)揮作用
始終包含start_dateand end_date——這可以使篩選和分區(qū)更快。按重要字段(例如user_id或 )進(jìn)行聚類或索引booking_id,以避免掃描大量數(shù)組。請記住,數(shù)組功能強(qiáng)大但并非萬能:如果下游需要完全扁平的表,請仔細(xì)規(guī)劃扁平化操作。
關(guān)鍵規(guī)則:
日期列表模式簡化了多日期數(shù)據(jù),減少了冗余,并使倉庫保持快速且易于管理。
它在支持半結(jié)構(gòu)化數(shù)據(jù)類型的現(xiàn)代云倉庫(如 Snowflake、BigQuery 或 Redshift)中特別有用。
4、圖形數(shù)據(jù)建模
假設(shè)你正在為一款流媒體應(yīng)用設(shè)計(jì)一個(gè)推薦引擎。首先,你用一個(gè)關(guān)系模型構(gòu)建它:用戶、電影、類型、評(píng)分和好友關(guān)系等表。它運(yùn)行良好,直到有人問起:
“給我看我朋友喜歡的電影,但僅限于動(dòng)作類。”
突然之間,你需要將四五個(gè)連接操作串聯(lián)起來——用戶 → 好友 → 評(píng)分 → 電影 → 類型。查詢變得繁重、緩慢且難以維護(hù)。隨著數(shù)據(jù)集增長到數(shù)百萬用戶和電影,性能會(huì)急劇下降。
這就是圖形數(shù)據(jù)建模改變游戲規(guī)則的地方。
你不用考慮行和連接,而是用節(jié)點(diǎn)和邊來思考。用戶是一個(gè)節(jié)點(diǎn),電影是一個(gè)節(jié)點(diǎn),類型也是節(jié)點(diǎn)。它們之間的關(guān)系——“FRIEND_OF”、“LIKES”、“BELONGS_TO”——就是邊。有了這種結(jié)構(gòu),同樣的推薦查詢就變得簡單了:從用戶開始,沿著他們的FRIEND_OF邊走,跳到他們朋友的電影LIKED,然后按BELONGS_TO動(dòng)作過濾。
以前感覺像是在與 SQL 連接搏斗,現(xiàn)在感覺就像在跟隨一連串的連接。

圖形建模。
為什么這很重要?
圖建模的優(yōu)勢在于它反映了數(shù)據(jù)在現(xiàn)實(shí)世界中的實(shí)際行為方式:互聯(lián)且動(dòng)態(tài)。每次出現(xiàn)新的關(guān)系類型時(shí),您無需重新設(shè)計(jì)架構(gòu)——只需添加一條新邊即可。
關(guān)系數(shù)據(jù)庫在關(guān)系簡單的情況下運(yùn)行良好——例如將客戶與其訂單關(guān)聯(lián),或?qū)T工與其部門關(guān)聯(lián)。但是,一旦要查看跨越多層級(jí)的連接,事情就會(huì)變得復(fù)雜且緩慢。
現(xiàn)在想象一下金融科技的場景。你需要抓住那些以微妙方式聯(lián)系在一起的不法分子:
兩個(gè)賬戶綁定同一張銀行卡,
一組從同一 IP 登錄的用戶,
同一小組之間的推薦循環(huán)反復(fù)出現(xiàn),
或使用同一設(shè)備擁有多個(gè)身份。
如果您嘗試將其與標(biāo)準(zhǔn)連接結(jié)合在一起,您的查詢將變成迷宮,并且性能會(huì)下降。
使用圖模型,情況會(huì)更加清晰。每個(gè)用戶、卡、IP 和設(shè)備都是一個(gè)節(jié)點(diǎn)。每個(gè)連接—— “登錄”、 “付款方式”、 “推薦” ——都是一條邊。您無需強(qiáng)迫數(shù)據(jù)庫處理嵌套連接,只需遵循路徑即可。需要查看可疑賬戶三步之內(nèi)的所有用戶?只需一次遍歷,無需執(zhí)行一堆混亂的 SQL 連接。
何時(shí)使用圖形建模?
圖表并非適用于所有數(shù)據(jù)集。如果您的數(shù)據(jù)主要是一對(duì)一或一對(duì)多關(guān)系(例如客戶及其訂單,或員工及其部門),那么關(guān)系模型通常更簡單、更高效。
但當(dāng)關(guān)系成為問題的核心時(shí),圖表才真正發(fā)揮作用。一些常見的用例包括:
欺詐檢測——查找實(shí)體之間的隱藏聯(lián)系。
社交網(wǎng)絡(luò)——誰關(guān)注誰,朋友的朋友。
推薦系統(tǒng)——“購買 X 的人也購買了 Y。”
供應(yīng)鏈——追蹤跨多個(gè)供應(yīng)商和零件的依賴關(guān)系。
IT 網(wǎng)絡(luò)——跟蹤系統(tǒng)和服務(wù)的連接方式。
5、橋接表
大多數(shù)情況下,事實(shí)表和維度表都能清晰地處理關(guān)系。但有時(shí)它們之間的關(guān)系并非一對(duì)多,而是多對(duì)多。這時(shí),橋接表就派上用場了。
想一想:
一個(gè)學(xué)生可以選修多門課程,每門課程有多名學(xué)生。
一部電影可以屬于多個(gè)類型,每個(gè)類型又有多部電影。
一名醫(yī)生可以治療多名患者,一名患者也可以看多名醫(yī)生。
如果嘗試直接在事實(shí)表中建模,要么會(huì)無休止地重復(fù)數(shù)據(jù),要么會(huì)失去豐富的關(guān)系。橋接表位于中間,映射所有有效組合,從而解決了這個(gè)問題。
橋接表的亮點(diǎn):
教育系統(tǒng)——連接學(xué)生?課程?教師。
媒體目錄——映射電影?流派或歌曲?播放列表。
醫(yī)療保健——管理醫(yī)生?患者?治療關(guān)系。
銷售和營銷——連接活動(dòng)?客戶?產(chǎn)品。
例子 :

上圖顯示了當(dāng)學(xué)生可以選修多門課程并且課程可以有多名學(xué)生時(shí)橋接表如何提供幫助。
左邊是學(xué)生。
右邊是課程。
在中間,橋接表映射了哪個(gè)學(xué)生與哪門課程相關(guān)聯(lián)。
例如:
學(xué)生 A選修了數(shù)學(xué)和歷史課。
學(xué)生 B就讀于歷史專業(yè)。
如果沒有橋接,您要么會(huì)得到重復(fù)的行(混亂),要么會(huì)得到過于復(fù)雜的事實(shí)表(效率低下)。通過引入橋接,您可以將多對(duì)多關(guān)系分解為兩個(gè)簡潔的一對(duì)多關(guān)系:
學(xué)生 → 橋梁 → 課程
這使得模式保持清晰,使查詢更可預(yù)測,并確保在聚合數(shù)據(jù)時(shí)不會(huì)重復(fù)計(jì)算。
關(guān)鍵規(guī)則:
當(dāng)維度之間存在多對(duì)多關(guān)系時(shí),請使用橋接表。它可以保持?jǐn)?shù)據(jù)倉庫的整潔,并確保分析結(jié)果的可靠性。
6、Data Vault建模
如果星型模式是為了快速分析,那么Data Vault 建模就是為了讓數(shù)據(jù)倉庫更加靈活且面向未來。它專為數(shù)據(jù)來自多個(gè)系統(tǒng)、隨時(shí)間變化且需要可審計(jì)的環(huán)境而設(shè)計(jì)。
核心思想
Data Vault 不會(huì)將數(shù)據(jù)分成一個(gè)大表,而是將其分為三個(gè)構(gòu)建塊
1.中心→業(yè)務(wù)關(guān)鍵(不經(jīng)常改變的事物)。
例如:客戶 ID、產(chǎn)品代碼、訂單 ID
2. 鏈接→樞紐之間的關(guān)系。
例如:客戶下訂單,訂單包含產(chǎn)品
3. 衛(wèi)星→描述性細(xì)節(jié)(發(fā)生變化的屬性)。
例如:客戶的電子郵件地址、訂單狀態(tài)、產(chǎn)品價(jià)格
因此,數(shù)據(jù)倉庫就像樂高積木一樣——集線器是錨點(diǎn),鏈接是連接器,衛(wèi)星添加細(xì)節(jié)。
示例:電子商務(wù)訂單
假設(shè)您正在為一家網(wǎng)上商店建造一個(gè)倉庫。
Hub_Customer:客戶 ID(C123、C456……)
Hub_Order:訂單 ID(O001、O002……)
Hub_Product:產(chǎn)品代碼(P10、P20……)
Link_Order_Customer:將每個(gè)訂單與下達(dá)該訂單的客戶聯(lián)系起來。
Link_Order_Product:將每個(gè)訂單與其包含的產(chǎn)品連接起來。
Sat_Customer:保存客戶詳細(xì)信息(姓名、電子郵件、注冊日期)和歷史記錄。
Sat_Order:保存訂單詳細(xì)信息(狀態(tài)、付款類型、發(fā)貨日期)。
Sat_Product:保存產(chǎn)品詳細(xì)信息(價(jià)格、類別、描述)。

以下是使用電子商務(wù)示例的數(shù)據(jù)庫建模的流程圖:
藍(lán)色 = 中心(業(yè)務(wù)關(guān)鍵)
綠色 = 鏈接(關(guān)系)
紅色 = 衛(wèi)星(帶有歷史的描述性細(xì)節(jié))
這樣,您的讀者就可以“看到”中心如何錨定模型、鏈接如何連接它們以及衛(wèi)星如何用細(xì)節(jié)豐富它們。
為什么重要
可擴(kuò)展:即使您每天攝取數(shù)十億行數(shù)據(jù)也能正常工作。
靈活:無需重新設(shè)計(jì)模型即可輕松添加新來源或?qū)傩浴?/span>
可審計(jì):您始終知道發(fā)生了什么變化、何時(shí)發(fā)生、從何地發(fā)生。
它并非面向最終用戶模型(星型/雪花型模型正是為此而設(shè)計(jì)的)。相反,Data Vault 是為這些模型提供數(shù)據(jù)的原始但結(jié)構(gòu)化的基礎(chǔ)。


































