Ga naar inhoud

Relaties hebben gevolgen

Ook beschikbaar in 28 talen

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

A brick house with a glass room built onto its side, and a separate timber garden studio across the lawn, joined to it only by a stepping-stone path.
Afbeelding gegenereerd met AI

Module 7 van 10 in het hoofdstuk Salesforce-data-architectuur, hoofdstuk 3 van de cursus Data Architect. Elke module staat op zichzelf. Vorige: Velden zijn ook architectuur · Volgende: Eigenaarschap en levenscyclus

De vraag die deze module beantwoordt: Wat kies ik eigenlijk als ik twee Salesforce-objecten verbind?

Een relatie tekenen is makkelijk. In hoofdstuk 2 tekenden we lijnen en gaven ze namen: een retailpartner stuurt veel vrachtlijsten, een levering bevat veel items, ploegen en vrachtwagens ontmoeten elkaar in een ploegtoewijzing. We hadden het over kardinaliteit, optionaliteit en historie. Nu implementeren we die lijnen op Salesforce, en een lijn op een diagram gaat veel meer gewicht dragen.

Als ik op Salesforce een relatietype kies, zeg ik niet alleen deze twee records zijn verbonden. Ik beslis misschien ook wie eigenaar is van het child, of het zonder de parent kan bestaan, wie het kan zien, wat er gebeurt als de parent verwijderd wordt, of het naar een andere parent kan verhuizen, of ik het op de parent kan samenvatten, en wat er gebeurt als er honderdduizenden children zijn. Een relatie is niet alleen een lijn. Ze draagt gedrag.

Ga vóór lookup of master-detail terug naar de business. Neem een levering en haar leveringsitems, de koelkast, de installatie, de afvoer. Kan een item bestaan zonder zijn levering? Nee. Als de levering verwijderd wordt, moeten haar items dan ook weg? Ja. Hebben de items een eigen eigenaar of eigen beveiliging nodig? Niet echt. Moet iemand een item van de ene levering naar de andere verplaatsen? Hopelijk niet per ongeluk.

Neem nu een levering en de route waarop ze staat. De levering bestaat voordat ze ingepland is, ze kan naar een andere route verplaatst worden als de planning verandert, en het verwijderen van een route mag nooit de leveringen erop verwijderen. Twee een-op-veel-lijnen die er op een diagram hetzelfde uitzien, met totaal ander gedrag. Merk op dat we nog steeds geen “lookup” of “master-detail” hebben gezegd. Beschrijf eerst het gedrag. De configuratie implementeert het.

Open het scherm New Field en Salesforce biedt je een handvol relatietypes aan (Object Relationships Overview (opens in a new tab), Engels):

  • Lookup (opzoekrelatie): verbindt twee objecten. Het dagelijks brood van Salesforce-relaties.
  • Master-detail (hoofd-detail): een parent-childbinding waarbij de parent het child beheerst.
  • Veel-op-veel (many-to-many): geen eigen veldtype, maar een patroon: een Salesforce-koppelobject (Salesforce Junction Object), een aangepast object met twee master-detailrelaties.
  • Relatie met zichzelf (self-relationship): een lookup van een object naar zichzelf.
  • Hiërarchisch (hierarchical): een speciale lookup die alleen op het object User bestaat, zoals de manager van een gebruiker.
  • External lookup en indirect lookup: de relaties van en naar externe objecten, de __x-objecten uit module 4. Een external lookup verwijst naar een extern parent-object; een indirect lookup verwijst van een extern object naar een standaard- of aangepast object, gematcht op een unieke External ID.

De meeste ontwerptijd gaat naar de eerste drie. Laten we ze één voor één nemen.

Een lookup zegt: dit record is geassocieerd met dat record. Het child behoudt een eigen identiteit, een eigen eigenaar en een eigen leven. Een levering verwijst naar haar route. Als de route wordt geannuleerd, verdwijnen de leveringen niet; ze gaan terug om opnieuw ingepland te worden.

Het is grappig: het lookupveld staat op het child, maar de parent krijgt ook iets, een gerelateerde lijst (related list) met zijn children. Geef dus allebei de kanten een naam als je er een maakt. Het Related List Label is wat mensen op de parent zien, en de Child Relationship Name is wat developers en integraties gebruiken om van parent naar children te lopen. Accepteer de standaardwaarden niet.

