Standard & Custom Objects, Relationships

0/4 in this phase0/41 across the roadmap

📖 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:

  1. 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)
  2. 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
  3. 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
  4. Hierarchical Relationship — Self-referencing (User object only)

    • Example: User.ManagerId → User
  5. 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

codeTap to expand ⛶
1// Working with objects and relationships in Apex
2
3// Creating records with relationships
4public class DataModelExamples {
5
6 // 1. Creating parent-child records (Account → Contact)
7 public static void createAccountWithContacts() {
8 // Create parent
9 Account corp = new Account(
10 Name = 'Acme Corporation',
11 Industry = 'Technology',
12 BillingCity = 'San Francisco'
13 );
14 insert corp;
15
16 // Create children with relationship
17 List<Contact> contacts = new List<Contact>{
18 new Contact(
19 FirstName = 'John',
20 LastName = 'Doe',
21 AccountId = corp.Id, // Lookup relationship
22 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 }
33
34 // 2. Querying across relationships
35 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, Email
40 FROM Contacts // Child relationship name
41 WHERE Email != null
42 ORDER BY LastName)
43 FROM Account
44 WHERE Industry = 'Technology'
45 LIMIT 10
46 ];
47
48 // Child-to-parent (dot notation) — "Get contact and its account info"
49 List<Contact> contacts = [
50 SELECT FirstName, LastName,
51 Account.Name, // Parent field
52 Account.Industry, // Navigate up the relationship
53 Account.Owner.Name // Navigate multiple levels
54 FROM Contact
55 WHERE Account.Industry = 'Technology'
56 ];
57
58 // Working with results
59 for (Account acc : accounts) {
60 System.debug('Account: ' + acc.Name);
61 for (Contact c : acc.Contacts) { // Access child records
62 System.debug(' Contact: ' + c.FirstName + ' ' + c.LastName);
63 }
64 }
65 }
66
67 // 3. Junction Object pattern (Many-to-Many)
68 // Student__c <---> Course_Enrollment__c <---> Course__c
69 public static void createManyToMany() {
70 // Assume Student__c and Course__c already exist
71 // Create junction records
72 List<Course_Enrollment__c> enrollments = new List<Course_Enrollment__c>();
73
74 // Enroll student in multiple courses
75 for (Id courseId : courseIds) {
76 enrollments.add(new Course_Enrollment__c(
77 Student__c = studentId, // Master-Detail 1
78 Course__c = courseId, // Master-Detail 2
79 Enrollment_Date__c = Date.today(),
80 Status__c = 'Active'
81 ));
82 }
83 insert enrollments;
84 }
85
86 // 4. Dynamic relationship queries
87 public static List<SObject> getRelatedRecords(
88 Id parentId, String childObject, String relationshipField
89 ) {
90 String query = 'SELECT Id, Name FROM ' +
91 String.escapeSingleQuotes(childObject) +
92 ' WHERE ' + String.escapeSingleQuotes(relationshipField) +
93 ' = :parentId';
94 return Database.query(query);
95 }
96
97 // 5. Schema Describe — inspect relationships at runtime
98 public static void describeRelationships(String objectName) {
99 Schema.DescribeSObjectResult objDescribe =
100 Schema.getGlobalDescribe().get(objectName).getDescribe();
101
102 // Get all child relationships
103 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:

  1. Design a data model for a university system: Students, Courses, Professors, Departments, Enrollments
  2. Create a Junction Object to model many-to-many relationships between Products and Orders
  3. Write SOQL queries that traverse: parent-to-child, child-to-parent, and across junction objects
  4. Use Schema.DescribeSObjectResult to list all relationships on the Account object
  5. Create a trigger on a child object that updates a field on the parent (simulating a roll-up on a lookup)
  6. Design an ERD (Entity Relationship Diagram) for a project management app with 8+ objects
  7. Compare lookup vs master-detail: create both and test what happens when you delete the parent
  8. Build a hierarchical relationship on a custom object (self-referencing lookup)
  9. Write a batch Apex job that reparents 100,000 Contact records from one Account to another
  10. 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.