Developer Fundamentals · Topic 3 of 4

The Data Model for Developers

Salesforce data model for Apex developers: objects, field API names, lookup and master-detail relationships, relationship names, external IDs and upsert.

  • 4 min
In a nutshell
  • Custom objects and fields end in __c; custom relationship names end in __r.
  • Child to parent uses dot notation; parent to child uses a subquery with the plural relationship name.
  • Master-detail: no owner on the detail, cascade delete, roll-ups; lookup: independent records.

What it is

The data model is the set of objects, fields and relationships that store an org's data. In Apex every object is an sObject type, such as Account or Invoice__c, and every field is reached by its API name.

Developers need to know how relationships appear in code and queries, and how external IDs let code and integrations match records from other systems without knowing Salesforce Ids.

ObjectsObject typeFieldsAPI namesRelationshipslookup or master detailExternal IDmatch outside keys

How it works

Naming in code

ItemExample API name
Standard objectAccount, Contact, Case
Custom objectInvoice__c
Custom fieldAmount__c
Custom relationship field (holds the Id)Account__c
Custom relationship name (used to traverse)Account__r
Custom metadata typeDiscount_Rate__mdt
Platform eventOrder_Placed__e

Relationship types

TypeKey behaviour
LookupLoose link; child keeps its own owner and sharing; parent delete clears the field or is blocked
Master-detailDetail has no owner, inherits sharing, is deleted with the master; master can have roll-up summaries
Many-to-manyA junction object with two master-detail fields
HierarchicalA lookup from User to User
External lookupLinks to an external object by its external ID

Relationships in SOQL

// Child to parent: dot notation
List<Contact> cs = [SELECT LastName, Account.Name FROM Contact];

// Parent to child: subquery using the child relationship name
List<Account> accs = [SELECT Name, (SELECT LastName FROM Contacts) FROM Account];

// Custom relationship: __r in both directions
List<Invoice__c> inv = [SELECT Name, Customer__r.Name FROM Invoice__c];
List<Customer__c> cust = [SELECT Name, (SELECT Name FROM Invoices__r) FROM Customer__c];

The child relationship name for a standard relationship is plural (Contacts, Cases, Opportunities). For a custom one it is the name set on the field plus __r.

External IDs

An External ID is a custom field (text, number, email or auto number) flagged to hold a key from another system. External ID fields are indexed, so queries filtering on them are fast.

They are used for:

  • Upsert: insert or update depending on whether a matching record exists.
  • Setting relationships without a query: link a child to a parent by the parent's external ID.
// Upsert by external ID
List<Account> accs = new List<Account>{ new Account(Name = 'Acme', ERP_Id__c = 'A-100') };
upsert accs Account.ERP_Id__c;

// Link a Contact to an Account by its external ID, with no SOQL
Contact c = new Contact(LastName = 'Ng', Account = new Account(ERP_Id__c = 'A-100'));
insert c;

If the external ID value matches more than one record, the upsert fails for that record with a duplicate error. Marking the field Unique prevents that.

Custom settings and custom metadata types

FeatureCustom metadata typeCustom setting
Records deployable as metadataYesNo (data must be loaded)
Read in ApexRate__mdt.getInstance('Standard') or getAll(), no SOQL limit usedSettings__c.getInstance() or getOrgDefaults(), cached
Hierarchy by profile or userNoYes, hierarchy custom settings
Typical useApp configuration that moves between orgsUser or profile-specific switches

A worked example

An ERP sends nightly invoice files containing an account number, never a Salesforce Id. The developer adds ERP_Id__c to Account as an External ID and Unique, and ERP_Invoice_No__c to Invoice__c as an External ID. The load runs upsert invoices Invoice__c.ERP_Invoice_No__c; and sets each invoice's parent with Account__r = new Account(ERP_Id__c = row.accountNo). No query for Account Ids is needed, and rerunning the file updates rather than duplicates.

Exam tip

When a question says "without querying for the Id" or "records from an external system", look for an External ID with upsert.

How the exam asks about this

  • "Query each Account with its Contacts." A parent-to-child subquery using Contacts.
  • "Load records again without creating duplicates." Upsert on an External ID field.
  • "Configuration records must deploy with the code." Custom metadata types.

What to remember for the exam

  • Custom objects and fields end in __c; custom relationship names end in __r.
  • Child to parent uses dot notation; parent to child uses a subquery with the plural relationship name.
  • Master-detail: no owner on the detail, cascade delete, roll-ups; lookup: independent records.
  • External IDs are indexed and power upsert and relationship matching without SOQL.
  • Custom metadata records deploy as metadata and are read without using SOQL queries.
Watch out

In a subquery you must use the relationship name (Contacts, Invoices__r), not the object name (Contact, Invoice__c). Using the object name is a compile error.

Common mistakes

Using __c to traverse a relationship. Customer__c holds the Id; Customer__r.Name reaches the parent's field.

Querying for parent Ids before linking records. An external ID reference does it without a query.

Choosing custom settings for configuration that must deploy. Custom setting records are data; custom metadata records deploy.

Check yourself

  • How do you query each Account with its related Contacts in one SOQL statement?

    SELECT Name, (SELECT LastName FROM Contacts) FROM Account.

  • What does upsert records Account.ERP_Id__c; do?

    It updates records whose ERP_Id__c matches an existing account and inserts the rest.

  • Why does reading custom metadata with getInstance() suit trigger code?

    It does not count against the SOQL query limit, and its records deploy with the code.

Topic 3 of 4 in Developer Fundamentals

Test yourself on Developer Fundamentals

The full Salesforce Platform Developer question bank has 645 questions, with timed practice exams and an explanation for every answer.

This study guide is independent and is not affiliated with, endorsed by, or sponsored by Salesforce. Vendor names, certification names and exam codes are trademarks of their respective owners and are used for identification only.