offdataai
Salesforce · data model template

Salesforce Customer 360 data model

Data Vault 2.0 raw vault for a multi-cloud Salesforce Customer 360. Eight business-key hubs, ten links (including OpportunityContactRole, CampaignMember, lead conversion, a transactional opportunity-line link, and a Campaign Influence link), and ten satellites with PII masking and effectivity tracking for opportunity stage and case status. Hash keys and HASH_DIFF are generated by the DDL layer.

A Salesforce Customer 360 raw vault spanning Sales, Service, and Marketing clouds: hubs for Account, Contact, Lead, Opportunity, Case, Campaign, User, and Product; links for account-contact, opportunity, case, campaign membership, lead conversion, opportunity lines, and Campaign Influence; and satellites (including effectivity satellites for opportunity stage and case status) for fully auditable, multi-source loading of Salesforce into the warehouse. It is a Data Vault 2.0 raw vault: hubs for business keys, links for relationships and satellites for descriptive history, with hash keys and hash diffs generated in the DDL.

Data Vault 2.0SalesforceGDPRCCPASOX
29
tables
195
columns
34
relationships
13
PII columns

Opening the template creates a project with the ERD, platform-native DDL, a dbt project and documentation already generated (recommended platform: Snowflake). Edit it in plain English or on the canvas, then ship it to any supported warehouse.

Subject areas

hubslinkssatellitesreference

Design decisions

  • Hubs hold only the Salesforce 18-char business keys

    Separating Account, Contact, Lead, Opportunity, Case, and Campaign Ids into hubs decouples them from any single object's schema, so adding Service or Marketing cloud sources later means new sats/links, not reshaping existing structures.

  • Effectivity satellites for opportunity stage and case status

    Stage and status change frequently and must be queryable as-of; dedicated effectivity satellites with effective_from/to and is_current capture the full transition history Salesforce overwrites in place.

  • Lead conversion modelled as a unit-of-work link

    Lead conversion creates an Account, Contact, and Opportunity in one action; a single same-as/unit-of-work link records all four keys together, preserving the conversion event for funnel analysis.

  • Transactional links for opportunity lines and Campaign Influence

    OpportunityLineItem and Campaign Influence carry measures and are immutable events, so they are non-historized transactional links rather than hub+sat pairs, keeping line- and touch-grain facts close to the raw load.

  • PII masked on contact, lead, and user satellites

    GDPR/CCPA require masking personal data; email is hashed and mailing address is restricted with full masking so the governance report has signal directly from the raw vault.

Tables in the Salesforce Customer 360 model

Every table with its grain, columns, types and keys. PK marks a primary key, BK a business key and PII a column classified as personal data, which gets a masking strategy by default.

Hubs (8)

hub_account

Grain: one row per unique hub_account business key

ColumnTypeKeys
account_idvarcharBK
load_datetimestamp
record_sourcevarchar

hub_contact

Grain: one row per unique hub_contact business key

ColumnTypeKeys
contact_idvarcharBK
load_datetimestamp
record_sourcevarchar

hub_lead

Grain: one row per unique hub_lead business key

ColumnTypeKeys
lead_idvarcharBK
load_datetimestamp
record_sourcevarchar

hub_opportunity

Grain: one row per unique hub_opportunity business key

ColumnTypeKeys
opportunity_idvarcharBK
load_datetimestamp
record_sourcevarchar

hub_case

Grain: one row per unique hub_case business key

ColumnTypeKeys
case_idvarcharBK
load_datetimestamp
record_sourcevarchar

hub_campaign

Grain: one row per unique hub_campaign business key

ColumnTypeKeys
campaign_idvarcharBK
load_datetimestamp
record_sourcevarchar

hub_user

Grain: one row per unique hub_user business key

ColumnTypeKeys
user_idvarcharBK
load_datetimestamp
record_sourcevarchar

hub_product

Grain: one row per unique hub_product business key

ColumnTypeKeys
product_codevarcharBK
load_datetimestamp
record_sourcevarchar

Links (10)

lnk_account_contact

Grain: one row per lnk_account_contact relationship

Which contacts belong to which account.

ColumnTypeKeys
account_hkbinary
contact_hkbinary
load_datetimestamp
record_sourcevarchar

lnk_opportunity_account

Grain: one row per lnk_opportunity_account relationship

The account an opportunity belongs to.

ColumnTypeKeys
opportunity_hkbinary
account_hkbinary
load_datetimestamp
record_sourcevarchar

lnk_opportunity_contact

Grain: one row per OpportunityContactRole

Buying-group roles linking opportunities to contacts.

