What is Data Modeling?

Last updated: July 2026

Data modeling is a process of mapping entities, attributes, and relationships before deciding how a database will store them. The entities are the easy part — every product knows its users, orders, and posts. The craft is in the relationships: which records point at which, how many, and where that edge physically lives. Get the edges right and queries write themselves; get them wrong and every feature fights the schema.

Key takeaways

QuestionAnswer
The three levelsConceptual (what) → logical (structure) → physical (engine)
The three edgesOne-to-one · one-to-many · many-to-many
Relational toolsForeign keys; junction tables for many-to-many
Document toolsEmbedding, Pointers (references), Relations/ID arrays
The modern ruleModel for access patterns — data read together lives together

The same relationships, both worlds

Relational first — the foreign key carries one-to-many, and many-to-many must decompose through a junction:

-- 1:N — the foreign key lives on the "many" side
CREATE TABLE books (
  id        bigint PRIMARY KEY,
  title     text   NOT NULL,
  author_id bigint NOT NULL REFERENCES authors(id) ON DELETE CASCADE
);

-- M:N — no single FK can express it; a junction table holds both keys
CREATE TABLE book_genres (
  book_id  bigint REFERENCES books(id),
  genre_id bigint REFERENCES genres(id),
  added_at timestamptz DEFAULT now(),     -- junctions can carry attributes
  PRIMARY KEY (book_id, genre_id)         -- composite key: one edge, once
);

Document world, same model: the one-to-many edge is a typed Pointer, the many-to-many edge is a Relation — no junction table to invent, and the edge is declared in application code:

// JavaScript / Node.js — Back4app JS SDK
// One-to-many: a Pointer. Many-to-many: a Relation.
const author = await new Parse.Query('Author').get(authorId);

const book = new Parse.Object('Book');
book.set('title', 'Dune');
book.set('author', author);              // Pointer — typed one-to-many edge
await book.save();

const genres = book.relation('genres');  // Relation — many-to-many, unbounded
genres.add([sciFi, classics]);
await book.save();

Conceptual vs. logical vs. physical: the three levels

Conceptual, logical, and physical data modelsA conceptual model names entities and relationships for business discussion; the logical model adds attributes, types, and keys independent of technology; the physical model commits to tables or collections, indexes, and constraints in a specific database engine.

Conceptual
Author —writes→ Book
(what exists, for humans)

Logical
+ attributes, types, keys
(structure, engine-agnostic)

Physical
tables/collections, indexes,
constraints in one engine

A conceptual model names entities and relationships for business discussion; the logical model adds attributes, types, and keys independent of technology; the physical model commits to tables or collections, indexes, and constraints in a specific database engine.
DimensionConceptualLogicalPhysical
Question answeredWhat exists, how relatedWhat fields, what keysHow stored, how fast
AudienceEveryoneDesignersEngineers + the engine
ContainsEntities, relationships+ attributes, types, cardinality+ indexes, constraints, partitions
Changes whenThe business changesRequirements refineThe engine or scale changes

The discipline the levels enforce: don’t argue about indexes while the team still disagrees about what an “order” is.

Every relationship, every implementation

The table the SERP never built — each edge type with its implementation in both worlds:

RelationshipExampleRelational implementationDocument implementation
One-to-oneUser ↔ profileFK with UNIQUE, or same rowEmbed it — almost always
One-to-fewPerson → addressesChild table + FKEmbedded array (bounded)
One-to-manyAuthor → booksFK on the many sidePointer on the many side
One-to-enormousDevice → eventsFK + partitioningPointer on the child; never an array
Many-to-manyBooks ↔ genresJunction table, composite PKRelation or arrays of pointers
Self-referencingEmployee → managerFK to own tablePointer to own class

Cardinality notation, for reading diagrams: crow’s-foot draws a bar for “one” and a three-pronged fork for “many”; the ER tradition writes 1 and N on the lines; UML writes multiplicities like 1 and *. Three dialects, one grammar.

Normalize, denormalize, or embed?

Relational modeling starts from normalization — split data so every fact lives once, protecting writes from anomalies. Analytical and document modeling deliberately bend it: denormalization duplicates read-hot fields to kill joins, and embedding is denormalization’s document-native cousin. The embed-vs-reference checklist compresses to three questions: read together? owned by one parent? bounded in size? Three yeses embed; any no references. And over all of it, the modern rule that generalist guides skip: list the queries first. A model is correct when the access patterns it must serve are cheap — entities alone can’t tell you that.

Common use cases

  • Designing a new backend. The classic pass: name entities, draw edges, choose implementations per the table above — before the first line of code.
  • The junction-with-attributes pattern. Enrollments, memberships, line items — when the edge itself has data (date, quantity, role), the junction (or an edge class with two pointers) is a first-class entity.
  • Untangling a grown schema. Symptoms map to edges: duplicated rows reveal a mis-modeled many-to-many; document bloat reveals an unbounded embed.
  • Migrating between worlds. Relational→document means re-deciding every FK as embed vs. pointer; the table above is the translation dictionary.
  • AI and analytics feeds. Warehouses want the edges explicit and stable — modeling debt surfaces the day you try to export.

