One Résumé, Three Shapes — Relational · Document · Graph
A · Relational: tables + foreign keys
person
person_id PK
first_name
last_name
job
job_id PK
person_id FK
title
start_date
1
0..*
person_id
one row per thing; references must stay valid
listing a résumé = JOIN at read time
multi-object transaction keeps FK + indexes in sync
B · Document: one self-contained tree
resume (one JSON document)
_id
name
jobs: [
{ title, start_date },
{ title, start_date }
]
education: [ ... ]
skills: [ ... ]
job (embedded, not a table)
title
start_date
1
0..* embedded
all fields of one user live together — no join needed
denormalization: the résumé listing duplicates job data
updating duplicated copies needs a multi-object transaction
C · Graph: nodes and relationships are first-class
(:Person)
name
born
(:Company)
name
industry
(:City)
name
country
[:WORKS_AT
{since}]
[:LIVES_IN]
[:LOCATED_IN]
relationships carry data of their own ({since})
traversal cost depends on the query, not the schema
good fit when the data is all about how things connect
Same information, three shapes: the model decides which access patterns are cheap — and which ones need transactions or duplication.