Een lookup kan verplicht of optioneel zijn. Als hij optioneel is, beslis je wat er gebeurt als het record waarnaar hij verwijst verwijderd wordt, en er zijn drie keuzes (Considerations for Object Relationships (opens in a new tab), Engels):

  • Clear the value of this field (de waarde van dit veld leegmaken), de standaard. Het child blijft, met een lege lookup.
  • Don’t allow deletion (verwijdering niet toestaan) van het opgezochte record. Probeer de route te verwijderen, en Salesforce zegt nee: hij maakt deel uit van een relatie.
  • Delete this record also (dit record ook verwijderen), een trapsgewijze verwijdering (cascade delete), net als bij master-detail. Het wordt alleen aangeboden voor een aangepaste lookup op een aangepast object, het staat standaard uit, en Salesforce moet het voor je org aanzetten, omdat trapsgewijs verwijderen beveiliging en sharing omzeilt: gebruikers kunnen records verwijderen die ze niet eens konden zien.

Dat is een levenscyclusbeslissing die zich in een Setup-scherm verstopt.

Lookupfilters beperken wat een gebruiker kan kiezen. Stel dat Levering een lookup Installer naar Contact heeft, en installateurs zijn één recordtype van contactpersoon tussen vele. Een lookupfilter toont alleen installateurs, en kan filteren op het huidige record, op het record dat opgezocht wordt, en op de gebruiker: zijn profiel, rol of machtigingen (Lookup Filters (opens in a new tab), Engels). Het is een goedkope manier om een lookup eerlijk te houden.

Master-detail: dit child hoort bij die parent

Section titled “Master-detail: dit child hoort bij die parent ”

Master-detail doet een veel sterkere uitspraak. In de klas noem ik het een heel strakke binding. Je kunt geen detail hebben zonder zijn master; het masterveld is verplicht. Het detail verliest zijn eigen veld Owner en erft de eigenaar van zijn parent. Er is geen aparte sharetabel voor het detail, dus je kunt een child niet los delen; het erft de sharing van zijn parent. Daarom kan een detailobject geen deelregels, handmatige sharing of wachtrijen hebben: die hebben allemaal een veld Owner nodig (Object Relationships Overview (opens in a new tab), Engels). In Setup staat bij de sharinginstelling Controlled by Parent (beheerd door de parent). En op het master-detailveld zelf kies je een Sharing Setting: of een gebruiker Read Only- of Read/Write-toegang tot de master nodig heeft om de details te maken, te bewerken of te verwijderen. Het verwijderen van de master verwijdert zijn details. En de master krijgt samenvattingsvelden (roll-up summary).

Als een leveringsitem een detail van een levering is, zeg ik dus: dit item hoort zijn hele leven bij deze levering. Dat is de vraag die ik beantwoord wil hebben voordat iemand in Setup Master-Detail Relationship kiest.

Dit is mijn favoriete manier om te ontdekken of we het hebben doordacht: wat moet er met de children gebeuren als iemand de parent verwijdert? Iedereen voelt zich ongemakkelijk. Goed. Nu doen we aan architectuur.

Een retailpartner heeft honderdduizenden historische leveringen. Iemand verwijdert de partner. Moeten de leveringen verdwijnen? Vrijwel zeker niet: de claims, de facturering en de historie hangen er allemaal van af. Misschien mag een partner helemaal niet verwijderd worden, en moet hij in plaats daarvan gedeactiveerd worden. Bij master-detail loopt het verwijderen van de master door naar de details en hun details; het terughalen van de master brengt ze terug (Considerations for Object Relationships (opens in a new tab), Engels). Dus als iemand zegt “master-detail geeft ons samenvattingsvelden”, is mijn antwoord: mooi. Waar heb je verder nog mee ingestemd?

Bij een lookup kan het child een eigen eigenaar hebben. Bij master-detail niet; toegang volgt de master. Dat is precies goed als het detail echt deel van de parent is. Maar als het child een eigen eigenaar, eigen sharing of een eigen levenscyclus nodig heeft, vertelt het model je dat master-detail de verkeerde keuze is. De volgende module gaat dieper in op eigenaarschap, en de cursus Sharing and Visibility nog verder. Voor nu: relatieontwerp en beveiligingsontwerp zijn geen aparte gesprekken. Het datamodel vormt het beveiligingsmodel voordat iemand een deelregel schrijft.

Kan het child bestaan voordat we zijn parent kennen? Dat doet er meer toe dan het klinkt. Als leveringen de avond ervoor met de vrachtlijst binnenkomen en routes daarna worden gebouwd, zou een verplichte route op de levering betekenen dat de planning moet gebeuren voordat het record überhaupt gemaakt kan worden. De fysieke relatie moet de echte levenscyclus ondersteunen. Daarom ontwerp ik relaties niet alleen vanuit een statisch diagram. Ik wil weten: hoe worden ze geboren, kunnen ze alleen bestaan, kunnen ze verhuizen, en hoe sterven ze?

