Skip to content

Beginner · Planning an app · topic 6 of 34 · 30 min

Designing the data model

Explanation

A data model decides what things your app stores and how they connect. Each thing (a user, a note) becomes a table, its details become columns, and keys link the tables together. Getting this right early makes every later step easier.

From stories to data

Read your user stories and underline the nouns: student, note, title, tag. These nouns are clues to what the app must store.

An entity is one kind of thing you store, such as a user or a note. An attribute is a detail of that thing, such as a note's title or a user's email. In a database, each entity becomes a table and each attribute becomes a column.

Think of it like this: Think of a school office. There is a register of students (one row per student) and a register of library books issued (one row per issue). The issue register does not copy the student's full address; it writes the student's roll number. The roll number links the two registers. Database tables link the same way.

Keys: how rows find each other

A primary key is a column whose value is unique for every row, usually a number called id. A foreign key is a column that holds the primary key of a row in another table. In notes, the column user_id is a foreign key: it says which user owns the note.

Relationships

  • One-to-many: one user has many notes, but each note belongs to one user. Put user_id in the notes table.
  • Many-to-many: one note can have many tags, and one tag can be on many notes. You need a third table, note_tags, with one row per link (note_id, tag_id).
  • One-to-one: one user has one profile. Rare; often the columns just go in the same table.
TableColumnsLinks
usersid (PK), name, email (unique), password_hash, created_atone user has many notes
notesid (PK), user_id (FK), title, body, pinned, created_at, updated_atuser_id points to users.id
tags (Could)id (PK), name (unique)linked to notes through note_tags
note_tags (Could)note_id (FK), tag_id (FK); both together are the PKone row per note-tag pair

The table above is our ER diagram written as text. ER means Entity-Relationship: a drawing of the entities and the lines between them. On paper you would draw a box for each table and a line from notes.user_id to users.id, with "1" at the users end and "many" at the notes end.

sql
CREATE TABLE users (
  id INTEGER PRIMARY KEY,
  name TEXT NOT NULL,
  email TEXT UNIQUE NOT NULL,
  password_hash TEXT NOT NULL,
  created_at TEXT
);

CREATE TABLE notes (
  id INTEGER PRIMARY KEY,
  user_id INTEGER NOT NULL REFERENCES users(id),
  title TEXT NOT NULL,
  body TEXT,
  pinned INTEGER DEFAULT 0,
  created_at TEXT,
  updated_at TEXT
);
The two core tables of the Notes app (SQLite syntax).

Choosing types and timestamps

Pick the simplest type that fits. Text goes in TEXT. Whole numbers and ids go in INTEGER. SQLite has no true/false type, so pinned is stored as INTEGER: 1 for true, 0 for false. Timestamps (the date and time something happened) are stored as text in a fixed format such as 2026-02-01 08:00, so they sort correctly.

Add created_at and updated_at to almost every table. They cost little and help you sort ("newest first"), debug ("when did this change?") and answer users' questions.

Tip: Never store the password itself. Store password_hash: a scrambled value made by a hashing function. You will learn how in the authentication module.
Careful: Do not copy the same data into many tables (for example the user's name inside every note). When the name changes you must update every copy, and some will be missed. Store it once and link with a key.

Watch the lesson

Designing the data model · 1/7

Data model: what we store and how it links

Now we decide what the Notes app stores. This is called the data model.

Prefer a video by a teacher? Find free videos on “database design entity relationship diagram for beginners” on YouTube ↗

In real life: A kirana shop billing app

A small grocery shop wants a billing app. The entities are customers, products and bills. One customer has many bills (one-to-many: customer_id goes in bills). One bill has many products and one product appears on many bills (many-to-many), so there is a bill_items table with bill_id, product_id, quantity and price at that time. Storing the price in bill_items is important: when the price of sugar changes next month, old bills must still show the old price.

Practice (0/3 done)

Task 1 · Code · SQL

The users and notes tables are ready with sample data. Write a query that returns the title of every pinned note (pinned = 1), sorted by title A to Z.

Task 2 · Code · SQL

Show each note with the name of its owner. Return two columns, the note title and the user name, sorted by the note id. Use a JOIN from notes to users on the foreign key.

Task 3 · Code · SQL

Add tags (a many-to-many relationship). 1) Create tags(id INTEGER PRIMARY KEY, name TEXT UNIQUE NOT NULL). 2) Create note_tags(note_id, tag_id) with both columns as INTEGER NOT NULL foreign keys and PRIMARY KEY (note_id, tag_id). 3) Insert tags 1 "study" and 2 "travel". 4) Link note 1 to study, note 3 to travel and note 4 to study. 5) Finally select the titles of notes tagged "study", sorted by note id.

Quick quiz

Question 1

1.In the Notes app, why is user_id stored in the notes table?

Question 2

2.Notes can have many tags and tags can be on many notes. What do you need?

Question 3

3.How is the true/false pinned value stored in SQLite?

Question 4

4.Which column should NOT exist in the users table?

Question 5

5.What is a primary key?

Read more (free)

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

← Previous: Requirements and user stories