offdataai
HR & People · data model template

HR Workforce Analytics data model

Kimball warehouse for HR/HCM: a monthly headcount periodic snapshot, transaction-grain hire/termination events, and a periodic compensation snapshot over conformed employee/department/job/location/manager dimensions. National ID is fully masked and work email hashed.

Human-resources workforce analytics covering monthly headcount, hires and terminations, and employee compensation over a conformed SCD2 employee dimension with department, job, location, and manager dimensions. Sensitive employee PII (date of birth, national ID, ethnicity, salary) is classified and masked under GDPR. It is a Kimball dimensional model: fact tables at a declared grain surrounded by conformed dimensions, ready for BI tools and a semantic layer.

KimballHR & PeopleGDPRSOX
9
tables
97
columns
15
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

headcountattritioncompensationconformed_dimensions

Design decisions

  • Monthly headcount as a periodic snapshot

    Headcount and FTE must be reported at consistent month-end intervals regardless of movement volume; a periodic snapshot gives a dense, semi-additive grain ideal for trending and ratio analysis.

  • Separate transaction fact for hires and terminations

    Attrition and hiring velocity need event-level grain with reason and voluntary/regrettable flags that a snapshot would obscure.

  • SCD2 on employee, department, job, and manager

    Reorgs, promotions, and transfers must be analysed as-of any point in time, so descriptive history is preserved with type-2 versioning.

  • Masking on national ID, salary, and demographics

    GDPR requires minimising exposure of special-category personal data; national ID is fully masked, email hashed, and DOB/ethnicity restricted.

Tables in the HR Workforce Analytics 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 (3)

fct_headcount_snapshot

Grain: one row per active employee per month-end (periodic snapshot)

Monthly headcount snapshot — counts are semi-additive across time.

ColumnTypeKeys
date_keybigint
employee_keybigint
department_keybigint
job_keybigint
location_keybigint
manager_keybigint
headcountsmallint
ftedecimal
tenure_monthssmallint
is_new_hire_this_monthboolean
is_termination_this_monthboolean

fct_hire_termination

Grain: one row per hire or termination event

Transaction-grain workforce movement events.

ColumnTypeKeys
hire_termination_keybigintPK
date_keybigint
employee_keybigint
department_keybigint
job_keybigint
location_keybigint
event_idvarchar
event_typevarchar
termination_reasonvarchar
is_voluntaryboolean
is_regrettableboolean
tenure_at_event_monthssmallint
notice_dayssmallint

fct_compensation

Grain: one row per employee per compensation period (periodic snapshot)

Periodic compensation snapshot — salary is non-additive; aggregate by averaging.

ColumnTypeKeys
date_keybigint
employee_keybigint
department_keybigint
job_keybigint
base_salarydecimal
bonus_target_amountdecimal
bonus_actual_amountdecimal
equity_grant_valuedecimal
total_compensationdecimal
currencyvarchar
pay_gradevarchar
compa_ratiodecimal
is_merit_increase_periodboolean

Dimension tables (6)

dim_date

Grain: one row per calendar day

ColumnTypeKeys
date_keybigintPK
full_datedateBK
month_numbersmallint
month_namevarchar
quartersmallint
yearsmallint
fiscal_yearsmallint
fiscal_periodsmallint
is_month_endboolean
is_business_dayboolean

dim_employee

Grain: one row per employee per SCD2 version

SCD type 2

ColumnTypeKeys
employee_keybigintPK
employee_idvarcharBK
first_namevarcharPII
last_namevarcharPII
preferred_namevarcharPII
date_of_birthdatePII
gendervarcharPII
national_idvarcharPII
work_emailvarcharPII
personal_phonevarcharPII
home_postal_codevarcharPII
hire_datedate
original_hire_datedate
termination_datedate
employment_typevarchar
employment_statusvarchar
is_full_timeboolean
is_regrettable_attritionboolean
ethnicityvarcharPII
veteran_statusvarcharPII

dim_department

Grain: one row per department per SCD2 version

SCD type 2

ColumnTypeKeys
department_keybigintPK
department_idvarcharBK
department_namevarchar
divisionvarchar
cost_centervarchar
functionvarchar
parent_department_idvarchar

dim_job

Grain: one row per job/role per SCD2 version

SCD type 2

ColumnTypeKeys
job_keybigintPK
job_idvarcharBK
job_titlevarchar
job_familyvarchar
job_levelvarchar
is_manager_roleboolean
is_exemptboolean
eeo_categoryvarchar

dim_location

Grain: one row per work location

ColumnTypeKeys
location_keybigintPK
location_idvarcharBK
location_namevarchar
cityvarchar
statevarchar
countryvarchar
regionvarchar
work_modelvarchar
timezonevarchar

dim_manager

Grain: one row per manager per SCD2 version

SCD type 2

ColumnTypeKeys
manager_keybigintPK
manager_idvarcharBK
manager_namevarcharPII
manager_emailvarcharPII
management_levelvarchar
org_layersmallint

Relationships

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

  • fct_headcount_snapshot.date_key → dim_date (many-to-one)
  • fct_headcount_snapshot.employee_key → dim_employee (many-to-one)
  • fct_headcount_snapshot.department_key → dim_department (many-to-one)
  • fct_headcount_snapshot.job_key → dim_job (many-to-one)
  • fct_headcount_snapshot.location_key → dim_location (many-to-one)
  • fct_headcount_snapshot.manager_key → dim_manager (many-to-one)
  • fct_hire_termination.date_key → dim_date (many-to-one)
  • fct_hire_termination.employee_key → dim_employee (many-to-one)
  • fct_hire_termination.department_key → dim_department (many-to-one)
  • fct_hire_termination.job_key → dim_job (many-to-one)
  • fct_hire_termination.location_key → dim_location (many-to-one)
  • fct_compensation.date_key → dim_date (many-to-one)
  • fct_compensation.employee_key → dim_employee (many-to-one)
  • fct_compensation.department_key → dim_department (many-to-one)
  • fct_compensation.job_key → dim_job (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