data-engineering

Kimball, Inmon, Data Vault, and OBT: Which Data Modeling Framework Fits Your Warehouse

Four frameworks, one warehouse — what each approach optimizes for, when it wins, when it loses, and how to combine them in a modern dbt stack without ending up with a shape nobody can maintain.

cat kimball-inmon-data-vault-obt-data-modeling-frameworks.md --meta
category: data-engineering  |  read_time: 19 min  |  published:  |  author: Rakesh Madala  |  views:
Side-by-side comparison of four data modeling frameworks — Kimball star schema, Inmon 3NF corporate information factory, Data Vault hub-link-satellite structure, and one big table (OBT)

Every data team eventually argues about modeling. The argument usually starts as a schema decision — "should this be a star or should we just flatten it?" — and ends as an identity question, because how you model your warehouse is really a statement about who it's for and what change looks like in your business.

Four frameworks show up over and over: Kimball's dimensional modeling, Inmon's corporate information factory, Data Vault, and — more recently — one big table (OBT). None of them is wrong. Each optimizes for a different property, and picking the wrong one for your context is how teams end up with a warehouse that is technically correct and practically unusable.

This post walks through what each framework actually is, what it buys you, what it costs, and how to combine them in a modern warehouse without ending up with the worst of every world.

Why Framework Choice Still Matters

"Just build tables that answer the questions" sounds reasonable and produces a warehouse where the same question returns three different answers by lunchtime. Framework choice matters because it forces you to decide, up front, a few things you'd otherwise re-decide table by table:

  • Where the business logic lives. In the raw layer? In a curated integration layer? In the consumption layer next to the dashboards? Every framework answers this differently, and the answer determines how easy it is to change a definition without breaking twelve downstream models.
  • How you absorb source-system change. A new field on the customer object, a renamed column, a system replatform — these are inevitable. Some frameworks isolate the raw shape from the analytics shape, so change happens in one layer. Others don't.
  • How you handle history. Whether the warehouse remembers what a customer's segment used to be — and how expensively — is a modeling decision, not a storage one.
  • Who can safely add a table. A framework with strong conventions lets a new engineer add a fact table on day two. A framework with no conventions turns every addition into a design review.

Cheap storage did not make these questions go away. It made it possible to postpone them, which is why so many warehouses that started as "we'll just use dbt and figure it out" now have four different definitions of active customer.

The Four Frameworks at a Glance

Before we go deep on each one, here's the shape of the argument. Each framework is really a set of answers to "where does raw data go, where does business logic go, and what do analysts query?"

Framework Core unit Optimizes for Cost you pay
Kimball Star schema — fact + conformed dimensions Analyst legibility, query performance, fast time-to-first-dashboard Business logic mixed into the analytics layer; harder to refactor
Inmon 3NF enterprise data warehouse feeding dependent data marts Single source of truth, integrated enterprise view Long build time; heavy up-front modeling; slow to change
Data Vault 2.0 Hubs, links, satellites in a raw vault, plus a Kimball-style business vault on top Auditability, source-system agility, parallel loading Many small tables; complex joins; steep learning curve
OBT (one big table) A single wide, denormalized fact-plus-attributes table BI-tool ergonomics, no-join queries, semantic-layer simplicity Storage bloat; painful history; hidden grain problems

A useful frame: Kimball asks "how should analysts see the world?", Inmon asks "how should the enterprise see the world?", Data Vault asks "how should the warehouse absorb change?", and OBT asks "how do we make the BI tool stop complaining?".

framework 01 / 04

Kimball — The Dimensional Approach

Ralph Kimball's dimensional modeling is the framework most working data engineers meet first, because it's the one the industry converged on for BI. The core unit is the star schema: a narrow, deep fact table holding measurements plus foreign keys, surrounded by wide, flat dimension tables holding context. Business logic is applied on the way into the marts; the resulting shape is designed to be read by an analyst without a data-modeling PhD.

what it looks like in a modern stack

sqlmodels/marts/finance/fct_revenue.sql
{{ config(materialized='incremental', unique_key='revenue_sk') }}

select
  {{ dbt_utils.generate_surrogate_key(['order_id','line_id']) }} as revenue_sk,
  o.order_sk,
  c.customer_sk,
  p.product_sk,
  d.date_sk,
  ol.quantity,
  ol.net_amount_inr,
  ol.discount_inr,
  ol.cogs_inr