How should you model each edge? A decision matrix

Choose…When…Watch out for…
EmbedRead together, owned, boundedGrowth: today’s “few” becomes tomorrow’s thousands
Pointer / FKIndependent lifecycle, high cardinalityIndex it — every lookup and include pays
Relation / junctionMany-to-many, or the edge carries dataQuery direction: know which side you’ll ask from
Duplicate (denormalize)A read-hot field crossing an edgeUpdate fan-out — duplication is a debt with interest

Limitations and trade-offs

  • Models freeze assumptions. Cardinality decisions (“a user has one address”) become schema; cheap to change on paper, expensive after launch — model for tomorrow’s cardinality.
  • Both worlds punish the unindexed edge. FK columns and pointer fields are join paths; forgetting their indexes is the most common silent performance bug.
  • Embedding trades integrity for locality. No engine enforces that an embedded copy stays consistent with its source — that’s your update logic now.
  • Junctions multiply joins; relations hide them. Every many-to-many read crosses the edge store — budget the query path, whichever world you’re in.
  • Access-pattern modeling has a cost too. Optimizing for today’s queries can wed the schema to today’s product; keep the conceptual model around as the neutral ground truth.

Data modeling on Back4app

Back4app is an open-source Backend-as-a-Service (BaaS) platform that combines a managed database, auto-generated REST and GraphQL APIs, authentication, file storage, and Cloud Code serverless functions. Its modeling vocabulary is the document column of the tables above, made first-class: Pointers are typed one-to-many edges, Relations carry many-to-many without a hand-built junction, and arrays cover the bounded-few. Every edge you declare is immediately traversable — include() walks pointers in one request, GraphQL nests relations in one query — and the schema stays visible and editable in the dashboard, so the physical model never drifts out of sight of the team that designed the conceptual one.

Frequently asked questions

What is data modeling?

The process of mapping an application's information — its entities, their attributes, and the relationships between them — into a design a database can store. It typically moves through three levels of detail: a conceptual model naming the entities, a logical model adding attributes and keys, and a physical model committing to tables, columns, and indexes in a specific engine.

What are the three types of data models?

Conceptual, logical, and physical — the same design at increasing zoom. Conceptual answers "what exists and how does it relate" for business stakeholders. Logical adds attributes, types, and keys while staying technology-agnostic. Physical commits to an actual engine: tables or collections, indexes, constraints. Each level is the previous one plus decisions.

What is a one-to-many relationship?

One parent record relating to many children, each child belonging to exactly one parent — a customer and their orders, an author and their books. It is the most common relationship in any schema. Relational databases implement it with a foreign key on the many side; document databases use an embedded array for small bounded sets or a pointer to the parent for everything else.

What is a many-to-many relationship and why does it need a junction table?

Both sides relate to many of the other — students and courses, books and genres. A single foreign-key column can only point at one row, so relational databases decompose many-to-many into two one-to-many relationships through a junction table holding both keys (and often relationship attributes like an enrollment date). Document databases skip the junction: arrays of references, or a dedicated relation type, carry the edge directly.

How do I tell one-to-many from many-to-many?

Ask the ownership question in both directions. "Can one author have many books?" Yes. "Can one book have many authors?" If no — one-to-many, foreign key on the book. If yes — many-to-many, junction table or relation. Getting this wrong is the classic modeling mistake: a many-to-many modeled as one-to-many either duplicates rows or silently loses edges.

What is cardinality in an ER diagram?

How many instances of one entity can relate to instances of another — one-to-one, one-to-many, many-to-many. Diagrams express it in one of three notations: numbers and letters on the connecting lines, crow's-foot symbols (a bar for one, a three-pronged fork for many), or multiplicity ranges like 1 and asterisk. Same semantics, different drawing conventions.

How do document databases model relationships without foreign keys?

With three tools: embedding (nest the related data inside the parent document — right when it is read together, owned, and bounded), pointers or references (store the related document's ID as a typed field — right for independent lifecycles and high cardinality), and relation objects or ID arrays for many-to-many. The guiding rule flips from normalization to access patterns: data read together should live together.

What are the most common data modeling mistakes?

A stable top five: modeling many-to-many as one-to-many; forgetting indexes on foreign-key and pointer fields (every join and lookup pays); unbounded embedded arrays in document schemas; premature denormalization before any query proved slow; and modeling from the entities alone without listing the queries — the access patterns — the model must serve.

Related terms

Compare with

Further reading

Ready to build your backend?

Start your project on Back4app in minutes — database, auth, APIs, and Cloud Code included. No credit card required.

Written and reviewed by Back4app Engineering, Back4app Engineering · Published 2026-07-25