關係會帶來後果
另有 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)

第 7 個模組,共 10 個,屬於 Data Architect 課程第 3 章Salesforce 資料架構。每個模組都可以單獨閱讀。 上一篇:欄位也是架構 · 下一篇:所有權與生命週期
**本模組回答的問題:**當我連線兩個 Salesforce 物件時,我真正在選擇的是什麼?
畫一個關係很容易。在第 2 章裡,我們畫了線並給它們起了名字:一個零售合作夥伴傳送很多份裝貨清單,一次配送載有很多個項目,配送小組和卡車在配送小組分配中相遇。我們討論了基數、可選性和歷史。現在我們要在 Salesforce 上實現這些線,而圖上的一條線開始承載多得多的分量。
當我在 Salesforce 上選擇一種關係類型時,我不只是在說**這兩條記錄是相連的。**我可能還在決定誰擁有子記錄,它能否在沒有父記錄的情況下存在,誰能看到它,刪除父記錄時會發生什麼,它能否移到另一個父記錄下,我能否把它彙總到父記錄上,以及當子記錄有幾十萬條時會發生什麼。關係不只是一條線,它承載著行為。
從業務關係開始
Section titled “從業務關係開始 ”在談查閱關係還是主要-詳細資料關係之前,回到業務。拿一次配送和它的配送項目來說:冰箱、安裝、拉走舊貨。一個項目能脫離它的配送而存在嗎?不能。如果配送被刪除,它的項目也應該一起刪除嗎?應該。這些項目需要自己的所有者或自己的安全設定嗎?其實不需要。會有人把一個項目從一次配送移到另一次配送嗎?但願不會是無意中的。
再看一次配送和它所在的路線。配送在被排上路線之前就存在,計劃變化時它可以被移到另一條路線上,而刪除一條路線永遠不應該刪除路線上的配送。兩條在圖上看起來一樣的一對多連線,行為卻完全不同。注意,我們仍然還沒有說「查閱關係」或「主要-詳細資料關係」。先描述行為,配置只是去實現它。
開啟新建欄位介面,Salesforce 會給你幾種關係類型(Object Relationships Overview (opens in a new tab),英文):
- 查閱關係(Lookup):連線兩個物件。Salesforce 關係裡的家常便飯。
- 主要-詳細資料關係(Master-detail):一種父子繫結,由父記錄控制子記錄。
- 多對多(Many-to-many):它本身不是一種欄位類型,而是一種模式:一個 Salesforce 交叉物件(Junction Object),即帶有兩個主要-詳細資料關係的自訂物件。
- 自關係(Self-relationship):從一個物件指向它自己的查閱關係。
- 層級關係(Hierarchical):一種只存在於 User 物件上的特殊查閱關係,比如一個使用者的經理。
- 外部查閱關係(External lookup)和間接查閱關係(Indirect lookup):與外部物件之間的關係,也就是模組 4 裡的
__x物件。外部查閱關係指向一個作為父物件的外部物件;間接查閱關係則從一個外部物件指向一個標準物件或自訂物件,按一個唯一的外部 ID 來比對。
你的設計時間大多花在前三種上。我們一個一個來看。
查閱關係:這些記錄是相連的
Section titled “查閱關係:這些記錄是相連的 ”查閱關係說的是:**這條記錄與那條記錄相關聯。**子記錄保留自己的身分、自己的所有人和自己的生命。一次配送指向它的路線。如果路線被取消了,配送不會消失;它們會回去重新排路線。
有意思的是:查閱欄位放在子記錄上,但父記錄也會得到一樣東西,即它的子記錄組成的相關清單。所以建立查閱關係時,要給兩端都起好名字。Related List Label(相關清單標籤)是人們在父記錄上看到的,Child Relationship Name(子關係名稱)是開發人員和整合從父記錄走到子記錄時使用的。不要接受預設值。
查閱關係可以是必需的,也可以是可選的。當它是可選的時,你要決定它所指向的記錄被刪除時會發生什麼,共有三種選擇(Considerations for Object Relationships (opens in a new tab),英文):
- 清空這個欄位的值,這是預設選項。子記錄保留下來,查閱欄位為空。
- 不允許刪除被查閱的記錄。試著刪除這條路線,Salesforce 會拒絕:它是某個關係的一部分。
- 同時刪除這條記錄,也就是級聯刪除,就像主要-詳細資料關係那樣。它只提供給自訂物件上的自訂查閱關係,預設是停用的,而且必須由 Salesforce 為你的 org 開啟,因為級聯刪除會繞過安全和共用:使用者能刪除他們根本看不到的記錄。
這是一個藏在設定介面裡的生命週期決定。
查閱篩選器會縮小使用者可以選擇的範圍。假設配送上有一個指向連絡人的 Installer(安裝人員)查閱關係,而安裝人員只是眾多連絡人記錄類型中的一種。查閱篩選器只顯示安裝人員,它可以按當前記錄、按被查閱的記錄,以及按使用者(他們的設定檔、角色或權限)來篩選(Lookup Filters (opens in a new tab),英文)。這是讓查閱關係保持誠實的一種便宜辦法。
主要-詳細資料關係:這條子記錄屬於那條父記錄
Section titled “主要-詳細資料關係:這條子記錄屬於那條父記錄 ”主要-詳細資料關係做出的宣告要強得多。我在課上把它叫作一種非常緊密的繫結。沒有主記錄就不能有從記錄;主記錄欄位是必需的。從記錄失去自己的所有人欄位,繼承其父記錄的所有人。從記錄沒有單獨的共用表,所以你不能單獨共用一條子記錄;它繼承父記錄的共用設定。這就是為什麼從物件不能有共用規則、手動共用或佇列:它們都需要一個所有人欄位(Object Relationships Overview (opens in a new tab),英文)。在設定中,它的共用設定顯示為 Controlled by Parent(由父項控制)。而在主要-詳細資料關係欄位本身上,你要選擇一個 Sharing Setting(共用設定):使用者需要對主記錄有隻讀還是讀/寫權限,才能建立、編輯或刪除它的從記錄。刪除主記錄會刪除它的從記錄。而且主記錄可以使用彙總摘要欄位。
所以如果配送項目是配送的從記錄,我就是在說:這個項目在它的整個生命週期中都屬於這次配送。這是我希望在任何人在設定中選擇「主要-詳細資料關係」之前就得到回答的問題。
這是我最喜歡的檢驗我們是否想清楚了的方法:**如果有人刪除了父記錄,子記錄應該怎樣?**每個人都會不自在。很好。現在我們是在做架構了。
一個零售合作夥伴有幾十萬條歷史配送。有人刪除了這個合作夥伴。這些配送應該消失嗎?幾乎肯定不應該:索賠、計費和歷史都依賴於它們。也許根本就不應該允許刪除合作夥伴,而應該把它停用。在主要-詳細資料關係中,刪除主記錄會級聯到從記錄及其從記錄;恢復主記錄會把它們一起恢復(Considerations for Object Relationships (opens in a new tab),英文)。所以當有人說「主要-詳細資料關係能給我們彙總摘要欄位」時,我的回答是:很好。你剛才還同意了什麼?
所有權會隨之而來
Section titled “所有權會隨之而來 ”在查閱關係中,子記錄可以有自己的所有者。在主要-詳細資料關係中則不能;存取權限跟隨主記錄。如果從記錄真的是父記錄的一部分,這完全正確。但如果子記錄需要自己的所有者、自己的共用或自己的生命週期,模型就在告訴你主要-詳細資料關係是錯誤的選擇。下一個模組會更深入地討論所有權,而 Sharing and Visibility 課程會講得更遠。現在請記住:**關係設計和安全設計不是兩場分開的對話。**在任何人寫下一條共用規則之前,資料模型就已經在塑造安全模型了。
父記錄必需,還是可選?
Section titled “父記錄必需,還是可選? ”子記錄能否在我們知道它的父記錄之前就存在?這比聽起來更重要。如果配送在前一天晚上隨裝貨清單到達,而路線是之後才建的,那麼在配送上把路線設為必需,就意味著必須先排好路線才能建立這條記錄。物理關係必須支撐真實的生命週期。所以我不會只憑一張靜態的圖來設計關係。我想知道:它們如何誕生,能否單獨存在,能否移動,又如何消亡?
子記錄能更換父記錄嗎?
Section titled “子記錄能更換父記錄嗎? ”預設情況下,主要-詳細資料關係中的子記錄不能移到另一個父記錄下。你可以通過在關係上選擇允許重設父級來允許這樣做(Considerations for Object Relationships (opens in a new tab),英文)。我的直覺是保守的:如果業務說子記錄終生屬於一個父記錄,我就不會讓移動它變得容易。一個項目從一次配送移到另一次配送,應該是一個有意的業務事件,而不是一次欄位編輯。同樣,設定本身不是架構。生命週期規則才是,設定只是去實現它。
還有兩件事會在後來讓團隊措手不及。你不能在一個已經有資料的物件上建立主要-詳細資料關係;你要先建立一個查閱關係,在每條記錄上填好值,然後再轉換它。而且只有當主記錄上沒有彙總摘要欄位時,才能把它轉換回查閱關係。還要留意轉換對安全的影響:把查閱關係變成主要-詳細資料關係,會把子物件的共用設定改為 Controlled by Parent;把主要-詳細資料關係變回查閱關係,會把子物件的組織範圍預設設定改為 Public Read/Write(公共讀/寫)(Considerations for Object Relationships (opens in a new tab),英文)。昨天還是私有的記錄,今天就敞開了,直到有人發現為止。早做選擇。
彙總摘要欄位很有用,但不是免費的
Section titled “彙總摘要欄位很有用,但不是免費的 ”我喜歡彙總摘要欄位。統計一次配送上的項目數,彙總一張發票上的行金額,找出最晚的日期:原生功能,無需程式碼。主要-詳細資料關係欄位放在子記錄上,彙總摘要欄位則放在父記錄上。不過它們有附加條款(Roll-Up Summary Field (opens in a new tab),英文):
- 在某些變更之後(新建彙總摘要欄位、修改它所依賴的公式、強制重新計算),計算彙總值可能需要長達 30 分鐘,取決於受影響的記錄數量。我見過有人納悶父記錄上的數字為什麼還沒變。
- 它們不能彙總所有東西。自動編號欄位不能作為被彙總的欄位。只有當一個公式欄位不跨到另一個物件、也不使用會自己變化的函式(比如
NOW()或TODAY())時,彙總摘要欄位才能彙總它。一個基於TODAY()的「逾期天數」公式每晚都在變,卻沒有任何人儲存記錄,所以彙總摘要欄位沒有可以據以重新計算的東西。這類數字需要一個計劃觸發的 Flow,或者一張報表。 - 篩選條件也有限制:不能用長文字區域、多選挑選清單、描述、Last Activity 這樣的系統欄位、跨物件公式或查閱欄位。
- 彙總摘要欄位不在編輯頁面上,所以驗證規則可以使用它,但不能在那裡顯示它的錯誤。
而且不要把決定倒過來做。不要說:「我們需要一個彙總摘要欄位,所以這必須是主要-詳細資料關係。」要說:「這條子記錄確實屬於這條父記錄,所有權和生命週期都契合,而好處之一是有原生的彙總摘要欄位。」如果語義不契合,就用別的方法解決計算問題。不要為了得到一個功能而扭曲資料模型。
那麼別的方法是什麼?你自己構建彙總:在父記錄上放一個儲存計算值的欄位,再用自動化讓它保持最新。假設零售合作夥伴是從配送出發的一個查閱關係,這本來就該如此,而業務希望在合作夥伴上看到「未完成配送數」(Open Deliveries)。在合作夥伴上加一個數字欄位 Open Deliveries。然後用一個記錄觸發的 Flow,或者在資料量或邏輯需要程式碼時用一個 Apex 觸發器,在每次配送變化時重新計算它。它可以跨查閱關係工作,可以按任何條件篩選,還可以使用原生彙總摘要欄位用不了的日期和公式。
但現在要把它做對就是你的事了,而這類方案正是在這裡出錯的。自動化必須在每一個重要的變化上觸發:新建子記錄、編輯子記錄、刪除子記錄、恢復子記錄,以及子記錄移到另一個父記錄下,這意味著舊父記錄和新父記錄都要重新計算。它必須能處理一次 200 條記錄的資料載入而不觸及限制。要重新計數,而不是加加減減,這樣漏掉一個事件也不會讓數字永遠錯下去。要準備一種把所有東西重新計算一遍的辦法,用於首次載入和數字出現偏差的那一天。還要記住,現在每一次儲存子記錄都會更新父記錄,所以一個有幾千條子記錄的父記錄會把我們馬上要講到的鎖定問題帶回來。原生彙總摘要欄位會替你做好這一切;自訂彙總則是一小段歸你維護的軟體。
深三層:疊加主要-詳細資料關係
Section titled “深三層:疊加主要-詳細資料關係 ”平台有它的形狀,而主要-詳細資料關係在兩個維度上體現這種形狀。第一個是深度。
你可以把主要-詳細資料關係疊加到三個自訂從級的深度,這就到底了(Considerations for Object Relationships (opens in a new tab),英文)。在課上,我會畫一個客戶和它的訂單(第一級),訂單和它的項目(第二級),項目和它們的明細(第三級),然後我試著加第四級,Salesforce 不讓我加。在 Steve Trucking 上它可能是這樣的:**配送(Delivery)是主記錄;它的配送項目(Delivery Item)是第一級;一個項目的安裝任務(Install Task)是第二級;每個任務的任務步驟(Task Step)**是第三級。第四級,比如步驟備註(Step Note),就只能是查閱關係了。
疊加時有幾條規則:
- **標準物件不能作為自訂物件的從物件。**自訂物件可以是客戶的從物件;客戶不能是你的自訂物件的從物件。
- **一個物件在多級疊加中只能出現一次。**Salesforce 不希望你繞回到自己身上:一個子從物件不能同時是它自己的主物件的主物件。
- **主記錄不能直接彙總最底層。**如果配送想要任務步驟的數量,就由安裝任務彙總它的步驟,配送項目彙總這些彙總值,配送再彙總項目:一次一級。
- **所有權和共用來自頂部。**每一級都繼承主記錄的所有人和存取權限。
- 刪除主記錄會刪除它下面的一切,恢復它會把一切都帶回來。
三層通常已經足夠。如果你的設計總想要第四層,就問一問:每一層是否真的終生屬於它上面的那一層。還要記住,哪一個連線來斷開這條鏈,是由你選擇的。第四級不一定非得是那個查閱關係:也許一個安裝任務並不真正屬於它的配送項目,它是單獨排期、單獨分派的,那麼這個連線就變成查閱關係,而安裝任務開始一條新鏈,下面是任務步驟和步驟備註。挑出子記錄真正有自己生命的那個連線,把它做成查閱關係。
現在安裝任務有了自己的所有人和自己的共用,刪除一次配送不會把它的安裝任務一起帶走,而且安裝任務下面還可以再有兩級。這就是取捨:鏈條更短了,而安裝任務的生命是它自己的。
寬兩個父物件:Salesforce 交叉物件
Section titled “寬兩個父物件:Salesforce 交叉物件 ”首先說說用詞,因為「交叉物件」有兩個意思,而這兩個我都教。
在第 2 章裡,我們找到了邏輯交叉物件:兩個關鍵概念的交匯處變成了一個獨立的東西,有它自己的屬性。一隻狗會很多技能,一個技能被很多隻狗掌握,而狗狗技能(Dog Trick)位於兩者之間,儲存著熟練程度和日期。這就是一個邏輯交叉物件,存在於邏輯模型中,遠在任何人決定用查閱關係還是主要-詳細資料關係之前。
Salesforce 對這個詞的用法更窄。當 Salesforce 說交叉物件時,它指的是一個帶有兩個主要-詳細資料關係的自訂物件(Create a Many-to-Many Object Relationship (opens in a new tab),英文)。我把它叫作 Salesforce 交叉物件。每個 Salesforce 交叉物件都是邏輯交叉物件,但並不是每個邏輯交叉物件都會變成 Salesforce 交叉物件:用一個主要-詳細資料關係加一個查閱關係,或者用兩個查閱關係來構建它,它仍然是邏輯交叉物件,只是不是 Salesforce 那一種。(Salesforce 自己也不完全一致:它的物件參考把一些基於查閱關係的標準物件也叫作「交叉物件」。考試時,按窄的定義來理解。)
考點。 Salesforce 交叉物件是一個帶有兩個主要-詳細資料關係的自訂物件,Salesforce 說「交叉物件」時指的就是它。邏輯交叉物件是更寬泛的建模概念:任何在多對多關係中連線另外兩個物件、並帶有自己屬性的物件,不管它是怎麼構建的。
第二個維度是寬度。一條子記錄能有兩個主要-詳細資料關係父物件嗎?能。三個呢?不能。每個自訂物件最多可以有兩個主要-詳細資料關係(Considerations for Object Relationships (opens in a new tab),英文)。兩個主要-詳細資料關係父物件,就是你為多對多關係構建 Salesforce 交叉物件的方式。配送小組和卡車在配送小組分配(Crew Assignment)中相遇,而正如我們在第 2 章發現的,它不是管道:它有日期、路線,也許還有狀態。交叉物件正是關係變成業務概念的地方。Salesforce 關於構建交叉物件的建議:給它起一個能說明它是什麼的名字,把它的記錄名稱設為自動編號,並把每個主物件的相關清單改名為另一個主物件的名字,這樣配送小組頁面顯示「卡車」,卡車頁面顯示「配送小組」(Create a Many-to-Many Object Relationship (opens in a new tab),英文)。
複雜之處在這裡。兩個父物件中有一個是主要父物件,就是你先建立的那個主要-詳細資料關係欄位所屬的父物件。介面上沒有任何視覺提示告訴你是哪一個,所以這是一道經典考題,也是一個經典的意外。
主要父物件決定什麼?三件事(Create a Many-to-Many Object Relationship (opens in a new tab),英文):
- **外觀。**交叉物件的頁面使用主要主物件的顏色和圖示。
- **所有人。**聯接記錄繼承主要主記錄的所有人。你永遠看不到它,因為從物件沒有所有人欄位;只有當你以後刪除了兩個主要-詳細資料關係時,它才有意義。
- 部門(Division),如果你的 org 使用部門的話,也是同樣的方式。
另一個就是次要父物件。它意味著什麼?
- **它是主要父物件的接班人。**刪除主要的主要-詳細資料關係欄位,或者把它轉換為查閱關係,次要父物件就會變成主要父物件。
- **它決定報表的範圍。**Salesforce 給你兩種報表類型:「Primary master with junction object and secondary master」(主要主物件、交叉物件和次要主物件)和「Secondary master with junction object and primary master」(次要主物件、交叉物件和主要主物件)。排在前面的主物件決定報表能顯示哪些記錄。
- 在存取權限上它同樣重要。我是這樣說的:所有權來自主要父物件,存取權限來自兩者,最嚴格的那個說了算。交叉物件和任何從物件一樣,沒有自己的共用表。Salesforce 會通過每個主要-詳細資料關係欄位上的共用設定,檢查使用者對兩條主記錄的存取權限。如果兩邊都設為讀/寫,使用者就需要對配送小組和卡車都有讀/寫權限,才能編輯這條配送小組分配(Considerations for Object Relationships (opens in a new tab),英文)。
- **在刪除上它同樣起作用。**刪除任何一個主記錄,配送小組或卡車,它的聯接記錄都會進入資源回收筒。兩個都刪除,它們就永久消失了。
還有幾條規則:兩個主物件都可以有來自交叉物件的彙總摘要欄位,交叉物件的公式和驗證規則可以引用兩個主物件上的欄位。但交叉物件不能作為其他任何東西的主物件,所以它不能位於疊加鏈條的中間;而且兩個主物件不能是同一個物件,一個物件與它自己的多對多關係需要另一種設計。另外,如果一個父記錄有超過 200 條聯接記錄,而交叉物件又彙總到另一個父物件上,那麼在你刪掉足夠多的聯接記錄之前,Salesforce 不會讓你刪除那個父記錄。
那麼,哪個父物件應該是主要父物件?先建立承載含義的那一個。對於配送小組分配,幹活的是配送小組,所以我會先建立配送小組。然後把它寫下來,因為介面上沒有任何東西會告訴下一個人。
說了這麼多,我最後用到的 Salesforce 交叉物件其實並不多。通常一個物件只有一個主要-詳細資料關係父物件,而且是同一類資料:客戶資料掛在客戶資料下,交易資料掛在交易資料下(記得第 2 章的資料種類:客戶資料、交易資料、參考資料)。當它的另一個父物件是另一類資料,通常是一個參考物件時,那個關係就是查閱關係。配送項目屬於它的配送:主要-詳細資料關係,兩者都是交易資料。它用查閱關係指向它所運送的產品,因為產品是有自己生命的參考資料,沒人希望刪除一個產品會把多年的配送歷史一起帶走。配送項目仍然是配送和其上產品之間的邏輯交叉物件;它只是不是 Salesforce 交叉物件。
自關係:當連線繞回自己
Section titled “自關係:當連線繞回自己 ”一個物件可以與自己關聯:一個上級客戶,一個經理,一個向區域樞紐彙報的配送中心。Salesforce 內建了兩個你幾乎在每個 org 裡都會遇到的自關係:客戶到客戶,即構建客戶層級的上級客戶(Parent Account)欄位;以及案例到案例,即模組 2 裡用來歸組相關案例的上級案例(Parent Case)。自關係必須是查閱關係,而且一條記錄不能指向它自己,儘管兩條記錄可以互相指向(Considerations for Object Relationships (opens in a new tab),英文)。在 User 物件上,它是一種獨立的特殊類型,即層級關係,用於一個使用者的經理這類場景。機制很簡單;命名才重要。一個從配送中心指向配送中心、叫作 Distribution_Center__c 的查閱關係對誰都沒有幫助。上級?備用?溢位?按角色給關係命名,而不是按它指向的物件命名。
層級關係:User 物件專屬的關係
Section titled “層級關係:User 物件專屬的關係 ”這個很小,而它正是那種鮮為人知、獨一無二、我預計考試會拿來出題的事實。層級關係是一種只存在於 User 物件上的特殊查閱關係。它把一個使用者連線到另一個使用者,而 Salesforce 不允許這條鏈繞回來:一個使用者不能直接或間接地指向自己(Object Relationships Overview (opens in a new tab),英文)。如果 Maria 的經理是 Dev,那麼 Dev 的經理就不能是 Maria,也不能是任何向上彙報到 Maria 的人。
這就是它和上面那些自關係的區別。在客戶或自訂物件上,兩條記錄可以互相指向。在 User 上,層級必須保持為層級。而且這是關聯 User 與 User 的唯一方式:系統不提供從 User 指向自己的普通查閱關係。
你已經有一個了。User 上的標準 Manager(經理)欄位就是一個層級關係,審批可以使用它:把這個請求發給提交人的經理。你也可以建立自己的層級關係,比如 Escalation Contact(升級連絡人)或 Backup Approver(備用審批人),審批也能以同樣的方式沿著它流轉(ApprovalProcess, Metadata API (opens in a new tab),英文)。不要把它和角色階層混為一談,後者決定記錄存取權限。層級欄位只是使用者之間的一個關係;它不共用任何一條記錄。
考點。 層級關係只存在於 User 物件上,比如標準的 Manager 欄位,而且一個使用者不能直接或間接地指向自己。它不是角色階層。
關係也有限制
Section titled “關係也有限制 ”每個物件最多可以有兩個主要-詳細資料關係。查閱關係欄位和主要-詳細資料關係欄位合在一起算作關係欄位:每個物件預設 40 個,申請後最多 50 個。彙總摘要欄位:每個物件預設 25 個,最多 40 個(Increase the Maximum Relationships Allowed per Object (opens in a new tab);Increase the Maximum Limit of Roll-Up Summary Fields (opens in a new tab),英文)。Salesforce 還補充說,提高任一項限制都可能影響效能。
你不需要按這些數字來設計;你需要在接近它們時有所察覺。一個掛著一個又一個關係的物件,正在告訴你一些事情。也許它確實就是那麼核心。也許是模型錯了。(第 18 章的餘量規則也適用:遠離限制,並以第三年的資料來衡量。)
一萬條子記錄的問題
Section titled “一萬條子記錄的問題 ”然後是子記錄太多的父記錄。Salesforce 自己的建議是,一個主要-詳細資料關係父記錄下的子記錄不要超過大約 10,000 條(Considerations for Object Relationships (opens in a new tab),英文),而它關於大規模記錄存取的指南對一般的父子關係也是這麼說的(Parent-Child Data Skew (opens in a new tab),英文)。第 10,001 條記錄不會讓 org 崩潰。但過了這個點,儲存一條子記錄可能會鎖住父記錄,而父記錄上的共用變更會波及每一條子記錄。
所以當我看到一個父記錄、數量巨大的子記錄時,我會問:為什麼它們都在同一個父記錄下?誰擁有它們?它們如何被查詢?哪些自動化會碰到父記錄?把所有配送都放在一個「Steve Trucking」客戶下面,幾天就會超過 10,000 條。一個無害的一對多關係變成了傾斜問題。下一個模組會預覽資料傾斜,第 2 部分會深入討論。
不要按功能來設計連線
Section titled “不要按功能來設計連線 ”這是我希望你從本模組養成的習慣。不要從「我需要一個彙總摘要欄位」、「我需要它是必需的」、「我想要繼承的共用」開始。這些是實現層面的線索。要從業務開始:子記錄有自己的生命嗎?誰擁有它?它能單獨存在嗎?能移動嗎?父記錄沒了會怎樣?關係本身承載資料嗎?每一邊能有多大?然後選擇能實現這些答案的關係。
**考試之外:AI 改變了什麼。**AI 可以在幾秒內提出關係。它無法告訴你業務是否會刪除父記錄。一旦幾百萬條記錄和幾十個自動化依賴於某個錯誤的關係,畫圖更快並不會讓逆轉它變得更便宜。
架構師在這裡決定什麼
Section titled “架構師在這裡決定什麼 ”- 子記錄是有自己的生命週期,還是真正屬於父記錄,以及所有權和存取權限應該是它自己的還是繼承的。
- 子記錄能否在沒有父記錄的情況下存在,能否在父記錄之間移動,能否在父記錄被刪除後繼續存在。
- 每個查閱關係在其父記錄被刪除時做什麼:清空、阻止,還是級聯刪除。
- 一個多對多關係是管道還是業務概念,邏輯交叉物件是否要變成 Salesforce 交叉物件,哪個父物件是主要父物件,以及兩個父物件對存取權限意味著什麼。
- 模型是否符合平台的形狀:深三個自訂從級,寬兩個主要-詳細資料關係父物件,以及關係和彙總摘要欄位的限制。
- 預期的子記錄數量和分佈是否會帶來傾斜風險,而這種風險是否應該改變設計。
關係是一組關於兩份資料如何一起表現的承諾。要有意識地做出這些承諾。
- Salesforce Help,Considerations for Object Relationships (opens in a new tab)(英文),查閱日期 2026-10-13。
- Salesforce Help,Object Relationships Overview (opens in a new tab) 和 Create a Many-to-Many Object Relationship (opens in a new tab)(英文),查閱日期 2026-10-13。
- Salesforce Help,Roll-Up Summary Field (opens in a new tab)(英文),查閱日期 2026-10-13。
- Salesforce Developers,Metadata API,ApprovalProcess (opens in a new tab)(英文),查閱日期 2026-10-13。
- Salesforce Help,Lookup Filters (opens in a new tab)(英文),查閱日期 2026-10-13。
- Salesforce Help,Increase the Maximum Relationships Allowed per Object (opens in a new tab) 和 Increase the Maximum Limit of Roll-Up Summary Fields (opens in a new tab)(英文),查閱日期 2026-10-02。
- Salesforce Developers,Designing Record Access for Enterprise Scale,Parent-Child Data Skew (opens in a new tab)(英文),查閱日期 2026-10-02。
