Standard & Custom Objects, Relationships
📖 Concept
Every Salesforce solution starts with the data model. Understanding objects, fields, and relationships is the foundation of all Salesforce development.
Standard Objects: Salesforce ships with ~200 standard objects. The most critical:
- Account — Companies/organizations (the center of most data models)
- Contact — People associated with accounts
- Opportunity — Sales deals (pipeline tracking)
- Lead — Unqualified prospects (convert to Account + Contact + Opportunity)
- Case — Support tickets/issues
- Task / Event — Activities (calls, meetings, to-dos)
- User — System users (not the same as Contact)
Custom Objects:
Created to store data specific to your business. Named with __c suffix.
- Example:
Invoice__c,Project__c,TimeEntry__c - Can have up to ~500 custom fields
- Support all relationship types
- Can participate in sharing, triggers, flows, and Lightning pages
Relationship Types:
Lookup Relationship — Loose association
- Child can exist without parent
- No cascade delete (configurable)
- Sharing is independent
- Maximum 40 lookups per object
- Example: Contact → Account (Contact can exist without Account)
Master-Detail Relationship — Tight parent-child
- Child cannot exist without parent
- Cascade delete (deleting parent deletes all children)
- Child inherits parent's sharing/security
- Roll-up summary fields available on parent
- Maximum 2 master-detail per object
- Example: OpportunityLineItem → Opportunity
Junction Object — Many-to-many
- A custom object with TWO master-detail relationships
- Creates a many-to-many relationship between two objects
- Inherits sharing from the primary master (first master-detail created)
- Example: Student__c ←→ Class_Enrollment__c ←→ Course__c
Hierarchical Relationship — Self-referencing (User object only)
- Example: User.ManagerId → User
External Lookup — References external data sources
- Used with Salesforce Connect and external objects
Data modeling best practices:
- Start with standard objects before creating custom ones
- Use Master-Detail when you need cascade delete and roll-up summaries
- Use Lookup when objects need independent lifecycle
- Junction objects for many-to-many (no native M:M support)
- Keep object relationships shallow (3-4 levels max for query performance)
- Plan for large data volumes from the start
💻 Code Example
1// Working with objects and relationships in Apex23// Creating records with relationships4public class DataModelExamples {56 // 1. Creating parent-child records (Account → Contact)7 public static void createAccountWithContacts() {8 // Create parent9 Account corp = new Account(10 Name = 'Acme Corporation',11 Industry = 'Technology',12 BillingCity = 'San Francisco'13 );14 insert corp;1516 // Create children with relationship17 List<Contact> contacts = new List<Contact>{18 new Contact(19 FirstName = 'John',20 LastName = 'Doe',21 AccountId = corp.Id, // Lookup relationship22 Email = 'john@acme.com'23 ),24 new Contact(25 FirstName = 'Jane',26 LastName = 'Smith',27 AccountId = corp.Id,28 Email = 'jane@acme.com'29 )30 };31 insert contacts;32 }3334 // 2. Querying across relationships35 public static void queryRelationships() {36 // Parent-to-child (subquery) — "Get account and its contacts"37 List<Account> accounts = [38 SELECT Name, Industry,39 (SELECT FirstName, LastName, Email40 FROM Contacts // Child relationship name41 WHERE Email != null42 ORDER BY LastName)43 FROM Account44 WHERE Industry = 'Technology'45 LIMIT 1046 ];4748 // Child-to-parent (dot notation) — "Get contact and its account info"49 List<Contact> contacts = [50 SELECT FirstName, LastName,51 Account.Name, // Parent field52 Account.Industry, // Navigate up the relationship53 Account.Owner.Name // Navigate multiple levels54 FROM Contact55 WHERE Account.Industry = 'Technology'56 ];5758 // Working with results59 for (Account acc : accounts) {60 System.debug('Account: ' + acc.Name);61 for (Contact c : acc.Contacts) { // Access child records62 System.debug(' Contact: ' + c.FirstName + ' ' + c.LastName);63 }64 }65 }6667 // 3. Junction Object pattern (Many-to-Many)68 // Student__c <---> Course_Enrollment__c <---> Course__c69 public static void createManyToMany() {70 // Assume Student__c and Course__c already exist71 // Create junction records72 List<Course_Enrollment__c> enrollments = new List<Course_Enrollment__c>();7374 // Enroll student in multiple courses75 for (Id courseId : courseIds) {76 enrollments.add(new Course_Enrollment__c(77 Student__c = studentId, // Master-Detail 178 Course__c = courseId, // Master-Detail 279 Enrollment_Date__c = Date.today(),80 Status__c = 'Active'81 ));82 }83 insert enrollments;84 }8586 // 4. Dynamic relationship queries87 public static List<SObject> getRelatedRecords(88 Id parentId, String childObject, String relationshipField89 ) {90 String query = 'SELECT Id, Name FROM ' +91 String.escapeSingleQuotes(childObject) +92 ' WHERE ' + String.escapeSingleQuotes(relationshipField) +93 ' = :parentId';94 return Database.query(query);95 }9697 // 5. Schema Describe — inspect relationships at runtime98 public static void describeRelationships(String objectName) {99 Schema.DescribeSObjectResult objDescribe =100 Schema.getGlobalDescribe().get(objectName).getDescribe();101102 // Get all child relationships103 List<Schema.ChildRelationship> children = objDescribe.getChildRelationships();104 for (Schema.ChildRelationship child : children) {105 System.debug('Child Object: ' + child.getChildSObject());106 System.debug('Relationship Name: ' + child.getRelationshipName());107 System.debug('Field: ' + child.getField());108 }109 }110}
🏋️ Practice Exercise
Data Modeling Practice:
- Design a data model for a university system: Students, Courses, Professors, Departments, Enrollments
- Create a Junction Object to model many-to-many relationships between Products and Orders
- Write SOQL queries that traverse: parent-to-child, child-to-parent, and across junction objects
- Use Schema.DescribeSObjectResult to list all relationships on the Account object
- Create a trigger on a child object that updates a field on the parent (simulating a roll-up on a lookup)
- Design an ERD (Entity Relationship Diagram) for a project management app with 8+ objects
- Compare lookup vs master-detail: create both and test what happens when you delete the parent
- Build a hierarchical relationship on a custom object (self-referencing lookup)
- Write a batch Apex job that reparents 100,000 Contact records from one Account to another
- Investigate the maximum number of relationship levels you can traverse in a single SOQL query (5)
⚠️ Common Mistakes
Using lookup when master-detail is needed — if you need cascade delete or roll-up summary fields, you must use master-detail
Creating too many master-detail relationships — each object can have at most 2 master-detail relationships
Not understanding cascade delete implications — deleting a parent in master-detail deletes ALL children permanently
Forgetting that junction objects inherit sharing from the PRIMARY master — the first master-detail relationship created determines the sharing context
Querying too many relationship levels — SOQL supports up to 5 levels of parent traversal and 1 level of child subquery
💼 Interview Questions
🎤 Mock Interview
Mock interview is powered by AI for Standard & Custom Objects, Relationships. Login to unlock this feature.