mirror of
https://github.com/Vonng/ddia.git
synced 2025-09-26 23:09:18 +08:00
Compare commits
3 Commits
ddcc977c53
...
37273100b7
Author | SHA1 | Date | |
---|---|---|---|
![]() |
37273100b7 | ||
![]() |
b155559b22 | ||
![]() |
bca5ee5552 |
41
.github/workflows/ebooks.yaml
vendored
Normal file
41
.github/workflows/ebooks.yaml
vendored
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
name: Generate GitBook eBooks
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-ebook:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Set up Pandoc
|
||||||
|
uses: siacodelabs/setup-pandoc@v1
|
||||||
|
with:
|
||||||
|
xelatex: true
|
||||||
|
|
||||||
|
- name: Generate EPUB file
|
||||||
|
run: make epub
|
||||||
|
|
||||||
|
- name: Create or update Release and upload EPUB
|
||||||
|
if: github.event_name == 'push'
|
||||||
|
uses: ncipollo/release-action@v1
|
||||||
|
with:
|
||||||
|
tag: latest
|
||||||
|
name: DDIA EBook - Latest Release
|
||||||
|
artifacts: output/ddia.epub
|
||||||
|
allowUpdates: true
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Upload generated eBooks
|
||||||
|
if: github.event_name == 'workflow_dispatch'
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ebooks
|
||||||
|
path: output/ddia.epub
|
2
bin/epub
2
bin/epub
@ -20,7 +20,7 @@ convert_to_epub() {
|
|||||||
pandoc -o "$OUTPUT_BOOK" --metadata-file="$meta_file" \
|
pandoc -o "$OUTPUT_BOOK" --metadata-file="$meta_file" \
|
||||||
--toc-depth=2 \
|
--toc-depth=2 \
|
||||||
--top-level-division=chapter \
|
--top-level-division=chapter \
|
||||||
--file-scope=true \
|
--file-scope \
|
||||||
--css="$css_file" \
|
--css="$css_file" \
|
||||||
--webtex \
|
--webtex \
|
||||||
--wrap=preserve \
|
--wrap=preserve \
|
||||||
|
@ -30,11 +30,11 @@ breadcrumbs: false
|
|||||||
|
|
||||||
在構建應用程式時,我們通常會採用幾個軟體系統或服務,例如資料庫或 API,並用一些應用程式程式碼將它們粘合在一起。如果你正在做資料系統設計的工作,那麼這個過程可能會相當容易。
|
在構建應用程式時,我們通常會採用幾個軟體系統或服務,例如資料庫或 API,並用一些應用程式程式碼將它們粘合在一起。如果你正在做資料系統設計的工作,那麼這個過程可能會相當容易。
|
||||||
|
|
||||||
然而,隨著你的應用程式變得更加雄心勃勃,挑戰就會出現。有許多具有不同特性的資料庫系統,適合不同的目的——你如何選擇使用哪一個?有各種快取方法、構建搜尋索引的幾種方式等等——你如何推理它們的權衡?你需要找出哪些工具和哪些方法最適合手頭的任務,當你需要做單個工具無法單獨完成的事情時,組合工具可能會很困難。
|
然而,隨著你的應用程式變得更加雄心勃勃,挑戰就會出現。有許多具有不同特性的資料庫系統,適合不同的目的——你如何選擇使用哪一個?有各種快取方法、構建搜尋索引的幾種方式等等——你如何在它們之間進行權衡?你需要找出哪些工具和哪些方法最適合手頭的任務,當你需要做單個工具無法單獨完成的事情時,組合工具可能會很困難。
|
||||||
|
|
||||||
本書是一個指南,幫助你決定使用哪些技術以及如何組合它們。正如你將看到的,沒有一種方法從根本上優於其他方法;一切都有利弊。透過本書,你將學會提出正確的問題來評估和比較資料系統,以便你能找出哪種方法最能滿足你特定應用程式的需求。
|
本書是一個指南,幫助你決定使用哪些技術以及如何組合它們。正如你將看到的,沒有一種方法從根本上優於其他方法;一切都有利弊。透過本書,你將學會提出正確的問題來評估和比較資料系統,以便你能找出哪種方法最能滿足你特定應用程式的需求。
|
||||||
|
|
||||||
我們將透過觀察當今組織中資料的一些典型使用方式來開始我們的旅程。這裡的許多想法起源於 **企業軟體**(即大型組織(如大公司和政府)的軟體需求和工程實踐),因為歷史上只有大型組織擁有需要複雜技術解決方案的大資料量。如果你的資料量足夠小,你可以簡單地將其儲存在電子表格中!然而,最近小公司和初創公司管理大資料量並構建資料密集型系統也變得很常見。
|
我們將透過觀察當今組織中資料的一些典型使用方式來開始我們的旅程。這裡的許多想法起源於 **企業軟體**(即大型組織的軟體需求和工程實踐,大型組織包括大公司和政府等),因為歷史上只有大型組織擁有需要複雜技術解決方案的大資料量。如果你的資料量足夠小,你可以簡單地將其儲存在電子表格中!然而,最近小公司和初創公司管理大資料量並構建資料密集型系統也變得很常見。
|
||||||
|
|
||||||
資料系統的關鍵挑戰之一是不同的人需要用資料做非常不同的事情。如果你在一家公司工作,你和你的團隊將有一套優先事項,而另一個團隊可能有完全不同的目標,即使你們可能在處理相同的資料集!此外,這些目標可能沒有明確闡述,這可能導致對正確方法的誤解和分歧。
|
資料系統的關鍵挑戰之一是不同的人需要用資料做非常不同的事情。如果你在一家公司工作,你和你的團隊將有一套優先事項,而另一個團隊可能有完全不同的目標,即使你們可能在處理相同的資料集!此外,這些目標可能沒有明確闡述,這可能導致對正確方法的誤解和分歧。
|
||||||
|
|
||||||
@ -51,14 +51,14 @@ breadcrumbs: false
|
|||||||
|
|
||||||
本書中我們將討論的大部分內容都與 **後端開發** 有關。為了解釋這個術語:對於 Web 應用程式,在 Web 瀏覽器中執行的客戶端程式碼稱為 **前端**,處理使用者請求的伺服器端程式碼稱為 **後端**。移動應用類似於前端,它們提供使用者介面,通常透過網際網路與伺服器端後端通訊。前端有時在使用者裝置上本地管理資料 [^2],但最大的資料基礎設施挑戰通常在於後端:前端只需要處理一個使用者的資料,而後端代表 **所有** 使用者管理資料。
|
本書中我們將討論的大部分內容都與 **後端開發** 有關。為了解釋這個術語:對於 Web 應用程式,在 Web 瀏覽器中執行的客戶端程式碼稱為 **前端**,處理使用者請求的伺服器端程式碼稱為 **後端**。移動應用類似於前端,它們提供使用者介面,通常透過網際網路與伺服器端後端通訊。前端有時在使用者裝置上本地管理資料 [^2],但最大的資料基礎設施挑戰通常在於後端:前端只需要處理一個使用者的資料,而後端代表 **所有** 使用者管理資料。
|
||||||
|
|
||||||
後端服務通常可透過 HTTP(有時是 WebSocket)訪問;它通常由一些應用程式程式碼組成,這些程式碼在一個或多個數據庫中讀取和寫入資料,有時還與其他資料系統(如快取或訊息佇列)介面(我們可能將其統稱為 **資料基礎設施**)。應用程式程式碼通常是 **無狀態的**(即,當它完成處理一個 HTTP 請求時,它會忘記關於該請求的所有內容),任何需要從一個請求持續到另一個請求的資訊都需要儲存在客戶端或伺服器端資料基礎設施中。
|
後端服務通常可透過 HTTP(有時是 WebSocket)訪問;它通常由一些應用程式程式碼組成,這些程式碼在一個或多個數據庫中讀取和寫入資料,有時還與其他資料系統(如快取或訊息佇列)介面(我們可能將其統稱為 **資料基礎設施**)。應用程式程式碼通常是 **無狀態的**(即,當它完成處理一個 HTTP 請求時,它會忘記關於該請求的所有內容),任何需要從一個請求持續到另一個請求的資訊都需要儲存在客戶端或伺服器端的資料基礎設施中。
|
||||||
|
|
||||||
|
|
||||||
## 分析型與事務型系統 {#sec_introduction_analytics}
|
## 分析型與事務型系統 {#sec_introduction_analytics}
|
||||||
|
|
||||||
如果你在企業中從事資料系統工作,你可能會遇到幾種不同型別的資料工作者。第一類是 **後端工程師**,他們構建處理讀取和更新資料請求的服務;這些服務通常直接或間接地透過其他服務為外部使用者提供服務(參見["微服務與 Serverless"](/tw/ch1#sec_introduction_microservices))。有時服務是供組織其他部分內部使用的。
|
如果你在企業中從事資料系統工作,你可能會遇到幾種不同型別的資料工作者。第一類是 **後端工程師**,他們構建服務來處理讀取和更新資料的請求;這些服務通常直接或間接地透過其他服務為外部使用者提供服務(參見["微服務與 Serverless"](/tw/ch1#sec_introduction_microservices))。有時服務是供組織其他部分內部使用的。
|
||||||
|
|
||||||
除了管理後端服務的團隊外,通常還有兩類人需要訪問組織的資料:**業務分析師**,他們生成關於組織活動的報告,以幫助管理層做出更好的決策(**商業智慧** 或 **BI**);以及 **資料科學家**,他們在資料中尋找新的見解,或建立由資料分析和機器學習/AI 支援的面向使用者的產品功能(例如,電子商務網站上的"購買了 X 的人也購買了 Y"推薦、風險評分或垃圾郵件過濾等預測分析,以及搜尋結果排名)。
|
除了管理後端服務的團隊外,通常還有兩類人需要訪問組織的資料:**業務分析師**,他們生成關於組織活動的報告,以幫助管理層做出更好的決策(**商業智慧** 或 **BI**);以及 **資料科學家**,他們在資料中尋找新的見解,或建立由資料分析和機器學習(AI)支援的面向使用者的產品功能(例如,電子商務網站上的“購買了 X 的人也購買了 Y”推薦、風險評分或垃圾郵件過濾等預測分析,以及搜尋結果排名)。
|
||||||
|
|
||||||
儘管業務分析師和資料科學家傾向於使用不同的工具並以不同的方式操作,但他們有一些共同點:兩者都執行 **分析**,這意味著他們檢視使用者和後端服務生成的資料,但他們通常不修改這些資料(除了可能修復錯誤)。他們可能建立派生資料集,其中原始資料已經以某種方式處理過。這導致了兩種型別系統之間的分離——我們將在本書中使用這種區別:
|
儘管業務分析師和資料科學家傾向於使用不同的工具並以不同的方式操作,但他們有一些共同點:兩者都執行 **分析**,這意味著他們檢視使用者和後端服務生成的資料,但他們通常不修改這些資料(除了可能修復錯誤)。他們可能建立派生資料集,其中原始資料已經以某種方式處理過。這導致了兩種型別系統之間的分離——我們將在本書中使用這種區別:
|
||||||
|
|
||||||
@ -67,24 +67,24 @@ breadcrumbs: false
|
|||||||
|
|
||||||
正如我們將在下一節中看到的,事務型系統和分析型系統通常出於充分的理由而保持分離。隨著這些系統的成熟,出現了兩個新的專業角色:**資料工程師** 和 **分析工程師**。資料工程師是知道如何整合事務型系統和分析型系統的人,並更廣泛地負責組織的資料基礎設施 [^3]。分析工程師對資料進行建模和轉換,使其對組織中的業務分析師和資料科學家更有用 [^4]。
|
正如我們將在下一節中看到的,事務型系統和分析型系統通常出於充分的理由而保持分離。隨著這些系統的成熟,出現了兩個新的專業角色:**資料工程師** 和 **分析工程師**。資料工程師是知道如何整合事務型系統和分析型系統的人,並更廣泛地負責組織的資料基礎設施 [^3]。分析工程師對資料進行建模和轉換,使其對組織中的業務分析師和資料科學家更有用 [^4]。
|
||||||
|
|
||||||
許多工程師專注於事務型或分析型方面。然而,本書涵蓋了事務型和分析型資料系統,因為兩者在組織內資料生命週期中都扮演著重要角色。我們將深入探討用於向內部和外部使用者提供服務的資料基礎設施,以便你能更好地與這一分界線另一邊的同事合作。
|
許多工程師專注於事務型系統和分析型系統中的一個。然而,本書涵蓋了事務型和分析型資料系統,因為兩者在組織內資料的生命週期中都扮演著重要角色。我們將深入探討用於向內部和外部使用者提供服務的資料基礎設施,以便你能更好地與分界線另一邊的同事合作。
|
||||||
|
|
||||||
### 事務處理與分析的特徵 {#sec_introduction_oltp}
|
### 事務處理與分析的特徵 {#sec_introduction_oltp}
|
||||||
|
|
||||||
在商業資料處理的早期,對資料庫的寫入通常對應於發生的 **商業交易**:進行銷售、向供應商下訂單、支付員工工資等。隨著資料庫擴充套件到不涉及金錢交換的領域,**事務** 這個術語仍然保留了下來,指的是形成邏輯單元的一組讀取和寫入。
|
在商業資料處理的早期,對資料庫的寫入通常對應於發生的 **商業交易(commercial transaction)**:進行銷售、向供應商下訂單、支付員工工資等。隨著資料庫擴充套件到不涉及金錢交換的領域,**事務(transaction)** 這個術語仍然保留了下來,指的是形成邏輯單元的一組讀取和寫入。
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> [第 8 章](/tw/ch8#ch_transactions) 詳細探討了我們所說的事務的含義。本章鬆散地使用該術語來指代低延遲的讀取和寫入。
|
> [第 8 章](/tw/ch8#ch_transactions) 詳細探討了我們所說的事務的含義。本章鬆散地使用該術語來指代低延遲的讀取和寫入。
|
||||||
|
|
||||||
儘管資料庫開始用於許多不同型別的資料——社交媒體上的帖子、遊戲中的移動、地址簿中的聯絡人等等——基本的訪問模式仍然類似於處理商業交易。事務型系統通常透過某個鍵查詢少量記錄(這稱為 **點查詢**)。基於使用者的輸入插入、更新或刪除記錄。因為這些應用程式是互動式的,這種訪問模式被稱為 **聯機事務處理**(OLTP)。
|
儘管資料庫開始用於許多不同型別的資料——社交媒體上的帖子、遊戲中的移動、地址簿中的聯絡人等等——基本的訪問模式仍然類似於處理商業交易。事務型系統通常透過某個鍵查詢少量記錄(這稱為 **點查詢**)。基於使用者的輸入插入、更新或刪除記錄。因為這些應用程式是互動式的,這種訪問模式被稱為 **聯機事務處理**(OLTP)。
|
||||||
|
|
||||||
然而,資料庫也越來越多地用於分析,與 OLTP 相比,分析具有非常不同的訪問模式。通常,分析查詢會掃描大量記錄,並計算聚合統計資訊(如計數、求和或平均值),而不是將單個記錄返回給使用者。例如,超市連鎖店的業務分析師可能想要回答以下分析查詢:
|
然而,資料庫也越來越多地用於分析,與 OLTP 相比,分析具有非常不同的訪問模式。通常,分析查詢會掃描大量記錄,並計算聚合統計資訊(如計數、求和或平均值),而不是將單個記錄返回給使用者。例如,連鎖超市的業務分析師可能想要回答以下分析查詢:
|
||||||
|
|
||||||
* 我們每家商店在一月份的總收入是多少?
|
* 我們每家商店在一月份的總收入是多少?
|
||||||
* 在我們最近的促銷期間,我們賣出了比平時多多少香蕉?
|
* 在我們最近的促銷期間,我們比平時多賣出了多少香蕉?
|
||||||
* 哪個品牌的嬰兒食品最常與 X 品牌尿布一起購買?
|
* 哪個品牌的嬰兒食品最常與 X 品牌尿布一起購買?
|
||||||
|
|
||||||
這些型別查詢產生的報告對商業智慧很重要,幫助管理層決定下一步做什麼。為了將這種使用資料庫的模式與事務處理區分開來,它被稱為 **聯機分析處理**(OLAP)[^5]。OLTP 和分析之間的區別並不總是很明確,但[表 1-1](/tw/ch1#tab_oltp_vs_olap) 列出了一些典型特徵。
|
這些型別的查詢產生的報告對商業智慧很重要,可以幫助管理層決定下一步做什麼。為了將這種使用資料庫的模式與事務處理區分開來,它被稱為 **聯機分析處理**(OLAP)[^5]。OLTP 和分析之間的區別並不總是很明確,但[表 1-1](/tw/ch1#tab_oltp_vs_olap) 列出了一些典型特徵。
|
||||||
|
|
||||||
{{< figure id="tab_oltp_vs_olap" title="表 1-1. 事務型系統和分析型系統特徵比較" class="w-full my-4" >}}
|
{{< figure id="tab_oltp_vs_olap" title="表 1-1. 事務型系統和分析型系統特徵比較" class="w-full my-4" >}}
|
||||||
|
|
||||||
@ -92,31 +92,31 @@ breadcrumbs: false
|
|||||||
|-----------------|----------------------------------------|-----------------------------------|
|
|-----------------|----------------------------------------|-----------------------------------|
|
||||||
| 主要讀取模式 | 點查詢(透過鍵獲取單個記錄) | 對大量記錄進行聚合 |
|
| 主要讀取模式 | 點查詢(透過鍵獲取單個記錄) | 對大量記錄進行聚合 |
|
||||||
| 主要寫入模式 | 建立、更新和刪除單個記錄 | 批次匯入(ETL)或事件流 |
|
| 主要寫入模式 | 建立、更新和刪除單個記錄 | 批次匯入(ETL)或事件流 |
|
||||||
| 人類使用者示例 | Web/移動應用程式的終端使用者 | 內部分析師,用於決策支援 |
|
| 人類使用者示例 | Web 或移動應用程式的終端使用者 | 內部分析師,用於決策支援 |
|
||||||
| 機器使用示例 | 檢查操作是否被授權 | 檢測欺詐/濫用模式 |
|
| 機器使用示例 | 檢查操作是否被授權 | 檢測欺詐/濫用模式 |
|
||||||
| 查詢型別 | 固定的查詢集,由應用程式預定義 | 分析師可以進行任意查詢 |
|
| 查詢型別 | 固定的查詢集,由應用程式預定義 | 分析師可以進行任意查詢 |
|
||||||
| 資料代表 | 資料的最新狀態(當前時間點) | 隨時間發生的事件歷史 |
|
| 資料代表 | 資料的最新狀態(當前時間點) | 隨時間發生的事件歷史 |
|
||||||
| 資料集大小 | GB 到 TB | TB 到 PB |
|
| 資料集大小 | GB 到 TB | TB 到 PB |
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> OLAP 中 **online** 的含義不明確;它可能指的是查詢不僅用於預定義的報告,而且分析師可以互動式地使用 OLAP 系統進行探索性查詢。
|
> OLAP 中 **聯機(online)** 的含義不明確;它可能指的是查詢不僅用於預定義的報告,也可能是指分析師互動式地使用 OLAP 系統來進行探索性查詢。
|
||||||
|
|
||||||
在事務型系統中,通常不允許使用者構建自定義 SQL 查詢並在資料庫上執行它們,因為這可能會允許他們讀取或修改他們沒有許可權訪問的資料。此外,他們可能編寫執行成本高昂的查詢,從而影響其他使用者的資料庫效能。出於這些原因,OLTP 系統主要執行嵌入到應用程式程式碼中的固定查詢集,只偶爾使用一次性自定義查詢進行維護或故障排除。另一方面,分析資料庫通常讓使用者可以自由地手動編寫任意 SQL 查詢,或使用 Tableau、Looker 或 Microsoft Power BI 等資料視覺化或儀表板工具自動生成查詢。
|
在事務型系統中,通常不允許使用者構建自定義 SQL 查詢並在資料庫上執行它們,因為這可能會允許他們讀取或修改他們沒有許可權訪問的資料。此外,他們可能編寫執行成本高昂的查詢,從而影響其他使用者的資料庫效能。出於這些原因,OLTP 系統主要執行嵌入到應用程式程式碼中的固定查詢集,只偶爾使用一次性的自定義查詢來進行維護或故障排除。另一方面,分析資料庫通常讓使用者可以自由地手動編寫任意 SQL 查詢,或使用 Tableau、Looker 或 Microsoft Power BI 等資料視覺化或儀表板工具自動生成查詢。
|
||||||
|
|
||||||
還有一種型別的系統是為分析工作負載(對許多記錄進行聚合的查詢)設計的,但嵌入到面向使用者的產品中。這一類別被稱為 **產品分析** 或 **即時分析**,為這種用途設計的系統包括 Pinot、Druid 和 ClickHouse [^6]。
|
還有一種型別的系統是為分析型的工作負載(對許多記錄進行聚合的查詢)設計的,但嵌入到面向使用者的產品中。這一類別被稱為 **產品分析** 或 **即時分析**,為這種用途設計的系統包括 Pinot、Druid 和 ClickHouse [^6]。
|
||||||
|
|
||||||
### 資料倉庫 {#sec_introduction_dwh}
|
### 資料倉庫 {#sec_introduction_dwh}
|
||||||
|
|
||||||
起初,相同的資料庫既用於事務處理,也用於分析查詢。SQL 在這方面相當靈活:它對兩種型別的查詢都很有效。然而,在 20 世紀 80 年代末和 90 年代初,公司傾向於停止使用其 OLTP 系統進行分析目的,而是在單獨的資料庫系統上執行分析。這個單獨的資料庫被稱為 **資料倉庫**。
|
起初,相同的資料庫既用於事務處理,也用於分析查詢。SQL 在這方面相當靈活:它對兩種型別的查詢都很有效。然而,在 20 世紀 80 年代末和 90 年代初,企業有停止使用其 OLTP 系統進行分析目的的趨勢,轉而在單獨的資料庫系統上執行分析。這個單獨的資料庫被稱為 **資料倉庫**。
|
||||||
|
|
||||||
一家大型企業可能有幾十個,甚至上百個聯機事務處理系統:為面向客戶的網站提供動力的系統、控制實體店中的銷售點(收銀臺)系統、跟蹤倉庫中的庫存、規劃車輛路線、管理供應商、管理員工以及執行許多其他任務。這些系統中的每一個都很複雜,需要一個團隊來維護它,因此這些系統最終主要是相互獨立地執行。
|
一家大型企業可能有幾十個甚至上百個聯機事務處理系統:為面向客戶的網站提供動力的系統、控制實體店中的銷售點(收銀臺)系統、跟蹤倉庫中的庫存、規劃車輛路線、管理供應商、管理員工以及執行許多其他任務。這些系統中的每一個都很複雜,需要一個團隊來維護它,因此這些系統最終主要是相互獨立地執行。
|
||||||
|
|
||||||
出於幾個原因,業務分析師和資料科學家直接查詢這些 OLTP 系統通常是不可取的:
|
出於幾個原因,業務分析師和資料科學家直接查詢這些 OLTP 系統通常是不可取的:
|
||||||
|
|
||||||
* 感興趣的資料可能分佈在多個事務型系統中,使得在單個查詢中組合這些資料集變得困難(稱為 **資料孤島** 的問題);
|
* 感興趣的資料可能分佈在多個事務型系統中,使得在單個查詢中組合這些資料集變得困難(稱為 **資料孤島** 的問題);
|
||||||
* 適合 OLTP 的模式和資料佈局不太適合分析(參見["星型和雪花型:分析模式"](/tw/ch3#sec_datamodels_analytics));
|
* 適合 OLTP 的模式和資料佈局不太適合分析(參見["星型和雪花型:分析模式"](/tw/ch3#sec_datamodels_analytics));
|
||||||
* 分析查詢可能相當昂貴,在 OLTP 資料庫上執行它們會影響其他使用者的效能;以及
|
* 分析查詢可能相當昂貴,在 OLTP 資料庫上執行它們會影響其他使用者的效能;以及
|
||||||
* OLTP 系統可能位於使用者出於安全或合規原因不允許直接訪問的單獨網路中。
|
* 出於安全或合規原因,OLTP 系統可能位於不允許使用者直接訪問的單獨網路中。
|
||||||
|
|
||||||
相比之下,**資料倉庫** 是一個單獨的資料庫,分析師可以隨心所欲地查詢,而不會影響 OLTP 操作 [^7]。正如我們將在[第 4 章](/tw/ch4#ch_storage)中看到的,資料倉庫通常以與 OLTP 資料庫非常不同的方式儲存資料,以最佳化分析中常見的查詢型別。
|
相比之下,**資料倉庫** 是一個單獨的資料庫,分析師可以隨心所欲地查詢,而不會影響 OLTP 操作 [^7]。正如我們將在[第 4 章](/tw/ch4#ch_storage)中看到的,資料倉庫通常以與 OLTP 資料庫非常不同的方式儲存資料,以最佳化分析中常見的查詢型別。
|
||||||
|
|
||||||
|
@ -30,11 +30,11 @@ breadcrumbs: false
|
|||||||
|
|
||||||
在构建应用程序时,我们通常会采用几个软件系统或服务,例如数据库或 API,并用一些应用程序代码将它们粘合在一起。如果你正在做数据系统设计的工作,那么这个过程可能会相当容易。
|
在构建应用程序时,我们通常会采用几个软件系统或服务,例如数据库或 API,并用一些应用程序代码将它们粘合在一起。如果你正在做数据系统设计的工作,那么这个过程可能会相当容易。
|
||||||
|
|
||||||
然而,随着你的应用程序变得更加雄心勃勃,挑战就会出现。有许多具有不同特性的数据库系统,适合不同的目的——你如何选择使用哪一个?有各种缓存方法、构建搜索索引的几种方式等等——你如何推理它们的权衡?你需要找出哪些工具和哪些方法最适合手头的任务,当你需要做单个工具无法单独完成的事情时,组合工具可能会很困难。
|
然而,随着你的应用程序变得更加雄心勃勃,挑战就会出现。有许多具有不同特性的数据库系统,适合不同的目的——你如何选择使用哪一个?有各种缓存方法、构建搜索索引的几种方式等等——你如何在它们之间进行权衡?你需要找出哪些工具和哪些方法最适合手头的任务,当你需要做单个工具无法单独完成的事情时,组合工具可能会很困难。
|
||||||
|
|
||||||
本书是一个指南,帮助你决定使用哪些技术以及如何组合它们。正如你将看到的,没有一种方法从根本上优于其他方法;一切都有利弊。通过本书,你将学会提出正确的问题来评估和比较数据系统,以便你能找出哪种方法最能满足你特定应用程序的需求。
|
本书是一个指南,帮助你决定使用哪些技术以及如何组合它们。正如你将看到的,没有一种方法从根本上优于其他方法;一切都有利弊。通过本书,你将学会提出正确的问题来评估和比较数据系统,以便你能找出哪种方法最能满足你特定应用程序的需求。
|
||||||
|
|
||||||
我们将通过观察当今组织中数据的一些典型使用方式来开始我们的旅程。这里的许多想法起源于 **企业软件**(即大型组织(如大公司和政府)的软件需求和工程实践),因为历史上只有大型组织拥有需要复杂技术解决方案的大数据量。如果你的数据量足够小,你可以简单地将其保存在电子表格中!然而,最近小公司和初创公司管理大数据量并构建数据密集型系统也变得很常见。
|
我们将通过观察当今组织中数据的一些典型使用方式来开始我们的旅程。这里的许多想法起源于 **企业软件**(即大型组织的软件需求和工程实践,大型组织包括大公司和政府等),因为历史上只有大型组织拥有需要复杂技术解决方案的大数据量。如果你的数据量足够小,你可以简单地将其保存在电子表格中!然而,最近小公司和初创公司管理大数据量并构建数据密集型系统也变得很常见。
|
||||||
|
|
||||||
数据系统的关键挑战之一是不同的人需要用数据做非常不同的事情。如果你在一家公司工作,你和你的团队将有一套优先事项,而另一个团队可能有完全不同的目标,即使你们可能在处理相同的数据集!此外,这些目标可能没有明确阐述,这可能导致对正确方法的误解和分歧。
|
数据系统的关键挑战之一是不同的人需要用数据做非常不同的事情。如果你在一家公司工作,你和你的团队将有一套优先事项,而另一个团队可能有完全不同的目标,即使你们可能在处理相同的数据集!此外,这些目标可能没有明确阐述,这可能导致对正确方法的误解和分歧。
|
||||||
|
|
||||||
@ -51,14 +51,14 @@ breadcrumbs: false
|
|||||||
|
|
||||||
本书中我们将讨论的大部分内容都与 **后端开发** 有关。为了解释这个术语:对于 Web 应用程序,在 Web 浏览器中运行的客户端代码称为 **前端**,处理用户请求的服务器端代码称为 **后端**。移动应用类似于前端,它们提供用户界面,通常通过互联网与服务器端后端通信。前端有时在用户设备上本地管理数据 [^2],但最大的数据基础设施挑战通常在于后端:前端只需要处理一个用户的数据,而后端代表 **所有** 用户管理数据。
|
本书中我们将讨论的大部分内容都与 **后端开发** 有关。为了解释这个术语:对于 Web 应用程序,在 Web 浏览器中运行的客户端代码称为 **前端**,处理用户请求的服务器端代码称为 **后端**。移动应用类似于前端,它们提供用户界面,通常通过互联网与服务器端后端通信。前端有时在用户设备上本地管理数据 [^2],但最大的数据基础设施挑战通常在于后端:前端只需要处理一个用户的数据,而后端代表 **所有** 用户管理数据。
|
||||||
|
|
||||||
后端服务通常可通过 HTTP(有时是 WebSocket)访问;它通常由一些应用程序代码组成,这些代码在一个或多个数据库中读取和写入数据,有时还与其他数据系统(如缓存或消息队列)接口(我们可能将其统称为 **数据基础设施**)。应用程序代码通常是 **无状态的**(即,当它完成处理一个 HTTP 请求时,它会忘记关于该请求的所有内容),任何需要从一个请求持续到另一个请求的信息都需要存储在客户端或服务器端数据基础设施中。
|
后端服务通常可通过 HTTP(有时是 WebSocket)访问;它通常由一些应用程序代码组成,这些代码在一个或多个数据库中读取和写入数据,有时还与其他数据系统(如缓存或消息队列)接口(我们可能将其统称为 **数据基础设施**)。应用程序代码通常是 **无状态的**(即,当它完成处理一个 HTTP 请求时,它会忘记关于该请求的所有内容),任何需要从一个请求持续到另一个请求的信息都需要存储在客户端或服务器端的数据基础设施中。
|
||||||
|
|
||||||
|
|
||||||
## 分析型与事务型系统 {#sec_introduction_analytics}
|
## 分析型与事务型系统 {#sec_introduction_analytics}
|
||||||
|
|
||||||
如果你在企业中从事数据系统工作,你可能会遇到几种不同类型的数据工作者。第一类是 **后端工程师**,他们构建处理读取和更新数据请求的服务;这些服务通常直接或间接地通过其他服务为外部用户提供服务(参见["微服务与 Serverless"](/ch1#sec_introduction_microservices))。有时服务是供组织其他部分内部使用的。
|
如果你在企业中从事数据系统工作,你可能会遇到几种不同类型的数据工作者。第一类是 **后端工程师**,他们构建服务来处理读取和更新数据的请求;这些服务通常直接或间接地通过其他服务为外部用户提供服务(参见["微服务与 Serverless"](/ch1#sec_introduction_microservices))。有时服务是供组织其他部分内部使用的。
|
||||||
|
|
||||||
除了管理后端服务的团队外,通常还有两类人需要访问组织的数据:**业务分析师**,他们生成关于组织活动的报告,以帮助管理层做出更好的决策(**商业智能** 或 **BI**);以及 **数据科学家**,他们在数据中寻找新的见解,或创建由数据分析和机器学习/AI 支持的面向用户的产品功能(例如,电子商务网站上的"购买了 X 的人也购买了 Y"推荐、风险评分或垃圾邮件过滤等预测分析,以及搜索结果排名)。
|
除了管理后端服务的团队外,通常还有两类人需要访问组织的数据:**业务分析师**,他们生成关于组织活动的报告,以帮助管理层做出更好的决策(**商业智能** 或 **BI**);以及 **数据科学家**,他们在数据中寻找新的见解,或创建由数据分析和机器学习(AI)支持的面向用户的产品功能(例如,电子商务网站上的“购买了 X 的人也购买了 Y”推荐、风险评分或垃圾邮件过滤等预测分析,以及搜索结果排名)。
|
||||||
|
|
||||||
尽管业务分析师和数据科学家倾向于使用不同的工具并以不同的方式操作,但他们有一些共同点:两者都执行 **分析**,这意味着他们查看用户和后端服务生成的数据,但他们通常不修改这些数据(除了可能修复错误)。他们可能创建派生数据集,其中原始数据已经以某种方式处理过。这导致了两种类型系统之间的分离——我们将在本书中使用这种区别:
|
尽管业务分析师和数据科学家倾向于使用不同的工具并以不同的方式操作,但他们有一些共同点:两者都执行 **分析**,这意味着他们查看用户和后端服务生成的数据,但他们通常不修改这些数据(除了可能修复错误)。他们可能创建派生数据集,其中原始数据已经以某种方式处理过。这导致了两种类型系统之间的分离——我们将在本书中使用这种区别:
|
||||||
|
|
||||||
@ -67,24 +67,24 @@ breadcrumbs: false
|
|||||||
|
|
||||||
正如我们将在下一节中看到的,事务型系统和分析型系统通常出于充分的理由而保持分离。随着这些系统的成熟,出现了两个新的专业角色:**数据工程师** 和 **分析工程师**。数据工程师是知道如何集成事务型系统和分析型系统的人,并更广泛地负责组织的数据基础设施 [^3]。分析工程师对数据进行建模和转换,使其对组织中的业务分析师和数据科学家更有用 [^4]。
|
正如我们将在下一节中看到的,事务型系统和分析型系统通常出于充分的理由而保持分离。随着这些系统的成熟,出现了两个新的专业角色:**数据工程师** 和 **分析工程师**。数据工程师是知道如何集成事务型系统和分析型系统的人,并更广泛地负责组织的数据基础设施 [^3]。分析工程师对数据进行建模和转换,使其对组织中的业务分析师和数据科学家更有用 [^4]。
|
||||||
|
|
||||||
许多工程师专注于事务型或分析型方面。然而,本书涵盖了事务型和分析型数据系统,因为两者在组织内数据生命周期中都扮演着重要角色。我们将深入探讨用于向内部和外部用户提供服务的数据基础设施,以便你能更好地与这一分界线另一边的同事合作。
|
许多工程师专注于事务型系统和分析型系统中的一个。然而,本书涵盖了事务型和分析型数据系统,因为两者在组织内数据的生命周期中都扮演着重要角色。我们将深入探讨用于向内部和外部用户提供服务的数据基础设施,以便你能更好地与分界线另一边的同事合作。
|
||||||
|
|
||||||
### 事务处理与分析的特征 {#sec_introduction_oltp}
|
### 事务处理与分析的特征 {#sec_introduction_oltp}
|
||||||
|
|
||||||
在商业数据处理的早期,对数据库的写入通常对应于发生的 **商业交易**:进行销售、向供应商下订单、支付员工工资等。随着数据库扩展到不涉及金钱交换的领域,**事务** 这个术语仍然保留了下来,指的是形成逻辑单元的一组读取和写入。
|
在商业数据处理的早期,对数据库的写入通常对应于发生的 **商业交易(commercial transaction)**:进行销售、向供应商下订单、支付员工工资等。随着数据库扩展到不涉及金钱交换的领域,**事务(transaction)** 这个术语仍然保留了下来,指的是形成逻辑单元的一组读取和写入。
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> [第 8 章](/ch8#ch_transactions) 详细探讨了我们所说的事务的含义。本章松散地使用该术语来指代低延迟的读取和写入。
|
> [第 8 章](/ch8#ch_transactions) 详细探讨了我们所说的事务的含义。本章松散地使用该术语来指代低延迟的读取和写入。
|
||||||
|
|
||||||
尽管数据库开始用于许多不同类型的数据——社交媒体上的帖子、游戏中的移动、地址簿中的联系人等等——基本的访问模式仍然类似于处理商业交易。事务型系统通常通过某个键查找少量记录(这称为 **点查询**)。基于用户的输入插入、更新或删除记录。因为这些应用程序是交互式的,这种访问模式被称为 **联机事务处理**(OLTP)。
|
尽管数据库开始用于许多不同类型的数据——社交媒体上的帖子、游戏中的移动、地址簿中的联系人等等——基本的访问模式仍然类似于处理商业交易。事务型系统通常通过某个键查找少量记录(这称为 **点查询**)。基于用户的输入插入、更新或删除记录。因为这些应用程序是交互式的,这种访问模式被称为 **联机事务处理**(OLTP)。
|
||||||
|
|
||||||
然而,数据库也越来越多地用于分析,与 OLTP 相比,分析具有非常不同的访问模式。通常,分析查询会扫描大量记录,并计算聚合统计信息(如计数、求和或平均值),而不是将单个记录返回给用户。例如,超市连锁店的业务分析师可能想要回答以下分析查询:
|
然而,数据库也越来越多地用于分析,与 OLTP 相比,分析具有非常不同的访问模式。通常,分析查询会扫描大量记录,并计算聚合统计信息(如计数、求和或平均值),而不是将单个记录返回给用户。例如,连锁超市的业务分析师可能想要回答以下分析查询:
|
||||||
|
|
||||||
* 我们每家商店在一月份的总收入是多少?
|
* 我们每家商店在一月份的总收入是多少?
|
||||||
* 在我们最近的促销期间,我们卖出了比平时多多少香蕉?
|
* 在我们最近的促销期间,我们比平时多卖出了多少香蕉?
|
||||||
* 哪个品牌的婴儿食品最常与 X 品牌尿布一起购买?
|
* 哪个品牌的婴儿食品最常与 X 品牌尿布一起购买?
|
||||||
|
|
||||||
这些类型查询产生的报告对商业智能很重要,帮助管理层决定下一步做什么。为了将这种使用数据库的模式与事务处理区分开来,它被称为 **联机分析处理**(OLAP)[^5]。OLTP 和分析之间的区别并不总是很明确,但[表 1-1](/ch1#tab_oltp_vs_olap) 列出了一些典型特征。
|
这些类型的查询产生的报告对商业智能很重要,可以帮助管理层决定下一步做什么。为了将这种使用数据库的模式与事务处理区分开来,它被称为 **联机分析处理**(OLAP)[^5]。OLTP 和分析之间的区别并不总是很明确,但[表 1-1](/ch1#tab_oltp_vs_olap) 列出了一些典型特征。
|
||||||
|
|
||||||
{{< figure id="tab_oltp_vs_olap" title="表 1-1. 事务型系统和分析型系统特征比较" class="w-full my-4" >}}
|
{{< figure id="tab_oltp_vs_olap" title="表 1-1. 事务型系统和分析型系统特征比较" class="w-full my-4" >}}
|
||||||
|
|
||||||
@ -92,31 +92,31 @@ breadcrumbs: false
|
|||||||
|-----------------|----------------------------------------|-----------------------------------|
|
|-----------------|----------------------------------------|-----------------------------------|
|
||||||
| 主要读取模式 | 点查询(通过键获取单个记录) | 对大量记录进行聚合 |
|
| 主要读取模式 | 点查询(通过键获取单个记录) | 对大量记录进行聚合 |
|
||||||
| 主要写入模式 | 创建、更新和删除单个记录 | 批量导入(ETL)或事件流 |
|
| 主要写入模式 | 创建、更新和删除单个记录 | 批量导入(ETL)或事件流 |
|
||||||
| 人类用户示例 | Web/移动应用程序的最终用户 | 内部分析师,用于决策支持 |
|
| 人类用户示例 | Web 或移动应用程序的最终用户 | 内部分析师,用于决策支持 |
|
||||||
| 机器使用示例 | 检查操作是否被授权 | 检测欺诈/滥用模式 |
|
| 机器使用示例 | 检查操作是否被授权 | 检测欺诈/滥用模式 |
|
||||||
| 查询类型 | 固定的查询集,由应用程序预定义 | 分析师可以进行任意查询 |
|
| 查询类型 | 固定的查询集,由应用程序预定义 | 分析师可以进行任意查询 |
|
||||||
| 数据代表 | 数据的最新状态(当前时间点) | 随时间发生的事件历史 |
|
| 数据代表 | 数据的最新状态(当前时间点) | 随时间发生的事件历史 |
|
||||||
| 数据集大小 | GB 到 TB | TB 到 PB |
|
| 数据集大小 | GB 到 TB | TB 到 PB |
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> OLAP 中 **online** 的含义不明确;它可能指的是查询不仅用于预定义的报告,而且分析师可以交互式地使用 OLAP 系统进行探索性查询。
|
> OLAP 中 **联机(online)** 的含义不明确;它可能指的是查询不仅用于预定义的报告,也可能是指分析师交互式地使用 OLAP 系统来进行探索性查询。
|
||||||
|
|
||||||
在事务型系统中,通常不允许用户构建自定义 SQL 查询并在数据库上运行它们,因为这可能会允许他们读取或修改他们没有权限访问的数据。此外,他们可能编写执行成本高昂的查询,从而影响其他用户的数据库性能。出于这些原因,OLTP 系统主要运行嵌入到应用程序代码中的固定查询集,只偶尔使用一次性自定义查询进行维护或故障排除。另一方面,分析数据库通常让用户可以自由地手动编写任意 SQL 查询,或使用 Tableau、Looker 或 Microsoft Power BI 等数据可视化或仪表板工具自动生成查询。
|
在事务型系统中,通常不允许用户构建自定义 SQL 查询并在数据库上运行它们,因为这可能会允许他们读取或修改他们没有权限访问的数据。此外,他们可能编写执行成本高昂的查询,从而影响其他用户的数据库性能。出于这些原因,OLTP 系统主要运行嵌入到应用程序代码中的固定查询集,只偶尔使用一次性的自定义查询来进行维护或故障排除。另一方面,分析数据库通常让用户可以自由地手动编写任意 SQL 查询,或使用 Tableau、Looker 或 Microsoft Power BI 等数据可视化或仪表板工具自动生成查询。
|
||||||
|
|
||||||
还有一种类型的系统是为分析工作负载(对许多记录进行聚合的查询)设计的,但嵌入到面向用户的产品中。这一类别被称为 **产品分析** 或 **实时分析**,为这种用途设计的系统包括 Pinot、Druid 和 ClickHouse [^6]。
|
还有一种类型的系统是为分析型的工作负载(对许多记录进行聚合的查询)设计的,但嵌入到面向用户的产品中。这一类别被称为 **产品分析** 或 **实时分析**,为这种用途设计的系统包括 Pinot、Druid 和 ClickHouse [^6]。
|
||||||
|
|
||||||
### 数据仓库 {#sec_introduction_dwh}
|
### 数据仓库 {#sec_introduction_dwh}
|
||||||
|
|
||||||
起初,相同的数据库既用于事务处理,也用于分析查询。SQL 在这方面相当灵活:它对两种类型的查询都很有效。然而,在 20 世纪 80 年代末和 90 年代初,公司倾向于停止使用其 OLTP 系统进行分析目的,而是在单独的数据库系统上运行分析。这个单独的数据库被称为 **数据仓库**。
|
起初,相同的数据库既用于事务处理,也用于分析查询。SQL 在这方面相当灵活:它对两种类型的查询都很有效。然而,在 20 世纪 80 年代末和 90 年代初,企业有停止使用其 OLTP 系统进行分析目的的趋势,转而在单独的数据库系统上运行分析。这个单独的数据库被称为 **数据仓库**。
|
||||||
|
|
||||||
一家大型企业可能有几十个,甚至上百个联机事务处理系统:为面向客户的网站提供动力的系统、控制实体店中的销售点(收银台)系统、跟踪仓库中的库存、规划车辆路线、管理供应商、管理员工以及执行许多其他任务。这些系统中的每一个都很复杂,需要一个团队来维护它,因此这些系统最终主要是相互独立地运行。
|
一家大型企业可能有几十个甚至上百个联机事务处理系统:为面向客户的网站提供动力的系统、控制实体店中的销售点(收银台)系统、跟踪仓库中的库存、规划车辆路线、管理供应商、管理员工以及执行许多其他任务。这些系统中的每一个都很复杂,需要一个团队来维护它,因此这些系统最终主要是相互独立地运行。
|
||||||
|
|
||||||
出于几个原因,业务分析师和数据科学家直接查询这些 OLTP 系统通常是不可取的:
|
出于几个原因,业务分析师和数据科学家直接查询这些 OLTP 系统通常是不可取的:
|
||||||
|
|
||||||
* 感兴趣的数据可能分布在多个事务型系统中,使得在单个查询中组合这些数据集变得困难(称为 **数据孤岛** 的问题);
|
* 感兴趣的数据可能分布在多个事务型系统中,使得在单个查询中组合这些数据集变得困难(称为 **数据孤岛** 的问题);
|
||||||
* 适合 OLTP 的模式和数据布局不太适合分析(参见["星型和雪花型:分析模式"](/ch3#sec_datamodels_analytics));
|
* 适合 OLTP 的模式和数据布局不太适合分析(参见["星型和雪花型:分析模式"](/ch3#sec_datamodels_analytics));
|
||||||
* 分析查询可能相当昂贵,在 OLTP 数据库上运行它们会影响其他用户的性能;以及
|
* 分析查询可能相当昂贵,在 OLTP 数据库上运行它们会影响其他用户的性能;以及
|
||||||
* OLTP 系统可能位于用户出于安全或合规原因不允许直接访问的单独网络中。
|
* 出于安全或合规原因,OLTP 系统可能位于不允许用户直接访问的单独网络中。
|
||||||
|
|
||||||
相比之下,**数据仓库** 是一个单独的数据库,分析师可以随心所欲地查询,而不会影响 OLTP 操作 [^7]。正如我们将在[第 4 章](/ch4#ch_storage)中看到的,数据仓库通常以与 OLTP 数据库非常不同的方式存储数据,以优化分析中常见的查询类型。
|
相比之下,**数据仓库** 是一个单独的数据库,分析师可以随心所欲地查询,而不会影响 OLTP 操作 [^7]。正如我们将在[第 4 章](/ch4#ch_storage)中看到的,数据仓库通常以与 OLTP 数据库非常不同的方式存储数据,以优化分析中常见的查询类型。
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user