Skip to content

Relationships Have Consequences

Also in 28 languages

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 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.
Image generated with AI

Module 7 of 10 in the chapter Salesforce Data Architecture, chapter 3 of the Data Architect course. Each module stands on its own. Previous: Fields Are Architecture Too · Next: Ownership and Lifecycle

The question this module answers: What am I really choosing when I connect two Salesforce objects?

Drawing a relationship is easy. In chapter 2 we drew lines and named them: a Retail Partner sends many manifests, a delivery carries many items, crews and trucks meet in a Crew Assignment. We talked about cardinality, optionality and history. Now we implement those lines on Salesforce, and a line on a diagram starts carrying a lot more weight.

When I choose a relationship type on Salesforce, I’m not just saying these two records are connected. I may also be deciding who owns the child, whether it can exist without the parent, who can see it, what happens when the parent is deleted, whether it can move to another parent, whether I can summarize it onto the parent, and what happens when there are hundreds of thousands of children. A relationship isn’t just a line. It carries behavior.

Before lookup or master-detail, go back to the business. Take a Delivery and its Delivery Items, the refrigerator, the install, the haul-away. Can an item exist without its delivery? No. If the delivery is deleted, should its items go too? Yes. Do the items need their own owner or their own security? Not really. Should anyone move an item from one delivery to another? Hopefully not by accident.

Now take a Delivery and the Route it’s on. The delivery exists before it’s routed, it can be moved to another route when the plan changes, and deleting a route should never delete the deliveries on it. Two one-to-many lines that look the same on a diagram, with completely different behavior. Notice we still haven’t said “lookup” or “master-detail.” Describe the behavior first. The configuration implements it.

Open the New Field screen and Salesforce offers you a handful of relationship types (Object Relationships Overview (opens in a new tab)):

  • Lookup: links two objects. The meat and potatoes of Salesforce relationships.
  • Master-detail: a parent-child binding where the parent controls the child.
  • Many-to-many: not a field type of its own, but a pattern: a Salesforce Junction Object, a custom object with two master-details.
  • Self-relationship: a lookup from an object to itself.
  • Hierarchical: a special lookup that exists only on the User object, such as a user’s manager.
  • External lookup and indirect lookup: the relationships to and from external objects, the __x objects from module 4. An external lookup points to a parent external object; an indirect lookup points from an external object to a standard or custom object, matched on a unique External ID.

Most of your design time goes to the first three. Let’s take them one at a time.

A lookup says: this record is associated with that record. The child keeps its own identity, its own owner and its own life. A Delivery points to its Route. If the route is cancelled, the deliveries don’t vanish; they go back to be routed again.

It’s funny: the lookup field goes on the child, but the parent gets something too, a related list of its children. So when you create one, name both ends. The Related List Label is what people see on the parent, and the Child Relationship Name is what developers and integrations use to walk from parent to children. Don’t accept the defaults.

A lookup can be required or optional. When it’s optional, you decide what happens if the record it points to is deleted, and there are three choices (Considerations for Object Relationships (opens in a new tab)):

  • Clear the value of this field, the default. The child stays, with an empty lookup.
  • Don’t allow deletion of the lookup record. Try to delete the route, and Salesforce says no: it’s part of a relationship.
  • Delete this record also, a cascade delete, like a master-detail. It’s only offered for a custom lookup on a custom object, it’s disabled by default, and Salesforce has to turn it on for your org, because a cascade delete bypasses security and sharing: users can delete records they couldn’t even see.

That’s a lifecycle decision hiding in a setup screen.

Lookup filters narrow what a user can pick. Say Delivery has an Installer lookup to Contact, and installers are one record type of contact among many. A lookup filter shows only installers, and it can filter on the current record, on the record being looked up, and on the user: their profile, role or permissions (Lookup Filters (opens in a new tab)). It’s a cheap way to keep a lookup honest.

Master-Detail: This Child Belongs to That Parent

Section titled “Master-Detail: This Child Belongs to That Parent”

Master-detail makes a much stronger statement. In class I call it a very tight binding. You can’t have a detail without its master; the master field is required. The detail loses its own Owner field and inherits the owner of its parent. There’s no separate share table for the detail, so you can’t share a child on its own; it inherits its parent’s sharing. That’s why a detail object can’t have sharing rules, manual sharing or queues: they all need an Owner field (Object Relationships Overview (opens in a new tab)). In Setup its sharing setting reads Controlled by Parent. And on the master-detail field itself you choose a Sharing Setting: whether a user needs Read Only or Read/Write access to the master to create, edit or delete its details. Deleting the master deletes its details. And the master gets roll-up summary fields.