from {{ ref('stg_order_lines') }} ol
left join {{ ref('dim_customer') }} c on c.customer_id = ol.customer_id and c.is_current
left join {{ ref('dim_product') }}  p on p.product_id  = ol.product_id  and p.is_current
left join {{ ref('dim_date') }}     d on d.date_actual  = ol.order_date
left join {{ ref('dim_order') }}    o on o.order_id     = ol.order_id
{% if is_incremental() %}
where ol._loaded_at > (select max(_loaded_at) from {{ this }})
{% endif %}

where it wins

Kimball is unbeatable for BI-first warehouses where the audience is analysts and the primary output is dashboards and metrics. The star schema is optimized both for columnar storage (small number of joins to well-clustered dimensions) and for the human reading the ERD. Slowly-changing dimensions handle history cleanly. Onboarding is fast — most analytics engineers already know it.

where it hurts

Business logic is baked into the marts. When the definition of "revenue" changes, you rebuild the mart; when the source system adds a field, you thread it through staging → intermediate → mart. Kimball is not designed to be a system of record, and it does not audit itself. If two dimensions disagree — because one snapshotted a bad batch and the other didn't — reconstructing what happened is up to you.

Side-by-side diagram comparing a Kimball star schema, with one wide fact_revenue table surrounded by five conformed dimensions, against an Inmon 3NF enterprise data warehouse, with many normalized entity tables in a spider web of foreign keys, feeding a downstream Kimball-shaped data mart
framework 02 / 04

Inmon — The Corporate Information Factory

Bill Inmon's approach predates the modern data stack by two decades but still turns up whenever a large organization needs a single, authoritative enterprise view. The idea is a top-down enterprise data warehouse (EDW) modeled in third normal form — one row per real-world entity, one attribute per column, foreign keys everywhere — that feeds downstream data marts, which are usually Kimball-shaped.

what it looks like in practice

Inmon warehouses are built entity-first: customer, account, product, contract, policy — each with its own table, keys to related entities, and no denormalization. Business definitions live in the EDW layer. Reporting doesn't run directly against the EDW; it runs against marts built on top of it. The EDW is the single source of truth; the marts are its consumption faces.

sqledw/customer.sql — a fragment of a typical 3NF EDW table
create table edw.customer (
  customer_id       bigint primary key,
  customer_type_id  int    references edw.customer_type,
  primary_address_id bigint references edw.address,
  household_id      bigint references edw.household,
  first_name        varchar(80),
  last_name         varchar(80),
  effective_from    date   not null,
  effective_to      date   not null,
  unique(customer_id, effective_from)
);
-- attributes that change frequently sit on satellite tables
-- (customer_contact, customer_preferences, customer_segment)

where it wins

Inmon is the right shape for organizations where the warehouse is a system of record — banks, insurers, telcos, regulated healthcare. The EDW gives you an unambiguous definition of every business entity, non-redundant storage, and a place to enforce enterprise-wide referential integrity. It's also the framework auditors are most comfortable with.

where it hurts

Time-to-first-dashboard is measured in quarters, not sprints. Every new source system has to be reconciled with the existing entity model before its data can flow through; every change to the entity model touches many tables. In a small team with fast-moving product data, an Inmon-style EDW is where dashboards go to wait.

In modern practice you rarely see a pure Inmon warehouse. The pattern more common today is Inmon-flavoured intermediate: a normalized, integrated layer between staging and marts, without the full CIF ceremony, that gives you the "one authoritative definition per entity" property without the two-year build.

framework 03 / 04

Data Vault 2.0 — Auditable and Adaptive

Data Vault, formalized by Dan Linstedt, is what you get when you optimize for change. Rather than modeling the business as it is today, it models the audit trail of how you learned about the business, then produces a Kimball-style consumption layer on top.

The raw vault has three shapes:

  • Hub — one row per unique business key. A hub table for customer holds nothing but the natural key, a hashed surrogate, the load timestamp, and the record source. Hubs never change.
  • Link — a many-to-many association between hubs. An order_customer_product_link row says "these three hubs were seen together on this order". Links, like hubs, are insert-only.
  • Satellite — descriptive attributes hanging off a hub or link, versioned by load_ts. A change to a customer's segment inserts a new satellite row; the old row is never updated. History is a query, not a snapshot job.
sqlraw_vault/hub_customer.sql
select
  {{ dbt_utils.generate_surrogate_key(['customer_id_source','source_system']) }} as customer_hk,
  customer_id_source        as customer_bk,
  current_timestamp()        as load_ts,
  source_system             as record_source
from {{ ref('stg_customer') }}
qualify row_number() over (partition by customer_hk order by load_ts) = 1