Standaard kan een master-detail-child niet naar een andere parent verplaatst worden. Je kunt het toestaan door Allow reparenting op de relatie aan te vinken (Considerations for Object Relationships (opens in a new tab), Engels). Mijn instinct is behoudend: als de business zegt dat het child zijn hele leven bij één parent hoort, maak ik verplaatsen niet makkelijk. Een item dat van de ene levering naar de andere gaat, moet een bewuste bedrijfsgebeurtenis zijn, geen veldwijziging. Ook hier is de instelling niet de architectuur. De levenscyclusregel is dat, en de instelling implementeert haar.

Nog twee dingen waar teams later tegenaan lopen. Je kunt geen hoofd-detailrelatie maken op een object dat al data heeft; je maakt een lookup, vult die op elk record en zet haar dan om. En je kunt alleen terug naar een lookup als er geen samenvattingsvelden op de master staan. Let ook op wat omzetten met de beveiliging doet: een lookup omzetten naar master-detail zet de sharing van het child op Controlled by Parent, en een master-detail terugzetten naar een lookup zet de organisatiebrede standaard van het child op Public Read/Write (Considerations for Object Relationships (opens in a new tab), Engels). Records die gisteren privé waren, staan vandaag open, tot iemand het merkt. Kies vroeg.

Samenvattingsvelden zijn nuttig, maar niet gratis

Section titled “Samenvattingsvelden zijn nuttig, maar niet gratis ”

Ik hou van samenvattingsvelden. Tel de items op een levering, tel de regelbedragen op een factuur op, vind de laatste datum: standaard, zonder code. Het master-detailveld staat op het child, maar het samenvattingsveld staat op de parent. Er horen wel kleine lettertjes bij (Roll-Up Summary Field (opens in a new tab), Engels):

  • Het berekenen van samenvattingswaarden na bepaalde wijzigingen (een nieuw samenvattingsveld, een gewijzigde formule waarvan het afhangt, een geforceerde herberekening) kan tot 30 minuten duren, afhankelijk van hoeveel records geraakt worden. Ik heb mensen zien afvragen waarom het getal op de parent nog niet veranderd was.
  • Ze kunnen niet alles samenvatten. Een automatisch nummer kan niet het veld zijn dat je aggregeert. En een samenvattingsveld kan een formuleveld alleen samenvatten als die formule niet naar een ander object reikt en geen functie gebruikt die vanzelf verandert, zoals NOW() of TODAY(). Een formule “dagen te laat” die op TODAY() gebouwd is, verandert elke nacht zonder dat iemand een record opslaat, dus er is niets waarvan het samenvattingsveld opnieuw kan rekenen. Zo’n getal heeft een geplande flow nodig, of een rapport.
  • Het filter heeft ook grenzen: geen lang tekstgebied, meervoudige keuzelijst, Description, systeemvelden zoals Last Activity, objectoverschrijdende formules of lookupvelden.
  • Samenvattingsvelden staan niet op bewerkpagina’s, dus een validatieregel kan er een gebruiken, maar zijn foutmelding daar niet tonen.

En draai de beslissing niet om. Zeg niet: “We hebben een samenvattingsveld nodig, dus dit moet master-detail zijn.” Zeg: “Dit child hoort echt bij deze parent, het eigenaarschap en de levenscyclus passen, en een van de voordelen is standaard samenvattingsvelden.” Als de betekenis niet past, los de berekening dan op een andere manier op. Verbuig het datamodel niet om een functie te krijgen.

Wat is dan die andere manier? Je bouwt het samenvattingsveld zelf: een veld op de parent dat de berekende waarde bevat, en automatisering die het actueel houdt. Stel dat retailpartner een lookup vanaf Levering is, zoals het hoort, en de business wil Open Deliveries op de partner. Voeg een getalveld Open Deliveries toe aan de partner. Dan berekent een record-triggered flow, of een Apex-trigger als het volume of de logica om code vraagt, het opnieuw zodra een levering verandert. Het werkt over een lookup, het kan op alles filteren, en het kan datums en formules gebruiken die een standaard samenvattingsveld niet kan.