So if Delivery Item is a detail of Delivery, I’m saying: this item belongs to this delivery for its whole life. That’s the question I want answered before anyone picks Master-Detail Relationship in Setup.

Here’s my favorite way to find out whether we’ve thought it through: what should happen to the children if somebody deletes the parent? Everybody gets uncomfortable. Good. Now we’re doing architecture.

A Retail Partner has hundreds of thousands of historical deliveries. Somebody deletes the partner. Should the deliveries disappear? Almost certainly not: the claims, the billing and the history all depend on them. Maybe deleting a partner shouldn’t be allowed at all, and the partner should be deactivated instead. With master-detail, deleting the master cascades to the details and their details; undeleting the master brings them back (Considerations for Object Relationships (opens in a new tab)). So when somebody says “master-detail gives us roll-ups,” my answer is: great. What else did you just agree to?

With a lookup, the child can have its own owner. With master-detail, it can’t; access follows the master. That’s exactly right if the detail really is part of the parent. But if the child needs its own owner, its own sharing or its own lifecycle, the model is telling you master-detail is the wrong choice. The next module goes deeper into ownership, and the Sharing and Visibility course goes further still. For now: relationship design and security design aren’t separate conversations. The data model shapes the security model before anyone writes a sharing rule.

Can the child exist before we know its parent? It matters more than it sounds. If deliveries arrive on the manifest the night before and routes are built afterwards, a required Route on Delivery would mean routing has to happen before the record can even be created. The physical relationship has to support the real lifecycle. So I don’t design relationships from a static diagram alone. I want to know: how are they born, can they exist alone, can they move, and how do they die?

By default, a master-detail child can’t be moved to another parent. You can allow it, by selecting Allow reparenting on the relationship (Considerations for Object Relationships (opens in a new tab)). My instinct is conservative: if the business says the child belongs to one parent for life, I don’t make moving it easy. An item moving from one delivery to another should be a deliberate business event, not a field edit. Again, the setting isn’t the architecture. The lifecycle rule is, and the setting implements it.

Two more things that catch teams later. You can’t create a master-detail relationship on an object that already has data; you create a lookup, fill it on every record, then convert it. And you can only convert back to a lookup if there are no roll-up summary fields on the master. Watch what converting does to security, too: turning a lookup into a master-detail sets the child’s sharing to Controlled by Parent, and turning a master-detail back into a lookup sets the child’s organization-wide default to Public Read/Write (Considerations for Object Relationships (opens in a new tab)). Records that were private yesterday are open today, until someone notices. Choose early.

Roll-Ups Are Useful, but They Aren’t Free

Section titled “Roll-Ups Are Useful, but They Aren’t Free”

I like roll-ups. Count the items on a delivery, sum the line amounts on an invoice, find the latest date: native, no code. The master-detail field goes on the child, but the roll-up goes on the parent. They come with fine print, though (Roll-Up Summary Field (opens in a new tab)):

  • Calculating roll-up values after certain changes (a new roll-up field, a changed formula it depends on, a forced recalculation) can take up to 30 minutes, depending on how many records are affected. I’ve watched people wonder why the number on the parent hasn’t changed yet.
  • They can’t summarize everything. An auto number can’t be the field you aggregate. And a roll-up can summarize a formula field only if that formula doesn’t reach across to another object and doesn’t use a function that changes on its own, such as NOW() or TODAY(). A “days overdue” formula built on TODAY() changes every night without anyone saving a record, so there’s nothing for the roll-up to recalculate from. That kind of number needs a scheduled flow, or a report.
  • The filter has limits too: no long text area, multi-select picklist, Description, system fields like Last Activity, cross-object formulas or lookup fields.
  • Roll-ups aren’t on edit pages, so a validation rule can use one but can’t show its error there.

And don’t reverse the decision. Don’t say, “We need a roll-up, so this must be master-detail.” Say, “This child truly belongs to this parent, the ownership and lifecycle fit, and one of the benefits is native roll-ups.” If the semantics don’t fit, solve the calculation another way. Don’t distort the data model to get a feature.