the business vault on top

Nobody queries the raw vault directly. On top of it sits a business vault that applies logic — deduplication, current-record flags, business rules — and, above that, a Kimball-style consumption layer of dims and facts that analysts and BI tools actually see. Data Vault does not replace dimensional modeling; it feeds it.

where it wins

Data Vault is the right shape when the warehouse is the system of record for change: financial services with heavy audit demands, healthcare where you need to reconstruct exactly what was known about a patient at any point in time, or any environment where source systems come and go faster than the analytics team can absorb. Loads are highly parallel (hubs, links, and satellites have no cross dependencies on each other), and every row carries provenance.

where it hurts

The learning curve is real. A modest business domain becomes hundreds of small tables; a single "customer with their latest segment" query has to join a hub, a satellite, and often a link. Without a Data Vault-aware tool (dbtvault, VaultSpeed, WhereScape) the boilerplate is exhausting. And because analysts always work off the consumption layer, you effectively maintain two warehouses.

Diagram of a Data Vault 2.0 raw vault showing hub_customer and hub_product hubs, a link_order association tying customer, product and order hubs together, and versioned satellite tables sat_customer_details and sat_product_price hanging off each hub with load_ts fields, plus a business vault and Kimball-style consumption layer sitting on top
framework 04 / 04

One Big Table (OBT) — The Modern Anti-Framework

OBT is what happens when a team builds warehouses for BI tools rather than for analysts writing SQL. Take a fact table, join it to every dimension you can think of, keep every attribute alongside every measurement, and materialize the result as one wide table. The BI tool never has to join anything. The semantic layer becomes a thin wrapper.

what it looks like

sqlmodels/marts/analytics/obt_orders.sql
{{ config(materialized='incremental', unique_key='order_line_id') }}

select
  ol.order_id,
  ol.line_id,
  ol.order_line_id,
  ol.order_date,
  ol.quantity,
  ol.net_amount_inr,
  ol.discount_inr,
  -- customer attributes, denormalized in
  c.customer_name, c.customer_segment, c.city, c.state,
  c.acquisition_channel, c.first_order_date,
  -- product attributes, denormalized in
  p.product_name, p.category, p.sub_category, p.brand,
  p.cogs_inr, p.list_price_inr,
  -- calendar attributes, denormalized in
  d.day_of_week, d.month_name, d.quarter, d.fiscal_year
from {{ ref('stg_order_lines') }} ol
left join {{ ref('dim_customer') }} c using (customer_id)
left join {{ ref('dim_product') }}  p using (product_id)
left join {{ ref('dim_date') }}     d on d.date_actual = ol.order_date

where it wins

OBT is the pragmatic answer when the consumer is Looker, Tableau, Power BI, or a metrics layer with limited join support, and when the warehouse is on modern columnar storage where wide tables compress well. There's no join blast radius, no dimension-conformance argument at dashboard time, and semantic layers on top become simpler because every measurement already carries its context.

where it hurts

OBT quietly hides two problems. First, grain drift: because there's no clean separation of measurements from context, a well-meaning engineer will add "monthly churn" as a column on an order-line table, and now half the rows have a value that doesn't correspond to the row's grain. Second, history: an OBT freezes attribute values at build time, so unless you rebuild the whole table you cannot answer "what was this customer's segment when this order was placed?" — the classic Kimball SCD Type 2 question — without deeply unpleasant workarounds.

Use OBT as a consumption layer sitting on top of properly modeled dims and facts. Do not use it as the primary storage shape of the warehouse.

Choosing a Framework

No framework is universally right, and the answer for most teams is a hybrid. Some diagnostics that actually work:

  • How many source systems, and how volatile? One or two stable sources → Kimball is enough. Ten sources, half of them mid-migration → Data Vault earns its complexity.
  • Who consumes the warehouse? Analysts writing SQL → Kimball. A BI tool with limited joins or a semantic layer → OBT on top of Kimball. Auditors and regulators → Data Vault or Inmon.
  • How important is historical reconstruction? "What did we know on Tuesday at 2pm?" is a Data Vault question. "What was this customer's segment at order time?" is a Kimball SCD question.
  • What's the team size? A three-person analytics team should not run Data Vault; the ratio of framework overhead to business value is wrong. Below ten people, Kimball with an Inmon-flavoured intermediate is almost always the right default.
  • How long is the warehouse expected to live? A three-year tactical build tolerates OBT and light Kimball. A ten-year enterprise warehouse absorbing many source-system replacements needs Data Vault's insulation.