Maar nu moet jij het goed krijgen, en daar gaan deze mis. De automatisering moet afgaan bij elke wijziging die ertoe doet: een nieuw child, een bewerkt child, een verwijderd child, een teruggezet child, en een child dat naar een andere parent verhuist, wat betekent dat zowel de oude als de nieuwe parent opnieuw berekend moet worden. Het moet een dataload van 200 records tegelijk aankunnen zonder limieten te raken. Tel opnieuw in plaats van op te tellen en af te trekken, zodat één gemiste gebeurtenis het getal niet voor altijd fout laat. Plan een manier om alles opnieuw te berekenen, voor de eerste load en voor de dag dat het gaat afwijken. En onthoud dat elke keer dat een child opgeslagen wordt nu de parent bijwerkt, dus een parent met duizenden children brengt de locking terug die we zo meteen zien. Een standaard samenvattingsveld doet dat allemaal voor je; een eigen samenvattingsveld is een klein stukje software waarvan jij eigenaar bent.

Drie niveaus diep: master-details stapelen

Section titled “Drie niveaus diep: master-details stapelen ”

Het platform heeft een vorm, en master-detail heeft daarvan twee dimensies. De eerste is diepte.

Je kunt master-details drie aangepaste detailniveaus diep stapelen, en dan houdt het op (Considerations for Object Relationships (opens in a new tab), Engels). In de klas teken ik het als een account met een order (één), de order met zijn items (twee), en de items met hun details (drie), en dan probeer ik een vierde toe te voegen en Salesforce laat me niet. Bij Steve Trucking zou het er zo uit kunnen zien: een levering (Delivery) is de master; haar leveringsitems (Delivery Items) zijn het eerste niveau; de installatietaken (Install Tasks) van een item zijn het tweede; en de taakstappen (Task Steps) van elke taak zijn het derde. Een vierde niveau, zeg een stapnotitie (Step Note), moet een lookup zijn.

Drie niveaus master-detail Drie gestapelde master-detailrelaties bij Steve Trucking, getekend als dikke lijnen. Levering is de master. Leveringsitem is detailniveau 1, installatietaak is niveau 2, en taakstap is niveau 3. Stapnotitie hangt aan taakstap met een dunne lookuplijn, omdat een vierde niveau een lookup moet zijn. Onderaan: eigenaarschap, sharing en verwijdering stromen van de levering naar elk niveau. niveau 1 niveau 2 niveau 3 een vierde niveau is een lookup Levering Delivery__c · master Leveringsitem Delivery_Item__c Installatietaak Install_Task__c Taakstap Task_Step__c Stapnotitie Step_Note__c Eigenaarschap, sharing en verwijdering stromen van de levering naar elk niveau. precies één nul of één één of veel nul of veel hoofd-detail opzoeken © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Bij de stapel horen een paar regels:

  • Standaardobjecten kunnen niet aan de detailkant van een aangepast object staan. Een aangepast object kan een detail van Account zijn; Account kan geen detail van het jouwe zijn.
  • Een object mag maar één keer voorkomen in een stapel van meerdere niveaus. Salesforce wil niet dat je op jezelf terugloopt: een subdetail kan niet ook de master van zijn eigen master zijn.
  • De master kan het onderste niveau niet rechtstreeks samenvatten. Als Levering het aantal taakstappen wil, vat installatietaak zijn stappen samen, vat leveringsitem die samenvattingen samen, en vat levering de items samen: niveau voor niveau.
  • Eigenaarschap en sharing komen van boven. Elk niveau erft de eigenaar en de toegang van de master.
  • De master verwijderen verwijdert alles eronder, en hem terugzetten brengt alles terug.

Drie niveaus is meestal ruim genoeg. Als je ontwerp steeds een vierde wil, vraag dan of elk niveau echt zijn hele leven bij het niveau erboven hoort. En onthoud dat jij mag kiezen welke schakel de keten breekt. Het vierde niveau hoeft niet de lookup te zijn: misschien hoort een installatietaak niet echt bij zijn leveringsitem, hij wordt los ingepland en toegewezen, dus wordt die schakel een lookup, en nu begint installatietaak een nieuwe keten met taakstap en stapnotitie eronder. Kies de schakel waar het child echt een eigen leven heeft, en maak dat de lookup.

