← bryan.dev / writing
Complete Visual Training

Object-Oriented Databases — From Zero to Hero

A practical, visual guide that takes you from "what even is a database?" to confidently reasoning about object models, identity, navigation, inheritance, and how modern systems like Workday persist data as objects rather than rows. Built for analysts, BI developers, and anyone who keeps hearing the term but has never had it explained from the ground up.

10Modules
35+Diagrams & Tables
0 → HeroSkill Path
No code backgroundrequired
MODULE 01 Beginner

What Is a Database, Really?

In this module: A working definition · Why we need databases at all · The five families of databases · Where object-oriented sits

A database is just an organised collection of data that a computer can read from and write to efficiently, reliably, and concurrently. That's it. Everything else — tables, objects, JSON documents, graphs — is a way of organising that data.

The hard part isn't storing data. The hard part is asking: how do we shape the data so that the questions we want to ask are easy and fast to answer? Different "shapes" became different families of databases.

The Five Families of Databases

DATABASE "organised data" Relational (SQL) Rows in tables Postgres · MySQL · SQL Server Document JSON-like documents MongoDB · Couchbase Key-Value Hash map at scale Redis · DynamoDB Graph Nodes & edges Neo4j · Neptune Object-Oriented Objects, just like in code
Figure 1.1 — The database family tree. This guide focuses on the bottom-center: object-oriented databases.

What Every Database Must Do (ACID)

No matter the shape, a "real" database must guarantee four things — known by the acronym ACID:

LetterMeansExample
AtomicityA transaction either fully happens or doesn't happen at all.Transferring £100 between accounts can't deduct from one without crediting the other.
ConsistencyThe database always moves from one valid state to another.If a worker must have a position, the DB rejects a half-saved worker.
IsolationConcurrent transactions don't see each other's half-done work.Two payroll runs can't read the same row at the same time and double-pay someone.
DurabilityOnce a transaction commits, it survives crashes, power loss, etc.Your hire decision doesn't vanish when the server reboots.
Mental model Think of a database as the world's most paranoid filing cabinet: it lets many people add/change/read at the same time, but never loses anything and never lets the filing system contradict itself.
MODULE 02 Beginner

Relational Databases & Their Limits

In this module: Relational refresher · The "impedance mismatch" · Why pure relational struggles with rich data · Worked example

If you've used Excel, you've used something shaped like a relational database. A relational DB stores data in tables (rows + columns), connects tables via keys, and lets you query with SQL. It's the dominant shape since the 1970s — and for very good reason.

Quick Refresher

workers id first_name last_name manager_id 10042 Jane Doe 10043 10043 Mark Lee (null) 10044 Priya Patel 10043 Primary Key: id · Foreign Key: manager_id → workers.id positions id title worker_id (FK) P-1024 Senior Analyst 10042 P-1025 Eng Manager 10043 P-1026 Engineer 10044 FK worker_id links each Position to a Worker
Figure 2.1 — Relational. Two tables joined by a foreign key. Clean, mathematical, very fast.

So Why Did Anyone Invent Anything Else?

The problem starts when your real-world thing doesn't fit cleanly in a flat table. Imagine a single Worker that has:

  • multiple addresses (home, mailing, emergency)
  • multiple phone numbers (mobile, home, work)
  • multiple skills (each with a proficiency level)
  • multiple dependents
  • multiple compensation plans (salary + bonus + stock)
  • a manager who has all of the above too

In code you'd model this as a single Worker object with arrays of child objects inside it. In a relational database, you have to shred that one rich object into 7+ tables and then re-assemble it with joins every time you load it. That gap between "how the program thinks" and "how the DB stores" is famous enough to have a name: the object-relational impedance mismatch.

The Impedance Mismatch — Pictured

In application code Worker { name, hireDate, ... addresses: [...] phones: [...] skills: [...] dependents: [...] } shred & flatten ⚡ mismatch ⚡ In relational tables workers addresses (FK worker_id) phones (FK worker_id) worker_skills (FK worker_id, FK skill_id) skills dependents (FK worker_id) 6 tables · 5 joins to reassemble one Worker
Figure 2.2 — The impedance mismatch: one rich object on the left becomes many flat tables on the right.
Why this matters Developers spent decades writing "translation layers" (ORMs — Object-Relational Mappers like Hibernate, Entity Framework) just to bridge this gap. Object-oriented databases said: what if we just stored the object as-is?