So what’s the other way? You build the roll-up yourself: a field on the parent that holds the calculated value, and automation that keeps it current. Say Retail Partner is a lookup from Delivery, as it should be, and the business wants Open Deliveries on the partner. Add a number field, Open Deliveries, to the partner. Then a record-triggered flow, or an Apex trigger when the volume or the logic calls for code, recalculates it whenever a delivery changes. It works over a lookup, it can filter on anything, and it can use dates and formulas a native roll-up can’t.

But now it’s yours to get right, and that’s where these go wrong. The automation has to fire on every change that matters: a new child, an edited child, a deleted child, an undeleted child, and a child moved to another parent, which means recalculating both the old parent and the new one. It has to handle a data load of 200 records at a time without hitting limits. Recount rather than add and subtract, so one missed event doesn’t leave the number wrong forever. Plan a way to recalculate everything, for the first load and the day it drifts. And remember every child save now updates the parent, so a parent with thousands of children brings back the locking we’ll see in a moment. A native roll-up does all of that for you; a custom one is a small piece of software you own.

Three Levels Deep: Stacking Master-Details

Section titled “Three Levels Deep: Stacking Master-Details”

The platform has a shape, and master-detail has two dimensions of it. The first is depth.

You can stack master-details three custom detail levels deep, and that’s the bottom (Considerations for Object Relationships (opens in a new tab)). In class I draw it as an account with an order (one), the order with its items (two), and the items with their details (three), and then I try to add a fourth and Salesforce won’t let me. On Steve Trucking it might look like this: a Delivery is the master; its Delivery Items are the first level; an item’s Install Tasks are the second; and each task’s Task Steps are the third. A fourth level, say a Step Note, has to be a lookup.

Three levels of master-detail Three stacked master-detail relationships on Steve Trucking, drawn as thick lines. Delivery is the master. Delivery Item is detail level 1, Install Task is level 2, and Task Step is level 3. Step Note hangs off Task Step on a thin lookup line, because a fourth level has to be a lookup. Underneath: ownership, sharing and deletion flow down from the Delivery to every level. {"author": "Steve Simpson", "blueprint": "1.0.0", "builder": "standard 1.28.0", "built": "2026-10-15", "id": "DGM-DA-PD-72", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "object-model/physical 1.8.0", "theme": "stevetecharc 1.4.0"} level 1 level 2 level 3 a fourth level is a lookup Delivery Delivery__c · master Delivery Item Delivery_Item__c Install Task Install_Task__c Task Step Task_Step__c Step Note Step_Note__c Ownership, sharing and deletion flow down from the Delivery to every level. exactly one zero or one one or many zero or many master-detail lookup © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

A few rules come with the stack:

  • Standard objects can’t be on the detail side of a custom object. A custom object can be a detail of Account; Account can’t be a detail of yours.
  • An object can appear only once in a multilevel stack. Salesforce doesn’t want you looping back on yourself: a subdetail can’t also be the master of its own master.
  • The master can’t roll up the bottom level directly. If Delivery wants the number of Task Steps, Install Task rolls up its steps, Delivery Item rolls up those roll-ups, and Delivery rolls up the items: one level at a time.
  • Ownership and sharing come from the top. Every level inherits the owner and the access of the master.
  • Deleting the master deletes everything beneath it, and undeleting it brings everything back.

Three levels is usually plenty. If your design keeps wanting a fourth, ask whether every level really belongs to the one above it for life. And remember you get to choose which link breaks the chain. The fourth level doesn’t have to be the lookup: maybe an Install Task doesn’t truly belong to its Delivery Item, it’s scheduled and assigned on its own, so that link becomes a lookup, and now Install Task starts a new chain with Task Step and Step Note beneath it. Pick the link where the child really has its own life, and make that one the lookup.

Breaking the chain with a lookup The same five Steve Trucking objects as the three-level stack, with a lookup in the middle. Delivery is a master, with Delivery Item as its detail on a thick master-detail line. Delivery Item links to Install Task on a thin lookup line that breaks the chain. Install Task is a new master: Task Step is its detail, and Step Note is Task Step's detail, both on thick master-detail lines. Underneath: Install Task has its own owner and sharing now, and deleting a delivery no longer deletes its install tasks. {"author": "Steve Simpson", "blueprint": "1.0.0", "builder": "standard 1.28.0", "built": "2026-10-15", "id": "DGM-DA-PD-74", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "object-model/physical 1.8.0", "theme": "stevetecharc 1.4.0"} level 1 a lookup breaks the chain level 1 level 2 Delivery Delivery__c · master Delivery Item Delivery_Item__c Install Task Install_Task__c · a new master Task Step Task_Step__c Step Note Step_Note__c Install Task has its own owner and sharing now, and deleting a delivery no longer deletes its install tasks. exactly one zero or one one or many zero or many master-detail lookup © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Now Install Task has its own owner and its own sharing, a delivery can be deleted without taking its install tasks with it, and Install Task can have two more levels beneath it. That’s the trade: the chain is shorter, and the install task’s life is its own.