De keten breken met een lookup Dezelfde vijf objecten van Steve Trucking als in de stapel van drie niveaus, met een lookup in het midden. Levering is een master, met leveringsitem als detail op een dikke master-detaillijn. Leveringsitem linkt naar installatietaak met een dunne lookuplijn die de keten breekt. Installatietaak is een nieuwe master: taakstap is het detail ervan, en stapnotitie is het detail van taakstap, allebei op dikke master-detaillijnen. Onderaan: installatietaak heeft nu een eigen eigenaar en sharing, en een levering verwijderen verwijdert haar installatietaken niet meer. niveau 1 een lookup breekt de keten niveau 1 niveau 2 Levering Delivery__c · master Leveringsitem Delivery_Item__c Installatietaak Install_Task__c · een nieuwe master Taakstap Task_Step__c Stapnotitie Step_Note__c Installatietaak heeft nu een eigen eigenaar en sharing, en een levering verwijderen verwijdert haar installatietaken niet meer. precies één nul of één één of veel nul of veel hoofd-detail opzoeken © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Nu heeft installatietaak een eigen eigenaar en eigen sharing, kan een levering verwijderd worden zonder haar installatietaken mee te nemen, en kan installatietaak nog twee niveaus onder zich hebben. Dat is de ruil: de keten is korter, en het leven van de installatietaak is van hemzelf.

Twee parents breed: het Salesforce-koppelobject

Section titled “Twee parents breed: het Salesforce-koppelobject ”

Eerst een woord over woorden, want “koppelobject” (junction object) betekent twee dingen, en ik leer ze allebei.

In hoofdstuk 2 vonden we het logische koppelobject: de verbinding tussen twee kernideeën die een eigen ding wordt, met eigen attributen. Een hond kent veel kunstjes, een kunstje wordt door veel honden gekend, en Hondkunstje staat ertussen met het vaardigheidsniveau en de datum. Dat is een logisch koppelobject, in het logische model, lang voordat iemand kiest tussen lookup en master-detail.

Salesforce gebruikt de term nauwer. Als Salesforce junction object zegt, bedoelt het een aangepast object met twee master-detailrelaties (Create a Many-to-Many Object Relationship (opens in a new tab), Engels). Dat noem ik een Salesforce-koppelobject (Salesforce Junction Object). Elk Salesforce-koppelobject is een logisch koppelobject, maar niet elk logisch koppelobject wordt een Salesforce-koppelobject: bouw er een met een master-detail en een lookup, of met twee lookups, en het is nog steeds een logisch koppelobject, alleen niet de Salesforce-soort. (Salesforce is zelf niet helemaal consequent: de eigen objectreferentie noemt sommige standaardobjecten die op lookups gebouwd zijn “junction objects”. Ga op het examen uit van de nauwe definitie.)

Examenkennis. Een Salesforce-koppelobject (Salesforce Junction Object) is een aangepast object met twee master-detailrelaties, en dat bedoelt Salesforce als het “junction object” zegt. Het logische koppelobject is het bredere modelleeridee: elk object dat twee andere verbindt in een veel-op-veel en eigen attributen draagt, hoe het ook gebouwd is.

De tweede dimensie is breedte. Kan een child twee master-detail-parents hebben? Ja. Drie? Nee. Elk aangepast object kan hooguit twee master-detailrelaties hebben (Considerations for Object Relationships (opens in a new tab), Engels). Twee master-detail-parents is hoe je een Salesforce-koppelobject bouwt voor een veel-op-veel. Bezorgploeg en vrachtwagen ontmoeten elkaar in een ploegtoewijzing (Crew Assignment), en zoals we in hoofdstuk 2 zagen, is dat geen leidingwerk: het heeft een datum, een route, misschien een status. Het koppelobject is waar de relatie een bedrijfsconcept wordt. De tips van Salesforce om er een te bouwen: geef het een naam die zegt wat het is, maak de recordnaam een automatisch nummer, en hernoem de gerelateerde lijst van elke master naar de andere master, zodat de pagina van de ploeg “Trucks” toont en de pagina van de vrachtwagen “Crews” (Create a Many-to-Many Object Relationship (opens in a new tab)).

Hier zit de finesse. Een van de twee parents is de primaire, en dat is degene waarvan je het master-detailveld als eerste hebt gemaakt. Er is geen visuele aanwijzing welke dat is, dus het is een klassieke examenvraag, en een klassieke verrassing.

Wat bepaalt de primaire? Drie dingen (Create a Many-to-Many Object Relationship (opens in a new tab), Engels):

  • Uiterlijk. De pagina’s van het koppelobject gebruiken de kleur en het pictogram van de primaire master.
  • Eigenaar. De records van het koppelobject erven de eigenaar van het primaire masterrecord. Je ziet het nooit, omdat een detail geen veld Owner heeft; het doet er alleen toe als je later beide master-detailrelaties verwijdert.
  • Divisie (Division), als je org divisies gebruikt, op dezelfde manier.