Where Relational Still Wins

None of this means relational is bad — it remains the right choice for most reporting, analytics, and transactional workloads. Set-based math on rows-and-columns is genuinely powerful, and SQL is the most widely understood data language on earth. The point is just: it's not the only shape, and for richly-nested, deeply-related data, a different shape can be simpler.

MODULE 03 Beginner

Meet the Object

In this module: What an object actually is · Class vs Instance · Attributes & Methods · A real-world analogy

Before we can talk about an object-oriented database, we need to be crystal-clear on what an object is. If you've never written code, this is the chapter that demystifies it.

The Recipe Analogy

Imagine a recipe for chocolate cake. The recipe is not a cake — it's a description of how to make one. When you bake one, you get an actual cake. You can bake many cakes from the same recipe; each cake is its own thing (you can eat one without affecting another), but they all share the recipe's structure.

Recipe = Class

A template. Defines what attributes (ingredients) every cake has and what methods (bake, slice, frost) can be done to it.

Each Cake = Instance (Object)

A real, individual thing produced from the recipe. Each instance has its own specific values for the attributes.

Anatomy of an Object

CLASS: Worker — ATTRIBUTES (data) — • name: Text • hireDate: Date • position: Position • salary: Money — METHODS (behaviour) — → promote(newTitle) → calculatePay() → terminate(date) creates INSTANCE (an object) name: "Jane Doe" hireDate: 2021-04-12 position: → P-1024 Sr Analyst salary: £70,000 jane.calculatePay() → returns £5,833.33
Figure 3.1 — A Class is the template; an Instance is one concrete thing built from it. Attributes hold data; methods do things.

The Two Things Inside Every Object

PartWhat it isWorker example
Attributes (also: fields, properties)The data the object remembers.name, hireDate, salary, position
Methods (also: functions, behaviours)The things the object can do.promote(), terminate(), calculatePay()
The big shift Relational thinking: "data lives in tables; logic lives in application code." Object thinking: "data and the logic that knows how to use it live together, in one bundle." That bundle is the object.

A Mental Model You Can Reuse Forever

Throughout the rest of this guide, whenever you see "object" think:

// An object is just:
{
  attributes: { stuff it knows },
  methods:    { stuff it can do },
  identity:   "its unchanging name in the universe"  // ← we'll come back to this
}
MODULE 04 Intermediate

The Four Pillars of Object-Orientation

In this module: Encapsulation · Inheritance · Polymorphism · Identity. The four ideas that make something truly "object-oriented".

Object-orientation isn't just "data in a bundle". It rests on four specific ideas. Memorise these and you'll understand every OO database, framework, and Workday concept that follows.

Encapsulation

Bundle data and behaviour together. Hide internals behind a controlled interface.

Inheritance

Build new types by extending existing ones. Share what's common; override what differs.

Polymorphism

Same call, different behaviour depending on the type of the object.

Identity

Every object has a unique, unchanging identity, regardless of its values.

1 · Encapsulation — the Bundle

Encapsulation packs an object's data + the rules for changing that data into one capsule. Outside code can ask the capsule to do things, but can't reach in and break it.

// Without encapsulation — anyone can mess with salary:
worker.salary = -10000;  // ← oops, allowed

// With encapsulation — the object guards itself:
worker.giveRaise(5000);  // the method validates, audits, then applies

2 · Inheritance — the Family Tree

If two types of object share a lot in common, you can define the common parts once in a parent class, then create child classes that inherit and only add what's different.

Worker name · hireDate · pay() Employee + salary · + PTO Contractor + hourlyRate · + endDate Intern + school · + endDate Manager (extends Employee)
Figure 4.1 — Inheritance: Employee, Contractor, Intern all are Workers. Manager is an Employee.

3 · Polymorphism — Same Verb, Different Outcome

