Skip to content

Steve Trucking,如果由我來設計

另有 28 種語言版本

English · Español · 日本語 · Português (Brasil) · Français · Deutsch · Italiano · 한국어 · 简体中文 · Português (Portugal) · Bahasa Indonesia · Türkçe · Polski · Tiếng Việt · ไทย · Nederlands · العربية · עברית · Українська · हिन्दी · Русский · Svenska · Dansk · Norsk bokmål · Suomi · Español (México) · Français (Canada) · Deutsch (Schweiz)

A row of plain white delivery trucks ready at the loading doors at first light, a clipboard on the front of the nearest one.
圖片由 AI 生成

第 6 個模組,共 6 個,屬於 Data Architect 課程第 6 章主資料與身分,也是第 1 部分的結尾。 上一篇:當權威被共用 · 下一篇:第 2 部分從Designing for Scale *(coming soon)*開始

**本檢查點回答的問題:**你能在一個真實的情景中把第 1 部分串起來嗎?

**先嚐試挑戰。**這是我對檢查點 1 挑戰的講解。如果你還沒有畫出自己的設計,在繼續讀之前先去畫。價值在於把你的推理和我的進行比較,而不在於讀答案。

這是「如果由我來設計」:一個可行的方案,而不是唯一的答案,其中的權衡都已點明,我的立場也已表明。我們還沒有講大數據量、查詢設計、整合模式、遷移或事務,這是有意的:架構會隨著你學到更多而發展。但第 1 部分給了我們足夠的東西來搭好骨架。

來自簡介:每個工作日大約 3,300 次配送,每年一百萬次,每年增長 30%。每次配送大約 1.6 個明細項目(每年 160 萬個);每次配送大約八次狀態變更(每年 800 萬次);每年四五百萬張照片;每天大約 20 萬條 GPS 讀數;每年大約 18 萬個案例;三個零售合作夥伴用三種不同的方式傳送裝貨清單;九個配送中心;330 輛卡車,配兩人小組。而且 Steve Trucking 已經在執行一個 Salesforce org,有 Service Cloud、Field Service 和一個合作夥伴入口網站。在畫任何一個方框之前,先數零。它們會決定下面好幾件事。

配送是核心,而 Field Service 已經在做排程了。所以我從 Field Service 的標準模型開始,就像第 3 章的那個切面一樣:

業務概念Salesforce 物件原因
零售合作夥伴客戶(Account)(零售合作夥伴記錄類型)Steve Trucking 與之簽約的企業;承載合同、案例和入口網站存取
合作夥伴員工(配送中心經理、門店員工)連絡人(Contact)入口網站使用者必須是連絡人
一次配送:一位收貨人、一個地址、一個合作夥伴訂單、一天工作訂單(Work Order)Field Service 的工作單位;排期、移動應用和服務報告都掛在它上面
每件商品或服務:冰箱、安裝、拉走舊貨工作訂單明細項目(Work Order Line Item)劃分工作,驅動檢查清單和開票
停靠點類型:僅配送、加安裝、加拉走舊貨工作類型(Work Type)設定時長、技能和安裝檢查清單
排定的上門服務及其時間視窗服務約會(Service Appointment)Field Service 排期的物件,也是配送小組的應用裡顯示的東西
配送小組和卡車;配送中心的排程區域服務資源、服務小組、服務區域(Service Resource、Service Crew、Service Territory)Field Service 把一個配送小組作為一個資源來排期
收貨人的諮詢、合作夥伴的索賠案例(Case)服務控制台、權利、電子郵件轉案例
合作夥伴在鳳凰城配送中心週二的那份清單Manifest__c(自訂)沒有標準物件能表示接收、對賬和重放的單位

其他一切都保持標準。抵制更多的自訂物件是有意的:第 1 章的問題是架構師什麼時候應該抵制再加一個,而在這裡答案是「幾乎總是」。比如,合作夥伴的訂單行就不是一個新物件。它就是工作訂單,由合作夥伴的編號來識別。