En de andere is de secundaire. Wat betekent dat?

  • Hij staat klaar om primair te worden. Verwijder het primaire master-detailveld of zet het om naar een lookup, en de secundaire wordt de primaire.
  • Hij bepaalt de reikwijdte van de rapporten. Salesforce geeft je twee rapporttypes: “Primary master with junction object and secondary master” en “Secondary master with junction object and primary master”. De master die als eerste genoemd wordt, bepaalt welke records het rapport kan tonen.
  • Hij telt net zo zwaar voor toegang. Zo zeg ik het: eigenaarschap van de primaire, toegang van allebei, en de strengste wint. Een koppelobject heeft, zoals elk detail, geen eigen sharetabel. Salesforce controleert de toegang van de gebruiker tot beide masterrecords, via de Sharing Setting op elk master-detailveld. Als beide op Read/Write staan, heeft de gebruiker Read/Write nodig op de ploeg en op de vrachtwagen om de ploegtoewijzing te bewerken (Considerations for Object Relationships (opens in a new tab), Engels).
  • Hij verwijdert net zo goed. Verwijder een van beide masters, de ploeg of de vrachtwagen, en de bijbehorende koppelrecords gaan naar de prullenbak (Recycle Bin). Verwijder ze allebei en ze zijn voorgoed weg.
De primaire en secundaire parent van een koppelobject Een koppelobject onder zijn twee master-detail-parents, getekend met dikke lijnen. Ploeg, linksboven, is de primaire, omdat het master-detailveld ervan als eerste gemaakt werd; die geeft de ploegtoewijzing haar eigenaar en haar uiterlijk. Vrachtwagen, rechtsboven, is de secundaire; die bepaalt de reikwijdte van het tweede rapporttype en wordt primair als de eerste relatie verwijderd wordt. Ploegtoewijzing staat tussen en onder hen. Onderaan: toegang vraagt om beide parents, en de strengste wint; verwijder een van beide parents en de toewijzing verdwijnt ook. eigenaar en uiterlijk rapportbereik Ploeg Crew__c · primair: als eerste gemaakt Vrachtwagen Truck__c · secundair Ploegtoewijzing Crew_Assignment__c Toegang vraagt om beide parents: de strengste wint. Verwijder een van beide parents en de toewijzing verdwijnt ook. precies één nul of één één of veel nul of veel hoofd-detail © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Nog een paar regels: beide masters kunnen samenvattingsvelden van het koppelobject hebben, en de formules en validatieregels van het koppelobject kunnen velden op allebei bereiken. Maar een koppelobject kan zelf geen master zijn van iets anders, dus het kan niet in het midden van een stapel staan, en de twee masters kunnen niet hetzelfde object zijn; een veel-op-veel van een object naar zichzelf vraagt om een ander ontwerp. En als een parent meer dan 200 koppelrecords heeft en het koppelobject naar de andere parent samenvat, laat Salesforce je die parent pas verwijderen als je er genoeg hebt weggehaald.

Dus: welke parent moet primair zijn? Maak eerst degene die de betekenis bezit. Bij een ploegtoewijzing doet de ploeg het werk, dus ik zou Bezorgploeg eerst maken. En schrijf het dan op, want niets op het scherm zal het de volgende persoon vertellen.

Dat gezegd hebbende, eindig ik niet met veel Salesforce-koppelobjecten. Meestal heeft een object één master-detail-parent, en die is van dezelfde soort data: klantgegevens onder klantgegevens, transactioneel onder transactioneel (denk aan de soorten data uit hoofdstuk 2: klant, transactie, referentie). Als zijn andere parent van een andere soort is, meestal een referentie-object, dan is die relatie een lookup. Een leveringsitem hoort bij zijn levering: master-detail, allebei transactioneel. Het verwijst met een lookup naar het product dat het vervoert, omdat een product referentiegegevens zijn met een eigen leven, en niemand wil dat het verwijderen van een product jaren leveringshistorie meeneemt. Leveringsitem is nog steeds een logisch koppelobject tussen een levering en de producten erop; het is alleen geen Salesforce-koppelobject.

Relaties met zichzelf: als de lijn terugkomt

Section titled “Relaties met zichzelf: als de lijn terugkomt ”