Decision tree diagram for picking a data modeling framework — branching on how many source systems there are, whether the warehouse is a system of record with audit requirements, whether analysts query directly, and team size, leading to Kimball, Kimball plus OBT, Kimball plus Inmon-flavoured intermediate, or a full Data Vault plus Kimball combination

Combining Frameworks in a Modern Stack

In practice, most healthy warehouses run a hybrid. A common shape:

  1. Staging — one model per source table, light casting and renaming, no logic. Framework-agnostic.
  2. Raw Vault / Integration — either full Data Vault (hubs/links/satellites) for regulated or multi-source environments, or an Inmon-flavoured integration layer holding one canonical row per entity. This is where cross-source reconciliation happens.
  3. Marts — Kimball dims and facts, materialized as incremental or table models. Analysts query these directly; the definitions live here.
  4. Consumption / OBT — optional wide tables built on top of the marts for BI tools that struggle with joins, or for very hot analytical questions.

dbt makes this layering explicit through folder structure and ref(). Each layer has one job; the transition between them is a version-controlled model, not a stored procedure. And because every layer inherits from the one below it, replacing the integration layer (say, moving from Inmon-style to full Data Vault) does not require rewriting the marts.

shella hybrid dbt project layout
models/
├── staging/          # framework-agnostic; one model per source table
│   ├── crm/
│   ├── billing/
│   └── product/
├── integration/       # Data Vault raw + business vault, or Inmon 3NF
│   ├── raw_vault/
│   ├── business_vault/
│   └── entities/
├── marts/             # Kimball — dims and facts
│   ├── finance/
│   ├── product/
│   └── shared_dims/
└── consumption/       # optional OBT views for BI
    └── obt_orders.sql

If you can't say which folder a new model belongs in without a five-minute discussion, the framework is not landed yet — that discussion is the framework doing its job, one model at a time.

Common Mistakes

  1. Adopting Data Vault because a talk was persuasive. If your warehouse has two source systems and five analysts, Data Vault's overhead will bury you. Reach for it when a Kimball-first stack starts creaking under real source-system change, not before.
  2. Treating OBT as the storage layer. One big table is a consumption shape. When it becomes the only shape, you lose history, you lose grain discipline, and any change to an attribute triggers a full rebuild.
  3. Skipping the integration layer. Going straight from staging to marts saves an afternoon and costs a year. Without an integration layer, every mart re-implements the same joins and definitions, and they drift.
  4. Confusing Kimball with "just make a fact table". Dimensional modeling is a system: conformed dimensions, declared grain, SCDs, an unknown member, the works. A pile of fact tables that share no dimensions is not Kimball; it's chaos with jargon.
  5. Believing the framework will pick itself. Frameworks lose to inertia. The default in a team that hasn't picked one is "whatever the loudest engineer builds first" — and that becomes the shape of the warehouse whether it should be or not.

Wrapping Up

The four frameworks are not competitors so much as different answers to the question "what is the warehouse for?". Kimball optimizes for analysts. Inmon optimizes for the enterprise. Data Vault optimizes for change. OBT optimizes for BI tools.

Most modern warehouses run some combination of them: a Kimball marts layer that analysts and BI tools query, sitting on top of an integration layer that looks either Inmon-like (for small teams) or Data-Vault-shaped (for large, regulated, multi-source environments), sitting on top of framework-agnostic staging. OBT shows up as a consumption convenience on top, not the storage layer beneath.

Pick one as the primary shape, and be explicit about why. The framework is not the point; the point is that a warehouse where every table's role is obvious is a warehouse whose numbers you can defend at the next quarterly review. That's a modeling property, not a technology property, and no amount of cheap storage will produce it by accident.

— This article is part of an ongoing data-engineering series on techedge.in. Wrestling with a modeling choice? Drop a comment, I read every one.

A note on sources. Framework definitions here follow the primary published bodies of work — Ralph Kimball's The Data Warehouse Toolkit for dimensional modeling, Bill Inmon's Building the Data Warehouse for the corporate information factory, and Dan Linstedt's Building a Scalable Data Warehouse with Data Vault 2.0 for the vault approach. "One big table" is not attributable to a single author; the term is common in modern data-stack practice. Tooling notes reflect dbt behavior current at publication; verify syntax against the docs before shipping.

Rakesh Madala

10 years in the data field. Writing research-backed, no-nonsense guidance on the tools and roles that make up modern data teams.

More about the author ↗

Comments

All comments are reviewed before they appear publicly — this keeps spam out.

Loading comments…