offdataai
Marketing & AdTech · data model template

Google Analytics 4 (GA4 BigQuery Export) data model

Kimball warehouse for the GA4 BigQuery export: a transaction-grain event fact, a derived session fact, a purchase fact, and an item-event fact (from the flattened items array), over conformed user/device/geo/traffic-source/page/event-type/item dimensions. Turns the nested GA4 export into query-ready stars for behavior and ecommerce reporting.

Google Analytics 4 modeled from its native BigQuery export: the nested events_* tables (repeated event_params and items records) flattened into conformed star schemas — event, session, purchase, and item-event facts over date, user, device, geo, traffic-source, page, event-type, and item dimensions for acquisition, engagement, conversion, and ecommerce analytics. It is a Kimball dimensional model: fact tables at a declared grain surrounded by conformed dimensions, ready for BI tools and a semantic layer.

KimballMarketing & AdTechGDPRCCPA
12
tables
112
columns
20
relationships
1
PII columns

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

Subject areas

behaviorecommerceconformed_dimensions

Design decisions

  • Flatten the nested export into conformed stars

    The GA4 export stores event_params, user_properties, and items as repeated RECORDs that require UNNEST to query; flattening into an event fact plus an item-event fact makes the data BI-tool-ready without per-query array gymnastics.

  • Derived session fact alongside the event fact

    GA4 has no session table — sessions are reconstructed from the ga_session_id event parameter; a dedicated session fact precomputes engaged-session, bounce, and duration metrics that are expensive to derive ad hoc.

  • Separate purchase and item-event facts for ecommerce

    Purchase headers (revenue, tax, shipping) and the repeated items array live at different grains; modelling them as two facts supports both order-level revenue and product-level performance.

  • user_id hashed under consent regimes

    GA4 carries a pseudonymous user_pseudo_id plus an optional logged-in user_id; hashing user_id and surfacing consent-aware dimensions keeps the model GDPR/CCPA-compliant in the Consent Mode era.

Tables in the Google Analytics 4 (GA4 BigQuery Export) 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.

Fact tables (4)

fct_event

Grain: one row per GA4 event (the flattened events_* export)

Transaction-grain event fact flattened from the nested events_* export (one row per event).

ColumnTypeKeys
event_keybigintPK
date_keybigint
user_keybigint
device_keybigint
geo_keybigint
traffic_source_keybigint
page_keybigint
event_type_keybigint
event_timestamp_microsbigint
session_idvarchar
engagement_time_msecinteger
event_value_usddecimal
is_conversionboolean
event_countsmallint

fct_session

Grain: one row per GA4 session (derived from events)

Session-grain fact for acquisition, engagement-rate, and landing-page analytics.

ColumnTypeKeys
session_keybigintPK
date_keybigint
user_keybigint
traffic_source_keybigint
device_keybigint
geo_keybigint
landing_page_keybigint
session_idvarchar
session_start_microsbigint
session_numbersmallint
event_countinteger
pageview_countinteger
session_duration_secinteger
conversionssmallint
purchase_revenue_usddecimal
is_engaged_sessionboolean
is_bounceboolean

fct_purchase

Grain: one row per GA4 purchase/transaction event

Transaction-grain purchase fact for revenue, AOV, and channel-revenue analytics.

ColumnTypeKeys
purchase_keybigintPK
date_keybigint
user_keybigint
traffic_source_keybigint
transaction_idvarchar
session_idvarchar
purchase_revenue_usddecimal
tax_value_usddecimal
shipping_value_usddecimal
refund_value_usddecimal
total_item_quantitysmallint
unique_itemssmallint
is_refundedboolean
purchase_countsmallint

fct_item_event

Grain: one row per item per ecommerce event (the flattened items array)

Item-grain ecommerce fact flattened from the repeated items record for product analytics.

ColumnTypeKeys
item_event_keybigintPK
date_keybigint
user_keybigint
item_keybigint
event_type_keybigint
transaction_idvarchar
quantitydecimal
item_revenue_usddecimal
price_usddecimal
item_event_countsmallint

Dimension tables (3)

dim_date

Grain: one row per calendar day

ColumnTypeKeys
date_keybigintPK
full_datedateBK
month_numbersmallint
quartersmallint
yearsmallint
day_of_weeksmallint
is_weekendboolean

dim_user

Grain: one row per GA4 user (user_pseudo_id)

ColumnTypeKeys
user_keybigintPK
user_pseudo_idvarcharBK
user_idvarcharPII
first_touch_date_keybigint
first_traffic_sourcevarchar
first_traffic_mediumvarchar
first_traffic_campaignvarchar
first_device_categoryvarchar
first_countryvarchar
is_logged_inboolean

dim_item

Grain: one row per ecommerce item (product)

ColumnTypeKeys
item_keybigintPK
item_idvarcharBK
item_namevarchar
item_brandvarchar
item_categoryvarchar
item_category2varchar
item_variantvarchar
price_usddecimal

Lookup tables (5)

dim_device

Grain: one row per device/platform combination

ColumnTypeKeys
device_keybigintPK
device_categoryvarcharBK
operating_systemvarchar
operating_system_versionvarchar
browservarchar
mobile_brand_namevarchar
languagevarchar
stream_platformvarchar

dim_geo

Grain: one row per geographic location

ColumnTypeKeys
geo_keybigintPK
continentvarchar
sub_continentvarchar
countryvarcharBK
regionvarchar
cityvarchar
metrovarchar

dim_traffic_source

Grain: one row per source/medium/campaign

ColumnTypeKeys
traffic_source_keybigintPK
sourcevarcharBK
mediumvarchar
campaignvarchar
source_mediumvarchar
default_channel_groupingvarchar
is_paidboolean

dim_page

Grain: one row per page/screen

ColumnTypeKeys
page_keybigintPK
page_locationvarcharBK
page_pathvarchar
page_titlevarchar
hostnamevarchar
content_groupvarchar

dim_event_type

Grain: one row per GA4 event name

ColumnTypeKeys
event_type_keybigintPK
event_namevarcharBK
event_categoryvarchar
is_conversionboolean

Relationships

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

  • fct_event.date_key → dim_date (many-to-one)
  • fct_event.user_key → dim_user (many-to-one)
  • fct_event.device_key → dim_device (many-to-one)
  • fct_event.geo_key → dim_geo (many-to-one)
  • fct_event.traffic_source_key → dim_traffic_source (many-to-one)
  • fct_event.page_key → dim_page (many-to-one)
  • fct_event.event_type_key → dim_event_type (many-to-one)
  • fct_session.date_key → dim_date (many-to-one)
  • fct_session.user_key → dim_user (many-to-one)
  • fct_session.traffic_source_key → dim_traffic_source (many-to-one)
  • fct_session.device_key → dim_device (many-to-one)
  • fct_session.geo_key → dim_geo (many-to-one)
  • fct_session.landing_page_key → dim_page (many-to-one)
  • fct_purchase.date_key → dim_date (many-to-one)
  • fct_purchase.user_key → dim_user (many-to-one)
  • fct_purchase.traffic_source_key → dim_traffic_source (many-to-one)
  • fct_item_event.date_key → dim_date (many-to-one)
  • fct_item_event.user_key → dim_user (many-to-one)
  • fct_item_event.item_key → dim_item (many-to-one)
  • fct_item_event.event_type_key → dim_event_type (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