Een object kan aan zichzelf gerelateerd zijn: een parent-account, een manager, een distributiecentrum dat rapporteert aan een regionale hub. Salesforce bouwt er twee in die je in bijna elke org tegenkomt: Account naar Account, het veld Parent Account dat de accounthiërarchie bouwt, en Case naar Case, de Parent Case uit module 2 die gerelateerde cases groepeert. Een relatie met zichzelf moet een lookup zijn, en een record kan niet naar zichzelf verwijzen, al kunnen twee records wel naar elkaar verwijzen (Considerations for Object Relationships (opens in a new tab), Engels). Op het object User is het een eigen speciaal type, de hiërarchische relatie, gebruikt voor dingen als de manager van een gebruiker. Het mechaniek is makkelijk; de naamgeving doet ertoe. Een lookup van Distributiecentrum naar Distributiecentrum die Distribution_Center__c heet, helpt niemand. Parent? Back-up? Overloop? Noem de relatie naar de rol, niet naar het object waarnaar ze verwijst.

Relaties met zichzelf Drie objecten, elk met een lookup naar zichzelf. Account wijst via zijn veld ParentId naar een parent-account, wat de accounthiërarchie opbouwt. Case wijst via zijn veld ParentId naar een parent-case. Distributiecentrum, een aangepast object, wijst naar zijn regionale hub via een veld met de naam Regional_Hub__c. Onderaan: altijd een lookup, nooit naar hetzelfde record, en genoemd naar de rol die hij speelt. parent account parent case regionale hub Account Account · ParentId Case Case · ParentId Distributiecentrum Distribution_Center__c · Regional_Hub__c Altijd een lookup, nooit naar hetzelfde record, en genoemd naar de rol die hij speelt. precies één nul of één één of veel nul of veel opzoeken © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Hiërarchisch: de eigen relatie van het object User

Section titled “Hiërarchisch: de eigen relatie van het object User ”

Deze is klein, en het is precies het soort weinig bekende, unieke feitje waar ik een examen op zou verwachten. Hiërarchisch (hierarchical) is een speciale lookup die alleen op het object User bestaat. Hij verbindt de ene gebruiker met een andere gebruiker, en Salesforce laat de keten niet teruglopen: een gebruiker kan niet naar zichzelf verwijzen, direct of indirect (Object Relationships Overview (opens in a new tab), Engels). Als de manager van Maria Dev is, kan de manager van Dev niet Maria zijn, of iemand die via de lijn aan Maria rapporteert.

Dat is het verschil met de relaties met zichzelf hierboven. Op Account of een aangepast object kunnen twee records naar elkaar verwijzen. Op User moet de hiërarchie een hiërarchie blijven. En het is de enige manier om User aan User te relateren: een gewone lookup van User naar zichzelf wordt niet aangeboden.

Je hebt er al een. Het standaardveld Manager op User is een hiërarchische relatie, en goedkeuringen kunnen hem gebruiken: stuur dit verzoek naar de manager van de indiener. Je kunt ook je eigen maken, zeg een escalatiecontact of een vervangende goedkeurder, en een goedkeuring kan er op dezelfde manier langs lopen (ApprovalProcess, Metadata API (opens in a new tab), Engels). Verwar het niet met de rolhiërarchie, die de toegang tot records stuurt. Een hiërarchisch veld is alleen een relatie tussen gebruikers; het deelt geen enkel record.

Examenkennis. De hiërarchische relatie bestaat alleen op het object User, zoals het standaardveld Manager, en een gebruiker kan niet naar zichzelf verwijzen, direct of indirect. Het is niet de rolhiërarchie.

Elk object kan hooguit twee hoofd-detailrelaties hebben. Lookup- en master-detailvelden tellen samen als relatievelden: standaard 40 per object, op verzoek hooguit 50. Samenvattingsvelden: standaard 25 per object, hooguit 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), Engels). Salesforce voegt eraan toe dat het verhogen van een van beide limieten de prestaties kan beïnvloeden.

Je hoeft niet op die getallen te ontwerpen; je moet merken wanneer je er dichtbij komt. Een object waaraan relatie na relatie hangt, vertelt je iets. Misschien is het echt zo centraal. Of misschien klopt het model niet. (En de vuistregel voor speelruimte uit hoofdstuk 18 geldt: blijf ruim onder een limiet, gemeten tegen jaar drie.)

Dan is er de parent met te veel children. De eigen richtlijn van Salesforce is niet meer dan ongeveer 10.000 child-records voor één master-detail-parent (Considerations for Object Relationships (opens in a new tab)), en de gids over recordtoegang op schaal zegt hetzelfde voor parent-childrelaties in het algemeen (Parent-Child Data Skew (opens in a new tab), Engels). Record 10.001 maakt de org niet kapot. Maar voorbij dat punt kan het opslaan van een child de parent vergrendelen, en sharingwijzigingen op de parent werken door in elk child.

