Study guide
3.3 Schema Design Impact on Apex
Salesforce Certified Platform Developer I Exam
Track your progress as you read
Finished sections get a check mark.
1 Introduction & Exam Overview
1.1 Current Exam Facts 1.2 Blueprint Weights & Study Strategy
2 Platform Fundamentals
2.1 Multi-Tenant Architecture & Shared Resources 2.2 MVC Mapping on the Lightning Platform 2.3 Declarative vs Programmatic Decisions 2.4 Agentforce for Developers: Use Cases & Limitations
3 Data Modeling & Schema
3.1 Objects, Fields & Schema Design 3.2 Relationship Types & Implications 3.3 Schema Design Impact on Apex 3.4 Data Import & Export for Development
4 Platform Data Features
4.1 Formula Fields & Roll-Up Summaries 4.2 Core CRM Objects & Standard Schema 4.3 AppExchange Extensions & Platform Boundaries
5 Declarative Process Automation
5.1 Record-Triggered Flows & Declarative Automation 5.2 Approval Processes & Business Rules 5.3 When to Use Apex vs Declarative Tools
6 Apex Language Basics
6.1 Variables, Constants & Apex Data Types 6.2 Lists, Sets & Maps 6.3 Control Flow & Exception Handling 6.4 Classes, Interfaces & OOP Patterns
7 SOQL, SOSL & DML
7.1 SOQL Query Fundamentals 7.2 SOSL Search Fundamentals 7.3 DML Operations & Bulkification 7.4 Governor Limits & Transaction Boundaries
8 Apex Triggers & Order of Execution
8.1 Trigger Structure & Context Variables 8.2 Bulk Trigger Patterns & Best Practices 8.3 Save Order of Execution 8.4 Recursion, Cascading & Transaction Control
9 Asynchronous Apex
9.1 @future Methods 9.2 Queueable Apex 9.3 Batch Apex 9.4 Schedulable Apex & Job Orchestration
10 Security, Events & Schema Access
10.1 Sharing, FLS, CRUD & Injection Prevention 10.2 Platform Events Publish & Subscribe 10.3 Programmatic Schema Access (Describe)
11 Visualforce
11.1 Visualforce Pages & Markup 11.2 Standard, Custom Controllers & Extensions 11.3 Visualforce in Lightning Experience
12 Lightning Components
12.1 Lightning Component Framework Benefits 12.2 Aura Component Structure & Resources 12.3 Lightning Web Components Fundamentals 12.4 LWC Data Access: Wire, Imperative & Events
13 UI Composition & Apex Integration Patterns
13.1 Composing UI in Lightning Apps 13.2 UI Security, Performance & Accessibility Patterns 13.3 Apex Actions for Flow, LWC, and Agentforce
14 Apex Testing
14.1 Testing Framework & Coverage Requirements 14.2 Writing Unit Tests for Triggers & Classes 14.3 Test Data Strategies & Isolation 14.4 Executing Tests & Execute Anonymous Differences
15 Debugging & Developer Tools
15.1 Debug Logs & Monitoring 15.2 Developer Console, CLI, VS Code & Workbench 15.3 Sandboxes, Scratch Orgs & Environment Strategy
16 Deployment & Release
16.1 Change Sets & Metadata Deployment 16.2 Unlocked Packages, Metadata API & Salesforce DX 16.3 Release Readiness & Credential Maintenance
3.3 Schema Design Impact on Apex
Key Takeaways Explain This Topic AI
Apex and SOQL bind to API names; custom fields/objects use __c and relationship navigation uses __r with configured child relationship names
Schema changes—renames, type changes, deletes—break static Apex references at compile or runtime and can invalidate dynamic queries
Formula and roll-up fields are read-only in Apex DML; null handling differs for lookups, booleans, and unset fields
Governor-friendly schema includes selective filters, indexed External ID/Unique fields, and avoiding chatty parent-child patterns
- Prefer stable API names and package-safe references; dynamic Schema describe APIs trade safety for flexibility
- Last updated: August 2026
3.3 Schema Design Impact on Apex
Quick Answer: Apex does not use field labels—it binds to API names . Custom attributes end in __c , parent navigation uses __r , and child subqueries use the child relationship name . Schema design choices determine null behavior, whether fields are writable, how SOQL must be written, and whether code survives package installs and renames.
Platform Developer I expects you to connect declarative schema decisions to programmatic consequences. A “correct” ERD that ignores Apex will still fail in production under governors or deployments.
API Names Are the Contract
Schema element Typical API pattern Apex / SOQL usage
Custom object Invoice__c List<Invoice__c> rows = ...
- Custom field Status__c inv.Status__c = 'Open'
- Custom lookup value Account__c Holds the parent Id
- Parent navigation Account__r inv.Account__r.Name
- Child relationship Invoice_Lines__r Subquery or related list API name
Labels can change for localization or clarity without breaking code. API names should be treated as permanent public contracts. Renaming Status__c to Invoice_Status__c forces updates to Apex classes, triggers, flows, validation formulas, reports, and integrations.
Standard objects and fields omit __c ( Account , Name , CloseDate ). Standard relationships use names like Account / Accounts depending on direction and context—learn the describe or Object Manager “Child Relationship Name” rather than guessing.
- Relationship Names in SOQL and Apex
- Child-to-parent (dot navigation via __r ): for (Invoice_Line__c line : [
- SELECT Id, Amount__c, Invoice__r.Name, Invoice__r.Account__r.Name
- FROM Invoice_Line__c
- WHERE Invoice__c = :invoiceId
- ]) {
- String acctName = line.Invoice__r.Account__r.Name;
- }
- Parent-to-child (subquery uses relationship name, not object API name): Invoice__c inv = [
- SELECT Id, Name,
- (SELECT Id, Amount__c FROM Invoice_Lines__r)
- FROM Invoice__c
- WHERE Id = :invoiceId
- ];
If the child relationship name was set poorly (or left as a non-obvious default), every subquery breaks. Relationship design is therefore an Apex design decision, not only a UI concern.
Master-detail vs lookup does not change __c / __r syntax, but it changes what is safe to assume : detail records always have a parent Id in master-detail; lookup parents may be null.
Nulls, Defaults, and Booleans
Unset lookup fields are null —always null-check before parent.Name style navigation on in-memory records not loaded via SOQL relationships
Checkbox fields in Apex are Boolean and often false when unchecked rather than null, but code should still be explicit
Number/Currency unset values may be null; arithmetic without null guards causes exceptions
SOQL does not return fields you did not select; touching them yields null, not an automatic lazy load (no transparent ORM load)
Schema defaults (checkbox default true, formula defaults, auto-number) affect insert behavior differently in UI vs Apex—tests should set fields explicitly when behavior depends on them.
Formula and Roll-Up Fields in Apex
Formula fields and roll-up summary fields are calculated by the platform:
- Readable in SOQL and Apex after query (and after refresh from DB)
- Not writable via DML—assignments will not persist and can cause issues if you try to treat them as inputs
- Formula results may be stale in-memory after related DML until re-queried
Some formula types are non-sortable/non-filterable or expensive; filtering on non-deterministic or cross-object formulas can hurt performance
Design implication: store source data in writable fields; expose calculations as formulas when appropriate; use Apex only when formulas/roll-ups cannot express the rule.
Governor-Friendly Schema
Schema shapes how easy it is to stay under governor limits:
Selective filters: Prefer indexed paths—Id, lookups, External ID, Unique, and some standard indexed fields—over leading wildcards on long text
Avoid unbounded parent-child explosion: Deep subquery trees and querying unnecessary relationships burn heap and rows
Roll-ups vs Apex aggregates: Native roll-ups push work to the platform; custom aggregates in triggers need bulkification
Cascade deletes and implicit updates: Master-detail cascades can fire large trigger storms—design trigger handlers for bulk
Record types: Branching logic on RecordTypeId should use maps of developer names from a single describe/query, not per-record SOQL
Poor schema (everything Long Text Area, no External IDs for integration, M:N faked as text) forces Apex into inefficient scans and string parsing.
Static vs Dynamic References
Static references (concrete Invoice__c , Status__c in code):
- Compile-time checking—deploy fails if the field is missing
- Easier to read and refactor with IDE tooling
- Required for most application business logic
Dynamic references ( Schema.SObjectType , getDescribe() , sObject.put/get , dynamic SOQL):
- Flexible for generic libraries, package utilities, and field-set driven UI
- Fail at runtime if names are wrong
- Dynamic SOQL must still guard against SOQL injection (bind variables or escape single quotes)
Slightly more verbose and easier to get wrong under exam time pressure Schema.DescribeFieldResult d = Invoice__c.Status__c.getDescribe();
Boolean updateable = d.isUpdateable();
Field-level security and CRUD checks use describe APIs—schema design that creates many similar custom objects may push you toward generic dynamic patterns; still enforce security explicitly (WITH SECURITY_ENFORCED, Security.stripInaccessible , or describe checks) as covered in security topics.
Packages, Unlocked Packages, and API Name Stability
In packaging contexts:
- Namespaced components appear as namespace__Object__c / namespace__Field__c
- Subscriber orgs cannot always rename packaged API names freely
- Changing a packaged field type or deleting a field is a breaking change for subscriber Apex and integrations
Even outside ISV packages, treat API names as versioned public APIs. Prefer additive changes (new fields) over renames/type changes. Use External IDs for integration keys so external systems do not depend on Salesforce Ids alone.
- Practical Schema → Apex Checklist
- Freeze API names and child relationship names early
- Decide master-detail vs lookup before writing triggers (nulls, cascade, roll-ups)
- Mark integration keys External ID + Unique for upsert-friendly Apex and loaders
- Keep formulas read-only in design docs so developers do not DML them
- Model M:N with junction objects so SOQL stays relational instead of parsing multi-selects
- Prefer static typed Apex for business logic; use dynamic describe for generic frameworks
Schema is not “admin work” separate from development—on the Lightning Platform, schema is part of the application’s type system .