檢查點 1:配送核心 檢查點 1 為 Steve Trucking 設計的物理核心。核心之上:零售合作夥伴是一個帶有記錄類型的客戶(Account),它傳送裝貨清單,也就是唯一的自訂物件,而每次配送都屬於一個合作夥伴。一份裝貨清單列出多次配送。配送是一張工作訂單(Work Order),收貨人以欄位形式放在上面;它被排期為預約,也就是服務約會(Service Appointment),並包含配送項目,也就是工作訂單明細項目(Work Order Line Item),每個配送項目由一種停靠點類型描述,也就是工作類型(Work Type)。配送小組,也就是服務小組(Service Crew),被分配到預約,並在配送中心排程區域,也就是服務區域(Service Territory)中工作。諮詢或索賠,也就是案例(Case),可以涉及配送。核心之外:配送小組的 GPS 定位訊號進入資料倉儲,配送連結到照片儲存中的配送照片,每個預約把它的狀態歷史以事件形式發布到資料倉儲。下方寫著:看向母艦:Field Service 就是配送核心。 核心之上 核心之外 傳送 委託 列出 涉及 排期為 包含 描述 供小組工作 分配到 傳送定位 連結到 發布 零售合作夥伴 Account · 記錄類型 裝貨清單 Manifest__c · 自訂 諮詢或索賠 Case 配送 WorkOrder · 收貨人欄位 配送項目 WorkOrderLineItem 預約 ServiceAppointment 停靠點類型 WorkType 配送中心排程區域 ServiceTerritory 配送小組 ServiceCrew 狀態歷史 事件,資料倉儲 配送照片 照片儲存,以連結存取 GPS 定位訊號 資料倉儲,以參照存取 看向母艦:Field Service 就是配送核心。 恰好一個 零個或一個 一個或多個 零個或多個 查閱 © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

它由第 3 章的最終圖(設計 Salesforce 物理模型)發展而來:同樣的物件在同樣的位置,再加上配送小組、排程區域、案例,以及檢查點 1 放在核心之外的東西。

把合作夥伴的訂單與配送比對起來的鍵

Section titled “把合作夥伴的訂單與配送比對起來的鍵 ”

每一行裝貨清單都變成一個工作訂單,並連結到它的裝貨清單。鍵是我最想得到回答的問題:我們怎麼知道合作夥伴的這一行就是那一次配送?我的答案是:工作訂單上的一個外部 ID,由零售合作夥伴加上合作夥伴自己的訂單和配送編號組成(類似 KEYSTONE-PHX-8843119-1),標記為唯一。每個來源一個欄位,一一對應。它是合作夥伴的識別符號,而不是我們的:這是第 2 章的「一樣東西,好幾個識別符號」,也是模組 1 的「合作夥伴擁有它的訂單編號」。

為什麼這很重要:裝貨清單提前一到兩天到達,並會在當天修改。有了這個鍵,每一份重發或修改後的裝貨清單都會做 upsert,而不是產生重複。修改會更新工作訂單,一個欄位記錄下這次修改,而對一次已經排好路線的配送的修改會提醒協調員:合作夥伴的修改被應用了,但在排程確認之前會被標記出來。這也是與第 4 章那張圖相比發生變化的地方。如今每一份裝貨清單都先進入 RouteDesk,協調員再把路線重新錄入 Salesforce,並把已完成的停靠點錄回去。在這個設計中,裝貨清單直接進入 Salesforce,按合作夥伴的鍵做 upsert;RouteDesk 退役,重複錄入也就結束了。整合那一章會設計三種入站格式。資料層面的決定就是這個鍵。

收貨人:個人帳戶、連絡人,還是都不是?

Section titled “收貨人:個人帳戶、連絡人,還是都不是? ”

這是第 1 部分中最有意思的資料決定,所以這裡先列出選項,再給出我的選擇。

選項 A:個人帳戶。每位收貨人成為一個個人帳戶,連結到每一次配送。*支援的理由:*標準,能與 Service Cloud、訊息和控制台自然配合,能識別重複的收貨人。*反對的理由:*每年大約一百萬位新收貨人,每一位都是一個個人帳戶,儲存大約是企業客戶的兩倍(Estimated Record Size by Object Type (opens in a new tab),英文),所以兩年內就會成為 org 中最大的物件之一。而且收貨人不是 Steve Trucking 的客戶。他們是每個零售合作夥伴的客戶,而 Steve Trucking 絕不能把一個合作夥伴的客戶和另一個合作夥伴的客戶混在一起(S2)。

**選項 B:零售合作夥伴客戶下的連絡人。***反對的理由:*三四個客戶下面掛一百萬個連絡人,是大規模的父子資料傾斜,遠遠超過 Salesforce 關於每個父記錄大約 10,000 條子記錄的建議(Considerations for Object Relationships (opens in a new tab);Parent-Child Data Skew (opens in a new tab),英文)。這是一個需要展示出來、然後否決的選項。

