Salesforce supports several relationship types, each with different rules for cascading, sharing, and required-ness. The core ones are Lookup, Master-Detail, Many-to-Many (implemented via a junction object using two Master-Details), Hierarchical (only on the User object), External Lookup (to an external object), and Indirect Lookup (from an external object back to a Salesforce object). Each relationship type creates a relationship field on the child object that points at the parent.
The relationship types at a glance
| Relationship | Where it lives | Required? | Cascade delete? | Ownership/sharing inherited? | Roll-up summary? |
|---|---|---|---|---|---|
| Lookup | Standard or custom | Optional (configurable) | No (default — child stays, ID cleared) | No — child has its own owner | No (use third-party or Apex/flow) |
| Master-Detail | Custom child object | Required | Yes — delete master, children go too | Yes — child’s access is controlled by master | Yes — built-in |
| Many-to-Many | Junction object (custom) with 2 master-details | First master-detail required; second can be looser | Cascades from primary master | Inherits from primary master | Yes — on either master |
| Hierarchical | User object only | Optional | No | No | No |
| External Lookup | Custom child pointing to external object | Optional | No | Limited | No |
| Indirect Lookup | External child pointing to a Salesforce object’s External ID field | Optional | No | Limited | No |
| Self-relationship | Lookup or master-detail where the parent and child are the same object | Optional | Per type | Per type | Per type |
Lookup relationship
A loose pointer from a child record to a parent record. The child stays alive if the parent is deleted (the lookup field just clears, by default). Lookups can be required or optional, and the child has its own OwnerId — sharing is independent of the parent.
Use lookups when the parent is informational: a custom Project may reference an Account, but the Project’s ownership and existence don’t depend on the Account.
Master-detail relationship
A tightly coupled parent-child pointer. The detail (child) is owned by the master — it inherits the master’s owner, the master’s sharing settings, and is deleted if the master is deleted. Detail records don’t have their own OwnerId field; they have no Sharing settings of their own. The master-detail field on the detail is always required.
Use master-detail when the child only exists in the context of the parent: line items under an order, stakeholders under a project, attendees under an event.
Many-to-many — the junction pattern
Salesforce doesn’t have a single “many-to-many” relationship type. You build it with a junction object: a custom object with two master-detail fields, one to each side of the relationship. The first master-detail you create on the junction becomes the primary master — its sharing and ownership govern the junction record.
Classic example: a Student object and a Class object related many-to-many through a Student_Class__c junction with master-detail fields to both Student and Class.
Hierarchical relationship
Only available on the User object. It’s a self-lookup with hierarchy semantics — typically used to model the management chain. The User.ManagerId field is a hierarchical relationship that points at another User.
This is a one-off on User and isn’t available on custom objects.
External Lookup and Indirect Lookup
Used with Salesforce Connect to relate Salesforce data to external system data:
- External Lookup — child is a normal Salesforce custom object, parent is an external object (
__x). Salesforce stores the external object’s primary key in the lookup. - Indirect Lookup — the inverse. Child is an external object, parent is a Salesforce object. The link goes through an External ID custom field on the Salesforce parent object — that’s why external IDs matter here.
Self-relationship (self-lookup)
A relationship pointing back at the same object — like a Case linked to a Parent Case, or a custom Component object linked to a Parent Component. Can be a lookup (most common — used for parent-child hierarchies) or a master-detail (rarer; restricts cascading and ownership in ways that need design care).
Comparing the two you’ll be asked about most
| Dimension | Lookup | Master-Detail |
|---|---|---|
| Required field | Optional (configurable) | Always required |
| Cascade delete | No by default | Yes — delete parent, children deleted |
| Detail has its own owner | Yes | No — controlled by parent |
| Detail has its own sharing | Yes | No — Controlled by Parent OWD |
| Roll-up summary on parent | No (workarounds via flow/Apex/third-party) | Yes — built-in (count, sum, min, max) |
| Reparenting (changing the parent reference) | Allowed | Allowed only if “Allow reparenting” is checked on the field |
| Per-object limit | Up to 40 relationships per object | Up to 2 master-detail per object (counted against the same 40) |
Real scenario
“You’re modeling Invoices and Invoice Line Items. Which relationship?”
Master-detail from Invoice_Line_Item__c to Invoice__c. Reasons:
- A line item only makes sense in the context of an invoice — if the invoice is deleted, the lines should go with it.
- The invoice’s owner should govern visibility of the lines.
- You’ll likely want a roll-up summary on Invoice for total line amount and line count — that requires master-detail.
If instead you were modeling Opportunity and Account, you’d use Lookup (and in fact Salesforce ships it that way). Account doesn’t “own” the Opportunity; sales reps own opportunities, and you wouldn’t want deleting an Account to silently delete its Opportunity history.
Verified against: Salesforce Help — Object Relationships Overview and the Salesforce Architects — Data Modeling resources. Last reviewed 2026-05-17.