"Polymorphism" sounds intimidating but means something simple: the same method name can do different things depending on the object's actual type.

// All three are Workers. Same call, different logic:
employee.pay()     base salary / 12
contractor.pay()   hourlyRate × hoursWorked
intern.pay()       fixed stipend

// You can write code that just says "pay everyone" and
// the right calculation runs for each one. That's polymorphism.
for (w in allWorkers) w.pay();

4 · Identity — the Hidden Star of OODB

This is the one that matters most for databases. Every object has an identity — a permanent, unique label — that is separate from its data. Two objects can have identical attributes (same name, same hire date) and still be different objects, because they have different identities.

Worker name: "John Smith" hireDate: 2024-03-01 OID: obj-7F3A92BC Worker name: "John Smith" hireDate: 2024-03-01 OID: obj-9C2E11A4 Same attributes ≠ same object. Different OIDs = different people.
Figure 4.2 — Two different John Smiths hired on the same day. Identity is what tells them apart.
Hold this thought Identity is the single biggest difference between relational and object-oriented thinking. We give it its own module (#6).
MODULE 05 Intermediate

What Makes a Database "Object-Oriented"?

In this module: Definition · Persistence · The OODB manifesto · Object DB vs ORM (key distinction)

An Object-Oriented Database (OODB) stores data as objects — with their attributes, methods, relationships, inheritance, and identity intact — instead of flattening them into tables. In other words: it speaks the same language as your application code.

The Core Idea: Persistence Without Translation

Without OODB (relational + ORM) Worker object in memory ORM translates SQL INSERT across 6 tables Relational DB stores rows With OODB Worker object in memory save() no translation OODB stores the object as-is
Figure 5.1 — OODBs eliminate the translation layer. Objects persist directly.

The OODB Manifesto (1989) — Plain English Version

In 1989, a group of researchers (Atkinson, Bancilhon, DeWitt, Dittrich, Maier, Zdonik) published The Object-Oriented Database Manifesto, listing 13 features a "real" OODB must have. Here they are, paraphrased:

  1. Complex objects — supports nested types (lists, sets, tuples of objects).
  2. Object identity — every object has a unique OID independent of attribute values.
  3. Encapsulation — objects expose methods; internals are hidden.
  4. Types & classes — has a type system that the DB understands.
  5. Inheritance — classes can extend other classes.
  6. Overriding + late binding — polymorphism works.
  7. Computationally complete — you can express any computation, not just queries.
  8. Extensibility — users can define new types.
  9. Persistence — any object can be made to survive program shutdown.
  10. Secondary storage management — handles indexes, buffering, clustering automatically.
  11. Concurrency — multiple users at once (ACID).
  12. Recovery — survives crashes.
  13. Ad-hoc query facility — a query language (usually OQL).

OODB vs ORM — Don't Confuse Them

An ORM (Object-Relational Mapper) like Hibernate or Entity Framework lets your code look object-oriented while the data still lives in a relational database underneath. An OODB is the database itself being object-oriented.

OODBORM over Relational
Storage shapeObjectsTables (rows + columns)
Translation layerNoneThe ORM library
Inheritance, methodsNativeSimulated
Query languageOQL / path-basedSQL + ORM API
Performance for nested objectsExcellentMany joins, often slow
Performance for set-based analyticsVariableExcellent (SQL strength)
Examplesdb4o, ObjectDB, Versant, Objectivity/DBHibernate + Postgres, EF Core + SQL Server
Where Workday sits Workday is widely described as having an "object-oriented data model" running on top of in-memory architecture. From the user/report-builder's perspective it behaves exactly like an OODB — you query Worker, Position, Cost Center as objects with native relationships — even though the underlying persistence layer is more nuanced.
MODULE 06 Intermediate

Object Identity (OID) — the Secret Sauce

In this module: OID vs primary key · Equality vs identity · Why it matters for references · Real-world consequences

Of the four pillars, identity is the one that transforms an object system into an object database. Understanding OID is what separates surface-level knowledge from real comfort.

OID vs Primary Key

Primary Key (Relational)OID (Object-Oriented)
What it isA column value you choseAn internal identity assigned by the system
Visible to users?Yes — you see it ("EMP-10042")Usually hidden — system-generated
Can it change?Yes (sometimes painfully)Never. OID is immutable.
Derived from data?Often (e.g., SSN)Independent of data
Uniqueness scopeWithin a tableAcross the entire database
Used for joins?Yes — JOIN ON idNo — direct references replace joins

Equality vs Identity — the Most Useful Distinction in OO

This trips up almost everyone the first time. There are two different questions you can ask about two objects:

Equality (==)

"Do they have the same values?" Two coins of the same denomination are equal.

workerA.name == workerB.name
        // might be true

Identity (===)

"Are they literally the same object?" Even two identical coins are different coins.

workerA === workerB
        // only true if same OID

Why This Matters in a Real System

Imagine you change Jane Doe's last name (after marriage). In a relational world, you update the row — and any code that compared by name silently breaks. In an OODB world, her OID never changes, so every reference to her object still points to the right person.

Before Worker name: "Jane Doe" OID: obj-7F3A92BC Project Assignment assignee → obj-7F3A92BC → resolves to Jane Doe ✓ marriage name change After Worker name: "Jane Smith" OID: obj-7F3A92BC (unchanged) Project Assignment assignee → obj-7F3A92BC → resolves to Jane Smith ✓
Figure 6.1 — Identity survives data changes. References never break.
Workday parallel Workday assigns every Business Object instance a permanent WID (Workday ID) — its OID. You can rename a worker, restructure an org, or merge cost centers, and every integration that uses WIDs continues to resolve correctly. This is why integration teams prefer WIDs over user-facing IDs.
MODULE 07 Intermediate

Relationships — References & Navigation

In this module: Direct references vs foreign keys · Walking the object graph · 1:1, 1:many, many:many · Bidirectional links

In a relational database, two tables relate via a foreign key — a column whose values point to another table's primary key. You stitch them together at query time with JOIN. In an OODB, an object simply holds a reference to another object, the way a variable in code holds a pointer. There's no join — you just walk the reference.

The Big Picture

Relational: JOIN workers id (PK) position_id (FK) positions id (PK) title Query: SELECT w.name, p.title FROM workers w JOIN positions p OODB: Navigation Worker name position → Position title Code: worker.position.title // just walk the reference
Figure 7.1 — Relational stitches tables together at query time. OODB pre-stitches them via references.

One-to-One, One-to-Many, Many-to-Many

All three exist in OODBs, expressed as either a single reference or a collection of references.

CardinalityHow it's modelledWorker example
One-to-OneA single referenceworker.primaryPosition → Position
One-to-ManyA collection (set/list)worker.dependents → [Dependent, Dependent, ...]
Many-to-ManyCollections on both sidesworker.projects → [Project] AND project.workers → [Worker]

Bidirectional References

OODBs can maintain references both ways automatically. If you set worker.manager = mark, the system can also add worker to mark.directReports. Relational systems have to be told the same thing in two places — easy to get wrong.

Walking the Object Graph

// Find the email of Jane's manager's manager:
jane.manager.manager.workEmail

// Same thing in SQL:
SELECT m2.email
FROM workers w
JOIN workers m1 ON m1.id = w.manager_id
JOIN workers m2 ON m2.id = m1.manager_id
WHERE w.id = '10042';
Workday parallel Workday's "dot-walking" in calculated fields and report writer (Worker → Manager → Work Email Address) is exactly this. You're navigating an object graph, not joining tables.
MODULE 08 Advanced

Inheritance & Polymorphism Inside the Database

In this module: Class hierarchies as first-class DB concepts · Polymorphic queries · The "Worker is the parent" pattern

In Module 4 we met inheritance as a code concept. The killer feature of an OODB is that the database itself understands class hierarchies. You can query a parent class and get back instances of every subclass — no UNION required.

A Hierarchy Stored in the Database

Worker name · hireDate · pay() Employee + salary · + PTO Contractor + hourlyRate · + endDate Intern + school SELECT * FROM Worker → returns ALL three subclass types 8,432 Employees 412 Contractors 28 Interns All polymorphically returned as "Worker" — each with its own subclass fields available
Figure 8.1 — Polymorphic query: ask for the parent, get all children.

Why This Is Powerful

  • One report writer query can produce headcount across every worker type without UNION ALL.
  • New subclasses appear automatically in existing reports if they extend the parent.
  • Subclass-specific fields are visible only on instances that have them — no NULL columns.
  • Methods like pay() resolve to the right calculation for each subclass automatically.

Filtering by Subclass

You can narrow the query to a specific subclass when you need to:

// All workers
SELECT w FROM Worker w

// Just contractors (subclass filter)
SELECT w FROM Worker w WHERE w IS Contractor

// Employees hired in 2025
SELECT w FROM Worker w
WHERE w IS Employee AND w.hireDate >= '2025-01-01'
Workday parallel Run a Workday report on the "Worker" business object and you'll see both employees and contingent workers in one result — a textbook example of polymorphic querying. Add a filter on "Worker Type" to narrow to one subclass.
MODULE 09 Advanced

Querying an OODB — OQL & Path Expressions

In this module: What OQL is · Path expressions · Method calls in queries · Side-by-side SQL vs OQL examples

OQL (Object Query Language) is to OODBs what SQL is to relational databases. It was standardised by the ODMG group and deliberately keeps SQL-style syntax so that anyone who knows SQL can pick it up fast. The big additions are path expressions (dot-walks) and method calls.

OQL by Example

// 1. Simple: all workers' names
SELECT w.name FROM Worker w

// 2. Path expression: walk references inline
SELECT w.name, w.position.title, w.position.costCenter.name
FROM Worker w

// 3. Call a method on each object
SELECT w.name, w.tenureInYears()
FROM Worker w
WHERE w.tenureInYears() > 5

// 4. Iterate over a collection inside an object
SELECT d.name
FROM Worker w, w.dependents d
WHERE w.name = 'Jane Doe'

// 5. Nested results: structure-preserving
SELECT struct(
  manager: w.manager.name,
  team:    (SELECT r.name FROM w.manager.directReports r)
)
FROM Worker w
WHERE w.name = 'Jane Doe'

The Two Big Differences from SQL

Path expressions

No JOIN — you just dot-walk. w.position.costCenter.name reads exactly like the object graph you drew.

Method calls

Queries can invoke object behaviour. w.tenureInYears() runs the method defined on the class, no view or function needed.

Side-by-side: SQL vs OQL

QuestionSQLOQL
Worker name + manager email SELECT w.name, m.email FROM workers w JOIN workers m ON m.id = w.manager_id SELECT w.name, w.manager.email FROM Worker w
Workers with > 3 dependents Subquery counting child rows SELECT w FROM Worker w WHERE count(w.dependents) > 3
Workers earning more than their manager Self-join + comparison SELECT w FROM Worker w WHERE w.salary > w.manager.salary
The takeaway OQL isn't replacing SQL out there in the world — but the dot-walk style it pioneered shows up everywhere now: Workday's Report Writer, GraphQL queries, MongoDB's nested document queries, even modern JavaScript optional chaining. Learning to think in paths is a transferable skill.
MODULE 10 Advanced

OODB in Practice — Where You'll See It Today

In this module: Pure OODBs · Workday's data model · Modern document & graph DBs · ORMs · How to choose

Pure object-oriented databases are a small but real niche today. More importantly, the ideas from OODB are now everywhere — in document stores, graph stores, ORMs, and enterprise platforms like Workday. Knowing OODB makes all of those easier to learn.

The Landscape Today

Pure OODBs db4o · ObjectDB · Versant · Objectivity/DB Niche: telecoms, scientific, real-time trading Native objects + OQL Enterprise OO Models Workday · Salesforce · ServiceNow User-facing OO data model + custom storage Massive scale, you query as objects Document DBs (close cousin) MongoDB · Couchbase · Firestore Store nested JSON ≈ objects Missing: classes, methods, inheritance Graph DBs Neo4j · TigerGraph · Neptune Nodes + edges = identity + references Excellent at traversal, less at strict typing ORMs over Relational (most common pattern in software today) Hibernate · Entity Framework · Django ORM · SQLAlchemy · Prisma Your code thinks objects · the DB stores rows · ORM bridges the gap
Figure 10.1 — The "OO ideas" are everywhere; pure OODBs are just one corner of the landscape.

Why Workday Is the OODB You'll Most Likely Touch

If you're working in HR analytics, Workday is the largest object-oriented data model most people will ever interact with. Everything we've covered shows up directly:

Concept (this guide)What it's called in Workday
ClassBusiness Object (Worker, Position, Cost Center…)
InstanceAn individual record (a specific worker, a specific position)
OIDWID (Workday ID)
AttributeField
MethodCalculated Field / Business Process action
ReferenceReference field — the basis of "dot-walking"
Path expressionWorker → Manager → Work Email Address in Report Writer
InheritanceWorker is the parent of Employee and Contingent Worker
Polymorphic query"All Workers" data source returning both subtypes

When Should You Choose an OODB (or OO Model)?

Good fit

  • Deeply nested, richly related domain (HR, finance, CAD, telecom)
  • Application thinks in objects all day
  • Heavy navigation, light set-math
  • Many subtypes that share a parent

Bad fit

  • Big aggregations across millions of rows (use a warehouse)
  • Wide ecosystem of BI & SQL tools required
  • Frequent ad-hoc reporting by non-developers
  • Cross-domain analytics blending unrelated systems
The pragmatic reality Most production stacks today are hybrids. The transactional system is OO-shaped (Workday, Salesforce, an ORM over Postgres). The analytics layer is a relational warehouse (Snowflake, BigQuery, Synapse) fed by extracts from the OO system. Knowing both shapes makes you the bridge.
★ CHEAT SHEET Quick Reference

One-Page OODB Cheat Sheet

Relational ↔ OODB translation

TableClass
RowInstance (object)
ColumnAttribute
Primary KeyOID
Foreign KeyReference
JOINPath expression / navigation
SQLOQL
Stored ProcedureMethod on the class
View(no equivalent — methods replace)
UNION across child tablesPolymorphic SELECT on parent

Workday ↔ OODB translation

Business ObjectClass
InstanceObject instance
WIDOID
FieldAttribute
Reference FieldReference
Dot-walkPath expression
Calculated FieldMethod
Data SourcePolymorphic query result
Worker (parent BO)Parent class
Employee / ContingentSubclasses

The four pillars (memorise)

  • Encapsulation — data + behaviour in one bundle
  • Inheritance — children extend parents
  • Polymorphism — same call, different result by type
  • Identity — every object has a permanent OID

When to pick what

Rich nested dataOODB / Document
BI & ad-hoc analyticsRelational warehouse
Relationship traversalGraph DB
Cache / sessionsKey-Value
Enterprise HR/Fin appOO model (Workday)

Glossary

ObjectA bundle of attributes (data) and methods (behaviour) with a unique identity.
ClassThe template/blueprint from which objects are created.
InstanceA concrete object created from a class.
AttributeA piece of data on an object (a.k.a. property, field).
MethodA behaviour the object can perform.
EncapsulationBundling data + behaviour and hiding internals behind an interface.
InheritanceBuilding new classes by extending existing ones.
PolymorphismSame operation behaves differently depending on the object type.
Identity / OIDA permanent, system-generated unique label for each object.
ReferenceA pointer from one object to another (replaces foreign keys).
Path expressionWalking a chain of references inside a query (worker.manager.email).
OQLObject Query Language — the SQL-like language for OODBs.
ORMObject-Relational Mapper — a library that makes a relational DB look object-oriented to code.
Impedance mismatchThe friction between object-shaped code and table-shaped storage.
PersistenceThe ability of objects to survive program shutdown and live in the DB.
Polymorphic queryA query on a parent class that returns instances of all child classes.
Your next steps Re-open the Workday Zero-to-Hero guide — you'll now read every Business Object, dot-walk, and calculated field through OO eyes. That mental model carries over to MongoDB, Salesforce, GraphQL, and modern ORMs. The vocabulary changes; the ideas don't.