選項 C:收貨人資訊放在配送上。收貨人的姓名、電話、電子郵件、地址和配送備註是工作訂單上的欄位(地址欄位在那裡本來就是標準欄位),從裝貨清單中採集。*支援的理由:*沒有新的大物件;資料的存在時間恰好與配送所需的一樣長;刪除按每次配送、按合作夥伴的時間表進行;而合作夥伴隔離是自然而然的,因為每次配送只屬於一個合作夥伴。*反對的理由:*重複的收貨人不會被識別為同一個人。

這就是需要把握的平衡。是否會有需要把好幾次配送識別為同一個人、在同一個地點?是否要給這個人一個登入帳號?這就是兩種情況的分界線:一種是收貨人需要一條屬於自己的記錄,另一種是收貨人資訊只是關於這次配送的資料。而且還有一條折中的路。把零售合作夥伴自己的客戶 ID 作為配送上的一個欄位,即零售合作夥伴客戶 ID(Retail Partner Customer ID)。它不會建立收貨人記錄,但能把一個合作夥伴為同一位客戶發來的多次配送串在一起,這是更統一的客戶體驗的起點,而且它直接指回零售合作夥伴的系統,也就是那位客戶真正所在的地方。這是合作夥伴的識別符號,所以它只有和合作夥伴放在一起才有意義:一個合作夥伴的客戶 4417 和另一個合作夥伴的客戶 4417 毫無關係。

依我的專業判斷,選項 C 是正確的選擇。不能識別重複這一點是可以接受的,甚至是可取的:除了這次配送,Steve Trucking 和這些人沒有任何關係。這又是模組 1:收貨人是合作夥伴的客戶,而合作夥伴是他們身分的權威。這也是第 5 章:落在一個地方、與一次配送繫結的個人資料,保護、保留和刪除起來都要容易得多。而且它也經得起第 2 章範式的檢驗:收貨人的資訊與配送是一對一的,所以它們屬於配送。一個單獨的收貨人子物件能省下幾個重複的值,代價卻是多一個物件、多一個關係以及隨之而來的開銷;而它唯一能省下更多的方式,是把跨零售合作夥伴的同一個人當作一個人,而我們不會這麼做。所以由配送承載收貨人資訊,再用零售合作夥伴客戶 ID 指回合作夥伴自己的系統。

收貨人是誰? 收貨人的三個選項,各自列出贊成和反對的理由。選項 A,每位收貨人一個個人帳戶:在關係上不通過,因為收貨人是合作夥伴的客戶;在資料量上不通過,每年大約一百萬個,儲存是企業客戶的兩倍;在資料傾斜上通過,每位都是自己的帳戶;在合作夥伴隔離上不通過,因為它會混合各合作夥伴的客戶;在刪除上不通過,比配送存在得更久;在識別重複上通過。否決。選項 B,零售合作夥伴下的連絡人:在關係上不通過,因為他們不是合作夥伴的員工;在資料量上不通過;在資料傾斜上不通過,三四個客戶下掛一百萬個;在隔離上通過,放在單一合作夥伴的客戶下;在刪除上不通過;能在合作夥伴內識別重複。展示並否決。選項 C,工作訂單上的收貨人欄位,以醒目標示作為檢查點 1 的選擇:唯一的關係就是這次配送;沒有新物件;沒有新的父記錄;每次配送一個合作夥伴;按合作夥伴的時間表刪除;而重複的收貨人不會被識別,這沒有問題。下方寫著:按照你實際擁有的關係為這個人建模。 A:個人帳戶 否決 贊成 能識別重複的收貨人 沒有父記錄傾斜:每位都是自己的帳戶 反對 是合作夥伴的客戶,不是我們的 每年約 100 萬個,儲存翻倍 混合各合作夥伴的客戶(S2) 比配送存在得更久 B:連絡人 掛在零售合作夥伴下:展示並否決 贊成 保留在單一合作夥伴下(S2) 在合作夥伴內可識別重複 反對 不是合作夥伴的員工 3 或 4 個客戶下掛 100 萬:傾斜 比配送存在得更久 C:放在配送上 工作訂單上的欄位:選定方案 贊成 唯一的關係就是這次配送 沒有新物件,沒有新的父記錄 每次配送一個合作夥伴(S2) 按合作夥伴的時間表刪除 反對 重複的收貨人不會被識別:沒問題 按照你實際擁有的關係為這個人建模。 © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

