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)

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.
Begin bij de bedrijfsrelatie
Section titled “Begin bij de bedrijfsrelatie ”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.
De relatietypes
Section titled “De relatietypes ”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.
Lookup: deze records zijn verbonden
Section titled “Lookup: deze records zijn verbonden ”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.
De verwijdervraag
Section titled “De verwijdervraag ”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?
Eigenaarschap reist mee
Section titled “Eigenaarschap reist mee ”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.
Verplichte parent, of optioneel?
Section titled “Verplichte parent, of optioneel? ”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?
Kan het child van parent wisselen?
Section titled “Kan het child van parent wisselen? ”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()ofTODAY(). Een formule “dagen te laat” die opTODAY()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.
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.
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.
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.
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.
Relaties hebben ook limieten
Section titled “Relaties hebben ook limieten ”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.)
De vraag van de 10.000 children
Section titled “De vraag van de 10.000 children ”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.
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.
Wat een architect hier beslist
Section titled “Wat een architect hier beslist ”- 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.
Verder lezen
Section titled “Verder lezen ”- Salesforce Help, Considerations for Object Relationships (opens in a new tab) (Engels, gecontroleerd op 2026-10-13)
- Salesforce Help, Object Relationships Overview (opens in a new tab) en Create a Many-to-Many Object Relationship (opens in a new tab) (Engels, gecontroleerd op 2026-10-13)
- Salesforce Help, Roll-Up Summary Field (opens in a new tab) (Engels, gecontroleerd op 2026-10-13)
- Salesforce Developers, Metadata API, ApprovalProcess (opens in a new tab) (Engels, gecontroleerd op 2026-10-13)
- Salesforce Help, Lookup Filters (opens in a new tab) (Engels, gecontroleerd op 2026-10-13)
- Salesforce Help, Increase the Maximum Relationships Allowed per Object (opens in a new tab) en Increase the Maximum Limit of Roll-Up Summary Fields (opens in a new tab) (Engels, gecontroleerd op 2026-10-02)
- Salesforce Developers, Designing Record Access for Enterprise Scale, Parent-Child Data Skew (opens in a new tab) (Engels, gecontroleerd op 2026-10-02)