Dus als ik één parent met enorme aantallen children zie, vraag ik: waarom staan ze allemaal onder dezelfde parent, wie is er eigenaar van, hoe worden ze bevraagd, en welke automatisering raakt de parent? Elke levering onder één account “Steve Trucking” zou binnen een paar dagen over de 10.000 gaan. Een onschuldige een-op-veel wordt een skewprobleem. De volgende module geeft een voorproefje van skew, en deel 2 gaat er diep op in.

Ontwerp de lijn niet op basis van een functie

Section titled “Ontwerp de lijn niet op basis van een functie ”

Dit is de gewoonte die ik uit deze module wil meegeven. Begin niet bij “ik heb een samenvattingsveld nodig”, “ik wil het verplicht”, “ik wil geërfde sharing”. Dat zijn aanwijzingen voor de implementatie. Begin bij de business: heeft het child een eigen leven, wie is eigenaar, kan het alleen bestaan, kan het verhuizen, wat gebeurt er als de parent verdwijnt, draagt de relatie data, en hoe groot kan elke kant worden? Kies dan de relatie die de antwoorden implementeert.

Lookup, master-detail of koppelobject? Een matrix van drie relatiepatronen tegenover zes bedrijfsvragen. Een lookup: het child kan alleen bestaan, heeft een eigen eigenaar, kan van parent wisselen, en kan meer dan 10.000 children per parent aan, al moet je nog op skew letten; het gaat standaard niet mee met de parent (het veld wordt leeggemaakt of het verwijderen wordt geblokkeerd) en bevat één parent per veld. Het betekent verbonden. Een master-detail: de parent is verplicht, het child erft de eigenaar van de parent, het wordt trapsgewijs met de parent verwijderd, het wisselt alleen van parent als reparenting is toegestaan, en meer dan 10.000 children brengt parent-locks en herberekening mee. Het betekent hoort bij. Een Salesforce-koppelobject (Salesforce Junction Object): het heeft beide parents nodig, krijgt zijn eigenaar van de primaire, wordt met elk van beide parents verwijderd, en is het enige patroon voor veel aan beide kanten. Het betekent een bedrijfsconcept. Onderaan: beantwoord eerst de bedrijfsvragen; het relatietype volgt. BESTAAT ALLEEN EIGEN EIGENAAR GAAT MEE MET PARENT WISSELT VAN PARENT VEEL AAN BEIDE KANTEN 10.000+ PER PARENT HET BETEKENT Lookup Levering → Route standaard leegmaken of blokkeren één parent per veld let nog op skew VERBONDEN Master-detail Levering → Leveringsitem parent verplicht erft die van de parent trapsgewijs verwijderen alleen met reparenting aan één master per veld parent-locks, herberekeningen HOORT BIJ Salesforce-koppelobject Ploeg + vrachtwagen → Ploegtoewijzing heeft beide parents nodig van de primaire elke parent verwijdert het alleen met reparenting aan daar is het voor zelfde 10.000-richtlijn EEN BEDRIJFSCONCEPT Beantwoord eerst de bedrijfsvragen. Het relatietype volgt; begin niet bij de functie die je wilt. © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Voorbij het examen: wat AI verandert. AI kan in seconden relaties voorstellen. Het kan je niet vertellen of de business de parent ooit gaat verwijderen. Sneller diagrammen maken maakt een verkeerde relatie niet goedkoper om terug te draaien zodra miljoenen records en tientallen automatiseringen ervan afhangen.

  • Of het child een eigen levenscyclus heeft of echt bij de parent hoort, en of eigenaarschap en toegang eigen of geërfd moeten zijn.
  • Of het child zonder parent kan bestaan, tussen parents kan verhuizen, of de verwijdering van de parent kan overleven.
  • Wat elke lookup doet als zijn parent verwijderd wordt: leegmaken, blokkeren of trapsgewijs verwijderen.
  • Of een veel-op-veel leidingwerk is of een bedrijfsconcept, of het logische koppelobject een Salesforce-koppelobject wordt, welke parent de primaire is, en wat beide parents betekenen voor toegang.
  • Of het model past bij de vorm van het platform: drie aangepaste detailniveaus diep, twee master-detail-parents breed, de limieten voor relaties en samenvattingsvelden.
  • Of het verwachte aantal en de verdeling van children een skewrisico oplevert dat het ontwerp zou moeten veranderen.

Een relatie is een reeks beloften over hoe twee stukken data zich samen gedragen. Doe ze bewust.