我會跨合作夥伴統一收貨人嗎?

Section titled “我會跨合作夥伴統一收貨人嗎? ”

John Smith,123 Main Street,同時出現在 Redrock 和 Brightwave 的裝貨清單中。多半是同一個人。Steve Trucking 應該統一他們嗎?**不,有意不統一。**跨零售合作夥伴統一收貨人會違反 S2:一個合作夥伴絕不能看到另一個合作夥伴的收貨人,而一個統一的身分恰恰就是那座會洩露資訊的橋。這正是本章立場的運用:在混合代價高昂的地方少比對,而在這裡,混合的代價非常高。

如果某個零售合作夥伴以後希望在它自己的配送範圍內識別重複的收貨人,那是限定在該合作夥伴範圍內的身分解析工具(比如 Data 360 的身分解析)的工作:一張註冊式的地圖,而不是一個個人帳戶,而且永遠不跨合作夥伴。一張誰是誰的地圖不授予所有權,也不授予存取權限。

第 3 章問的是資料應該放在哪裡。在這裡,零的個數給出了答案:

  • 當前狀態放在服務約會和工作訂單上。狀態變更的歷史,每年大約 800 萬次,而且還在增長,不需要放在核心 org 裡。每次變更都作為一個事件釋出出去,儲存在資料倉儲 Snowflake 中。org 保留當前狀態;歷史仍然可供服務、運營和分析使用,只是不在運營資料庫裡。
  • 照片(每年四五百萬張,有些拍到了人或住宅內部)放在核心平台之外為這種資料量而構建的儲存中,直接從配送小組的應用上傳。org 只保留它需要的東西:每張照片一條小小的索引記錄,或者只是一個數量和一個「所需安裝照片已齊全」的標誌。我更傾向於較輕的那種:讓 org 保持精簡,由照片儲存自己擁有它的索引和保留策略。
  • GPS 讀數(每天 20 萬條)留在 FleetLink 中,並進入 Snowflake;org 只需要最新的位置,供追蹤頁面和排程員的地圖使用。
  • RouteDesk 八年的歷史(大約 500 萬次配送)進入資料倉儲或檔案庫,供索賠時查閱。哪些資料(如果有的話)要進入 org,是第 2 部分的一個遷移決定。
檢查點 1:如果由我來設計 檢查點 1 的全景圖,如果由我來設計,位置與第 4 章的現狀全景圖相同。左邊是人:在 9 個合作夥伴配送中心內的 45 名排程協調員,330 輛卡車上約 700 名配送小組成員,100 名客服與辦公室人員,他們都使用 Salesforce;3 個合作夥伴約 300 名零售合作夥伴使用者,使用零售合作夥伴入口網站;以及每年約一百萬名收貨人,他們透過一個連結開啟追蹤頁面,無須登入,並打電話給客服人員。中間是一個帶有 Field Service 的美國 Salesforce org,上方是企業身分提供商,僅供辦公室人員使用,電子郵件轉案例把案例帶進來。右下是三個零售合作夥伴:Redrock 使用 REST API 和 webhook,Keystone 透過 SFTP 傳送 CSV,Brightwave 透過第三方網路使用 EDI;它們把裝貨清單送進一個在第 2 部分設計的整合層,整合層按合作夥伴的鍵把它們 upsert 進 Salesforce,並把狀態發回給每個合作夥伴。右邊:Salesforce 把狀態事件傳送到 Snowflake,由它保存狀態歷史和分析;原始 GPS 留在 FleetLink,它只把最新位置傳送給 Salesforce;Salesforce 透過整合把配送數量傳送到財務 ERP,由它向合作夥伴開發票並付款給配送小組;每年 400 到 500 萬張照片從配送小組的應用進入核心之外的照片儲存;RouteDesk 退役,只留下保存 8 年歷史的檔案庫。Salesforce 透過簡訊和電子郵件服務商傳送附連結的前一天訊息。下方寫著:與第 4 章是同一家公司;重複錄入和電子表格都不見了;歷史和照片放在核心之外。 上方:身分、APPEXCHANGE、WEB 人員 右側:內部系統 下方:客戶管道 右下:合作夥伴和服務商 排程協調員 45 名,在 9 個合作夥伴配送中心內 配送小組 約 700 人,330 輛卡車 客服與辦公室人員 100 名:服務、營運、財務 零售合作夥伴使用者 3 個合作夥伴,約 300 名 收貨人 每年約 100 萬 企業 IdP SSO 僅限辦公室人員 零售合作夥伴入口網站 追蹤頁面 整合 Snowflake 狀態歷史、分析 FleetLink 原始 GPS 留在這裡 財務 ERP 向合作夥伴開發票,付款給配送小組 照片儲存 每年 400–500 萬張,核心之外 RouteDesk 檔案庫 已退役;8 年歷史 電話 客服人員 電子郵件 電子郵件轉案例 簡訊和電子郵件服務商 前一天訊息,附連結 Redrock REST API、webhook Keystone 透過 SFTP 傳送 CSV Brightwave 透過第三方網路的 EDI Salesforce Field Service,一個美國 org 一個連結,無須登入 僅限辦公室人員 打電話 案例進入 裝貨清單進入 狀態發出 裝貨清單進入 狀態發出 裝貨清單進入 狀態發出 upsert,合作夥伴鍵 狀態事件 僅最新位置 配送數量 配送數量 照片,來自配送小組應用 前一天訊息,附連結 Salesforce 社群 人員 身分、應用程式、Web 內部系統 客戶管道 整合層 從發起連線的系統開始;標籤說明傳送的內容 共用憑證:信任,無直接呼叫 與第 4 章是同一家公司。重複錄入和電子表格都不見了;歷史和照片放在核心之外。 © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