ColumnTypeKeys
opportunity_hkbinary
contact_hkbinary
contact_rolevarchar
is_primaryboolean
load_datetimestamp
record_sourcevarchar

lnk_opportunity_owner

Grain: one row per lnk_opportunity_owner relationship

Opportunity ownership (OwnerId).

ColumnTypeKeys
opportunity_hkbinary
user_hkbinary
load_datetimestamp
record_sourcevarchar

lnk_case_account

Grain: one row per lnk_case_account relationship

The account a case is logged against.

ColumnTypeKeys
case_hkbinary
account_hkbinary
load_datetimestamp
record_sourcevarchar

lnk_case_contact

Grain: one row per lnk_case_contact relationship

The contact who raised a case.

ColumnTypeKeys
case_hkbinary
contact_hkbinary
load_datetimestamp
record_sourcevarchar

lnk_campaign_member

Grain: one row per CampaignMember (contact or lead)

Campaign membership — a contact or lead associated with a campaign.

ColumnTypeKeys
campaign_hkbinary
contact_hkbinary
lead_hkbinary
campaign_member_idvarcharBK
member_statusvarchar
has_respondedboolean
load_datetimestamp
record_sourcevarchar

lnk_lead_conversion

Grain: one row per converted lead

Lead conversion — ties a lead to the account, contact, and opportunity it became.

ColumnTypeKeys
lead_hkbinary
account_hkbinary
contact_hkbinary
opportunity_hkbinary
converted_datedate
load_datetimestamp
record_sourcevarchar

lnk_opportunity_line

Grain: one row per OpportunityLineItem (non-historized transactional link)

Transactional link — opportunity line items with measures.

ColumnTypeKeys
opportunity_hkbinary
product_hkbinary
opportunity_line_idvarcharBK
quantitydecimal
unit_pricedecimal
total_pricedecimal
currency_codevarchar
load_datetimestamp
record_sourcevarchar

lnk_campaign_influence

Grain: one row per (opportunity, campaign, contact, model) influence allocation

Transactional link — Campaign Influence revenue attribution across touches.

ColumnTypeKeys
opportunity_hkbinary
campaign_hkbinary
contact_hkbinary
attribution_modelvarchar
influence_pctdecimal
attributed_amountdecimal
touch_positionvarchar
load_datetimestamp
record_sourcevarchar

Satellites (10)

sat_account_details

Grain: one row per account_hk per change

Account descriptive history.

ColumnTypeKeys
account_hkbinaryPK
load_datetimestampPK
account_namevarchar
account_typevarchar
industryvarchar
annual_revenuedecimal
employee_countinteger
billing_countryvarchar
owner_namevarcharPII
is_activeboolean
load_end_datetimestamp
record_sourcevarchar

sat_contact_details

Grain: one row per contact_hk per change

Contact descriptive history (PII, GDPR/CCPA-masked).

ColumnTypeKeys
contact_hkbinaryPK
load_datetimestampPK
first_namevarcharPII
last_namevarcharPII
emailvarcharPII
phonevarcharPII
job_titlevarchar
lead_sourcevarchar
mailing_addressvarcharPII
has_opted_out_of_emailboolean
do_not_callboolean
load_end_datetimestamp
record_sourcevarchar

sat_lead_details

Grain: one row per lead_hk per change

Lead descriptive history (PII, GDPR/CCPA-masked).

ColumnTypeKeys
lead_hkbinaryPK
load_datetimestampPK
first_namevarcharPII
last_namevarcharPII
companyvarchar
emailvarcharPII
lead_statusvarchar
ratingvarchar
lead_sourcevarchar
industryvarchar
is_convertedboolean
load_end_datetimestamp
record_sourcevarchar

sat_opportunity_details

Grain: one row per opportunity_hk per change

Opportunity descriptive history.

ColumnTypeKeys
opportunity_hkbinaryPK
load_datetimestampPK
opportunity_namevarchar
opportunity_typevarchar
amountdecimal
annual_recurring_revenuedecimal
lead_sourcevarchar
close_datedate
load_end_datetimestamp
record_sourcevarchar

sat_opportunity_status

Grain: one row per opportunity per stage change

Effectivity satellite tracking opportunity stage transitions over time.

ColumnTypeKeys
opportunity_hkbinaryPK
load_datetimestampPK
stagevarchar
forecast_categoryvarchar
probability_pctdecimal
effective_fromdate
effective_todate
is_currentboolean
load_end_datetimestamp
record_sourcevarchar

sat_case_details

Grain: one row per case_hk per change

Case descriptive history.

ColumnTypeKeys
case_hkbinaryPK
load_datetimestampPK
subjectvarcharPII
case_typevarchar
case_reasonvarchar
priorityvarchar
originvarchar
load_end_datetimestamp
record_sourcevarchar