Two Parents Wide: the Salesforce Junction Object

Section titled “Two Parents Wide: the Salesforce Junction Object”

First, a word about words, because “junction object” means two things, and I teach both.

In chapter 2 we found the logical junction object: the junction of two key ideas that becomes a thing of its own, with its own attributes. A dog knows many tricks, a trick is known by many dogs, and Dog Trick sits between them holding the skill level and the date. That’s a logical junction object, in the logical model, long before anyone decides lookup or master-detail.

Salesforce uses the term more narrowly. When Salesforce says junction object, it means a custom object with two master-detail relationships (Create a Many-to-Many Object Relationship (opens in a new tab)). I’ll call that a Salesforce Junction Object. Every Salesforce Junction Object is a logical junction object, but not every logical junction object becomes a Salesforce Junction Object: build one with a master-detail and a lookup, or two lookups, and it’s still a logical junction object, just not the Salesforce kind. (Salesforce isn’t perfectly consistent itself: its own object reference calls some standard objects built on lookups “junction objects”. On the exam, assume the narrow definition.)

Test knowledge. A Salesforce Junction Object is a custom object with two master-detail relationships, and that’s what Salesforce means when it says “junction object”. The logical junction object is the wider modeling idea: any object that joins two others in a many-to-many and carries its own attributes, however it’s built.

The second dimension is width. Can a child have two master-detail parents? Yes. Three? No. Each custom object can have up to two master-detail relationships (Considerations for Object Relationships (opens in a new tab)). Two master-detail parents is how you build a Salesforce Junction Object for a many-to-many. Crew and Truck meet in a Crew Assignment, and as we found in chapter 2, it isn’t plumbing: it has a date, a route, maybe a status. The junction is where the relationship becomes a business concept. Salesforce’s tips for building one: give it a name that says what it is, make its record name an auto number, and rename each master’s related list to the other master, so the Crew page shows “Trucks” and the Truck page shows “Crews” (Create a Many-to-Many Object Relationship (opens in a new tab)).

Here’s the intricacy. One of the two parents is the primary, and it’s the one whose master-detail field you created first. There’s no visual indication of which one that is, so it’s a classic test question, and a classic surprise.

What does the primary decide? Three things (Create a Many-to-Many Object Relationship (opens in a new tab)):

  • Look and feel. The junction’s pages use the primary master’s color and icon.
  • Owner. The junction records inherit the owner of the primary master record. You never see it, because a detail has no Owner field; it only matters if you later remove both master-detail relationships.
  • Division, if your org uses divisions, the same way.

And the other one is the secondary. What does it mean?

  • It’s in line to become primary. Delete the primary master-detail field or convert it to a lookup, and the secondary becomes the primary.
  • It sets the scope of the reports. Salesforce gives you two report types: “Primary master with junction object and secondary master” and “Secondary master with junction object and primary master”. The master listed first decides which records the report can show.
  • It counts just as much for access. Here’s how I put it: ownership from the primary, access from both, and the most restrictive wins. A junction, like any detail, has no share table of its own. Salesforce checks the user’s access to both master records, through the Sharing Setting on each master-detail field. If both are set to Read/Write, the user needs Read/Write on the crew and on the truck to edit the Crew Assignment (Considerations for Object Relationships (opens in a new tab)).
  • It deletes just as much. Delete either master, the crew or the truck, and its junction records go to the Recycle Bin. Delete both and they’re gone for good.