檢查點 1:如果由我來設計。與第 4 章全景圖(Steve Trucking 的全景圖)的位置相同,只是重複錄入和電子表格都不見了。

  • 零售合作夥伴只看到自己的配送(S2)。每個工作訂單都帶有它的零售合作夥伴;入口網站使用者看到他們合作夥伴的配送,配送中心經理只看到自己配送中心的。
  • 合作夥伴使用者需要一個支援共用規則和角色的入口網站許可:Customer Community Plus 或 Partner Community。第 3 章的體育場座位:最便宜的座位得不到這個設計所需的共用。這兩種許可都需要為外部使用者設定角色,而 Salesforce 警告說,角色越多,org 越慢(Experience Cloud User Licenses (opens in a new tab),英文)。每個合作夥伴、每個配送中心一個角色沒有問題;每家門店一個角色就不行了。

考點。掌握哪些外部許可支援標準共用:Customer Community Plus 和 Partner Community(需要為外部使用者設定角色),而不是使用共用集的 Customer Community。

  • **收貨人不需要許可。**追蹤頁面通過一個帶有會過期的權杖的連結顯示一次配送(S3),而不是通過登入。
  • **留意資料傾斜。**每年幾十萬個工作訂單指向三四個合作夥伴客戶,就是客戶資料傾斜。一個選項是在每個合作夥伴下為每個配送中心建一個子客戶,把子記錄分散到九個或更多的父記錄下;在索賠期結束後歸檔已完成的配送,能讓每個父記錄下的活躍子記錄保持在較低水平。第 2 部分會處理這個問題。

我不會因為收貨人是個人,就為每位收貨人建立一個個人帳戶。我不會在三個客戶下面掛一百萬個連絡人。我不會在 Field Service 的工作訂單旁邊再建一個自訂的配送物件。我不會跨合作夥伴統一收貨人。我不會把幾百萬張照片或 GPS 讀數放進核心儲存。而且除非我們真的做出了主控決定,否則我不會把一個統一的收貨人叫作黃金記錄。

第 1 部分搭好了骨架;第 2 部分來檢驗它。第三年的大數據量標尺(工作訂單、服務約會和明細項目在兩三年內都會進入大數據量的範疇),針對合作夥伴範圍的清單檢視的查詢設計,三個入站整合和三個狀態回傳,RouteDesk 的遷移,當天的事務,以及入口網站背後的安全設計。Steve Trucking 也會變化。保留這個設計;你還會回來重新審視它。

  • 哪些標準物件承載核心(這裡是 Field Service 的),哪些自訂物件確實有理由存在(這裡是一個)。
  • 把每個合作夥伴的訂單行與一次配送比對起來的鍵,以及為什麼它屬於合作夥伴。
  • 收貨人是什麼,依據的是 Steve Trucking 與他們之間實際存在的關係。
  • 是否統一身分,以及在哪裡混合的代價太高而不值得冒險。
  • 什麼留在 org 裡,什麼放在核心平台之外,以及設計依賴哪些許可。