sat_case_status

Grain: one row per case per status change

Effectivity satellite tracking case status and ownership over time.

ColumnTypeKeys
case_hkbinaryPK
load_datetimestampPK
statusvarchar
is_escalatedboolean
owner_namevarcharPII
effective_fromdate
effective_todate
is_currentboolean
load_end_datetimestamp
record_sourcevarchar

sat_campaign_details

Grain: one row per campaign_hk per change

Campaign descriptive history.

ColumnTypeKeys
campaign_hkbinaryPK
load_datetimestampPK
campaign_namevarchar
campaign_typevarchar
channelvarchar
statusvarchar
start_datedate
end_datedate
budgeted_costdecimal
actual_costdecimal
load_end_datetimestamp
record_sourcevarchar

sat_user_details

Grain: one row per user_hk per change

User descriptive history (PII-masked).

ColumnTypeKeys
user_hkbinaryPK
load_datetimestampPK
user_namevarcharPII
emailvarcharPII
role_namevarchar
teamvarchar
regionvarchar
profile_namevarchar
is_activeboolean
load_end_datetimestamp
record_sourcevarchar

sat_product_details

Grain: one row per product_hk per change

Product descriptive history.

ColumnTypeKeys
product_hkbinaryPK
load_datetimestampPK
product_namevarchar
product_familyvarchar
charge_typevarchar
list_pricedecimal
is_activeboolean
load_end_datetimestamp
record_sourcevarchar

Lookup tables (1)

ref_currency

Grain: one row per ISO currency

ColumnTypeKeys
currency_codevarcharBK
currency_namevarchar
conversion_rate_to_corporatedecimal

Relationships

Each relationship is a foreign key on the first table referencing the second.

  • lnk_account_contact.account_hk → hub_account (many-to-one)
  • lnk_account_contact.contact_hk → hub_contact (many-to-one)
  • lnk_opportunity_account.opportunity_hk → hub_opportunity (many-to-one)
  • lnk_opportunity_account.account_hk → hub_account (many-to-one)
  • lnk_opportunity_contact.opportunity_hk → hub_opportunity (many-to-one)
  • lnk_opportunity_contact.contact_hk → hub_contact (many-to-one)
  • lnk_opportunity_owner.opportunity_hk → hub_opportunity (many-to-one)
  • lnk_opportunity_owner.user_hk → hub_user (many-to-one)
  • lnk_case_account.case_hk → hub_case (many-to-one)
  • lnk_case_account.account_hk → hub_account (many-to-one)
  • lnk_case_contact.case_hk → hub_case (many-to-one)
  • lnk_case_contact.contact_hk → hub_contact (many-to-one)
  • lnk_campaign_member.campaign_hk → hub_campaign (many-to-one)
  • lnk_campaign_member.contact_hk → hub_contact (many-to-one)
  • lnk_campaign_member.lead_hk → hub_lead (many-to-one)
  • lnk_lead_conversion.lead_hk → hub_lead (many-to-one)
  • lnk_lead_conversion.account_hk → hub_account (many-to-one)
  • lnk_lead_conversion.contact_hk → hub_contact (many-to-one)
  • lnk_lead_conversion.opportunity_hk → hub_opportunity (many-to-one)
  • lnk_opportunity_line.opportunity_hk → hub_opportunity (many-to-one)
  • lnk_opportunity_line.product_hk → hub_product (many-to-one)
  • lnk_campaign_influence.opportunity_hk → hub_opportunity (many-to-one)
  • lnk_campaign_influence.campaign_hk → hub_campaign (many-to-one)
  • lnk_campaign_influence.contact_hk → hub_contact (many-to-one)
  • sat_account_details.account_hk → hub_account (many-to-one)
  • sat_contact_details.contact_hk → hub_contact (many-to-one)
  • sat_lead_details.lead_hk → hub_lead (many-to-one)
  • sat_opportunity_details.opportunity_hk → hub_opportunity (many-to-one)
  • sat_opportunity_status.opportunity_hk → hub_opportunity (many-to-one)
  • sat_case_details.case_hk → hub_case (many-to-one)
  • sat_case_status.case_hk → hub_case (many-to-one)
  • sat_campaign_details.campaign_hk → hub_campaign (many-to-one)
  • sat_user_details.user_hk → hub_user (many-to-one)
  • sat_product_details.product_hk → hub_product (many-to-one)

Related templates

All templates →
Start for $1

From requirements to AI-ready context, in one platform.

Describe your business in a conversation, start from a template or connect your own database. Your first model is ready in minutes.

Get startedBook a demo

Plans from $1/month · cancel any time