A junction's primary and secondary A junction object below its two master-detail parents, drawn with thick lines. Crew, above on the left, is the primary, because its master-detail field was created first; it gives the Crew Assignment its owner and its look. Truck, above on the right, is the secondary; it decides the scope of the second report type and becomes primary if the first relationship is removed. Crew Assignment sits between and below them. Underneath: access needs both parents, and the most restrictive wins; delete either parent and the assignment goes too. {"author": "Steve Simpson", "blueprint": "1.0.0", "builder": "standard 1.28.0", "built": "2026-10-15", "id": "DGM-DA-PD-73", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "object-model/physical 1.8.0", "theme": "stevetecharc 1.4.0"} owner and look report scope Crew Crew__c · primary: created first Truck Truck__c · secondary Crew Assignment Crew_Assignment__c Access needs both parents: the most restrictive wins. Delete either parent and the assignment goes too. exactly one zero or one one or many zero or many master-detail © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

A few more rules: both masters can have roll-up summaries from the junction, and the junction’s formulas and validation rules can reach fields on both. But a junction can’t be the master of anything else, so it can’t sit in the middle of a stack, and the two masters can’t be the same object; a many-to-many from an object to itself needs a different design. And if a parent has more than 200 junction records and the junction rolls up to the other parent, Salesforce won’t let you delete that parent until you’ve removed enough of them.

So: which parent should be primary? Create the one that owns the meaning first. For a Crew Assignment, the crew is doing the work, so I’d create Crew first. And then write it down, because nothing on the screen will tell the next person.

Having said all that, I don’t end up with many Salesforce Junction Objects. Typically an object has one master-detail parent, and it’s the same kind of data: customer data under customer data, transactional under transactional (remember chapter 2’s kinds of data: customer, transactional, reference). When its other parent is a different kind, usually a reference object, that relationship is a lookup. A Delivery Item belongs to its Delivery: master-detail, both transactional. It points to the Product it carries with a lookup, because a product is reference data with a life of its own, and nobody wants deleting a product to take years of delivery history with it. Delivery Item is still a logical junction object between a delivery and the products on it; it just isn’t a Salesforce Junction Object.

Self-Relationships: When the Line Comes Back

Section titled “Self-Relationships: When the Line Comes Back”

An object can relate to itself: a parent account, a manager, a distribution center that reports to a regional hub. Salesforce builds in two you’ll meet in almost every org: Account to Account, the Parent Account field that builds the account hierarchy, and Case to Case, the Parent Case from module 2 that groups related cases. A self-relationship has to be a lookup, and a record can’t point to itself, although two records can point at each other (Considerations for Object Relationships (opens in a new tab)). On the User object it’s a special type of its own, the hierarchical relationship, used for things like a user’s manager. The mechanics are easy; the naming matters. A lookup from Distribution Center to Distribution Center called Distribution_Center__c helps nobody. Parent? Backup? Overflow? Name the relationship for the role, not for the object it points to.

Self-relationships Three objects, each with a lookup to itself. Account, through its ParentId field, points to a parent account, which builds the account hierarchy. Case, through its ParentId field, points to a parent case. Distribution Center, a custom object, points to its regional hub through a field named Regional_Hub__c. Underneath: always a lookup, never to the same record, and named for the role it plays. {"author": "Steve Simpson", "blueprint": "1.0.0", "builder": "standard 1.28.0", "built": "2026-10-15", "id": "DGM-DA-PD-75", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "object-model/physical 1.8.0", "theme": "stevetecharc 1.4.0"} parent account parent case regional hub Account Account · ParentId Case Case · ParentId Distribution Center Distribution_Center__c · Regional_Hub__c Always a lookup, never to the same record, and named for the role it plays. exactly one zero or one one or many zero or many lookup © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Hierarchical: the User Object’s Own Relationship

Section titled “Hierarchical: the User Object’s Own Relationship”

This one is small, and it’s exactly the kind of little-known, one-of-a-kind fact I’d expect an exam to draw on. Hierarchical is a special lookup that exists only on the User object. It links one user to another user, and Salesforce won’t let the chain loop back: a user can’t point to themselves, directly or indirectly (Object Relationships Overview (opens in a new tab)). If Maria’s manager is Dev, Dev’s manager can’t be Maria, or anyone who reports up to Maria.

That’s the difference from the self-relationships above. On Account or a custom object, two records can point at each other. On User, the hierarchy has to stay a hierarchy. And it’s the only way to relate User to User: an ordinary lookup from User to itself isn’t offered.

You already have one. The standard Manager field on User is a hierarchical relationship, and approvals can use it: send this request to the submitter’s manager. You can create your own too, say an Escalation Contact or a Backup Approver, and an approval can route along it the same way (ApprovalProcess, Metadata API (opens in a new tab)). Don’t confuse it with the role hierarchy, which drives record access. A hierarchical field is just a relationship between users; it doesn’t share a single record.

Test knowledge. The hierarchical relationship exists only on the User object, like the standard Manager field, and a user can’t point to themselves, directly or indirectly. It isn’t the role hierarchy.

Each object can have two master-detail relationships at most. Lookup and master-detail fields together count as relationship fields: 40 per object by default, 50 at most on request. Roll-up summary fields: 25 per object by default, 40 at most (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 adds that raising either limit can affect performance.

You don’t need to design to those numbers; you need to notice when you’re near them. An object with relationship after relationship hanging off it is telling you something. Maybe it genuinely is that central. Or maybe the model is wrong. (And chapter 18’s headroom rule applies: stay well under a limit, measured against year three.)

Then there’s the parent with too many children. Salesforce’s own guidance is not to exceed about 10,000 child records for one master-detail parent (Considerations for Object Relationships (opens in a new tab)), and its guide to record access at scale says the same for parent-child relationships generally (Parent-Child Data Skew (opens in a new tab)). Record 10,001 doesn’t break the org. But past that point, saving a child can lock the parent, and sharing changes on the parent ripple through every child.

So when I see one parent, enormous numbers of children, I ask: why are they all under the same parent, who owns them, how are they queried, and what automation touches the parent? Every delivery under a single “Steve Trucking” account would pass 10,000 in a few days. An innocent one-to-many becomes a skew problem. The next module previews skew, and Part 2 goes deep.

This is the habit I want from this module. Don’t start from “I need a roll-up,” “I need it required,” “I want inherited sharing.” Those are implementation clues. Start from the business: does the child have its own life, who owns it, can it exist alone, can it move, what happens when the parent goes, does the relationship carry data, and how big can each side get? Then choose the relationship that implements the answers.

Lookup, master-detail or junction? A matrix of three relationship patterns against six business questions. A lookup: the child can exist alone, has its own owner, can change parent, and copes with more than 10,000 children per parent, though skew still needs watching; it doesn't go with the parent by default (the field is cleared or the delete is blocked) and holds one parent per field. It means connected. A master-detail: the parent is required, the child inherits the parent's owner, it's cascade-deleted with the parent, it changes parent only if reparenting is allowed, and more than 10,000 children brings parent locks and recalculation. It means belongs to. A Salesforce Junction Object: it needs both parents, takes its owner from the primary, is deleted with either parent, and is the one pattern for many on both sides. It means a business concept. Underneath: answer the business questions first; the relationship type follows. {"author": "Steve Simpson", "blueprint": "1.0.0", "builder": "standard 1.28.0", "built": "2026-10-15", "id": "DGM-DA-PD-71", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "matrix 0.1.0", "theme": "stevetecharc 1.4.0"} EXISTS ALONE ITS OWN OWNER GOES WITH PARENT CHANGES PARENT MANY ON BOTH SIDES 10,000+ PER PARENT IT MEANS Lookup Delivery → Route clear or block, by default one parent per field still watch skew CONNECTED Master-detail Delivery → Delivery Item parent required inherits the parent's cascade delete only if reparenting on one master per field parent locks, recalcs BELONGS TO Salesforce Junction Object Crew + Truck → Crew Assignment needs both parents from the primary either parent deletes it only if reparenting on that's its job same 10,000 guidance A BUSINESS CONCEPT Answer the business questions first. The relationship type follows; don't start from the feature you want. © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Beyond the exam: what AI changes. AI can propose relationships in seconds. It can’t tell you whether the business will ever delete the parent. Faster diagramming doesn’t make a wrong relationship cheaper to reverse once millions of records and dozens of automations depend on it.

  • Whether the child has its own lifecycle or truly belongs to the parent, and whether ownership and access should be its own or inherited.
  • Whether the child can exist without a parent, move between parents, or survive the parent’s deletion.
  • What each lookup does when its parent is deleted: clear, block, or cascade.
  • Whether a many-to-many is plumbing or a business concept, whether the logical junction object becomes a Salesforce Junction Object, which parent is primary, and what both parents mean for access.
  • Whether the model fits the platform’s shape: three custom detail levels deep, two master-detail parents wide, the relationship and roll-up limits.
  • Whether the expected number and distribution of children creates a skew risk that should change the design.

A relationship is a set of promises about how two pieces of data behave together. Make them deliberately.