ByeBuy.ai
BUILD YOUR ESCAPE ROUTE · ✦ CURSOR · HOST IT · ◫ SUPABASE · CONNECT IT · ↯ RELAY · BUILD YOUR ESCAPE ROUTE · ✦ CURSOR · HOST IT · ◫ SUPABASE · CONNECT IT · ↯ RELAY ·
← BYEBUY NOTES

September 12, 2026

A DATABASE IS THE PART OF YOUR APP THAT REMEMBERS

A Database Is the Part of Your App That Remembers

Class 19 ended with a source map: a document that says what enters your product, who owns it, how fresh it is, and what to do when it fails. That map is a plan. It does not remember anything by itself.

This lesson gives your product its memory. A database preserves what the product must remember after the API response is gone, the browser tab is closed, and the model session ends.

Your source map says what enters. A database keeps what matters.

Think of the journey a single fact takes in Sonariq, the financial-research example running through this part of the course.

An SEC filing arrives as JSON from EDGAR — the SEC's public filing system, which serves company filing history and labeled financial facts your app can fetch. Your app reads it, picks out the company, the reporting period, the revenue figure, and the source URL. The user closes the laptop. A week later they return and ask: "What did we already find on this company?"

If the fact lived only in the API response, it is gone. If it lived only in the chat transcript, it is buried. If it lived in a database, the app can answer in milliseconds.

That is the whole idea. A source map describes the inputs. A database is the part of your app that remembers the outputs worth keeping.

Four places information can live — and only one remembers reliably

Beginners store things wherever is convenient. It helps to name the four options honestly:

StorageWhat it isWhat it remembersWhat it forgets
A fileMarkdown, JSON, or CSV on diskSmall, stable reference material; great for project context and source mapsWho changed what, which records connect, what is current when many users write at once
An API responseJSON returned by a provider right nowThe latest external fact at the moment you askEverything, the instant you stop holding it — it is a delivery, not a memory
Browser memoryState inside a running page: unsaved form inputs, loaded lists, chat history in the tabWhat the current visitor is doing right nowEverything on refresh, and everything belonging to other users
A databaseA managed store of structured records the app can save, update, connect, and queryProduct records with relationships: users, companies, reports, evidence, saves, historyNothing by design — forgetting is a deliberate deletion, not an accident

A file is right for a small static resource: a curated country list, a prompt template, your DATA-SOURCES.md. An API response is right for the moment of retrieval. Browser memory is right for the current screen. A database is right when records must be saved, filtered, connected, and updated across sessions and users — the test Class 18 introduced.

Most real apps use all four. The mistake is using the wrong one as the memory: keeping the user's saved research only in browser state, treating a re-fetched API response as history, or managing hundreds of connected records by hand-editing JSON files.

The vocabulary, taught through a saved-research app

Imagine the simplest version of Sonariq: a user saves research reports about public companies. Here is the vocabulary, each term anchored to that app:

  • Table: a named collection of the same kind of thing. companies is one table. research_reports is another.
  • Row (record): one entry in the table. One company is one row in companies. One saved report is one row in research_reports.
  • Column (field): one named attribute every row in the table has. ticker and sector are columns of companies.
  • Data type: the rule for what a field may hold. Text, integer, decimal, date, timestamp, true/false. Types make later questions — sorting by date, averaging numbers — possible.
  • ID: the stable identifier for a record, typically a number or generated string, that never changes even when everything else about the record does.

Here are the two tiny tables:

companies

idtickercompany_namesectorcreated_at
1AAPLApple Inc.Technology2026-03-02
2NOVO-BNovo Nordisk A/SHealthcare2026-03-02

research_reports

idcompany_idtitlereport_dateratingsource_url
1011Apple Q4 filing notes2026-02-10holdhttps://www.sec.gov/…/0000320193
1021Apple services-margin follow-up2026-03-01buyhttps://www.sec.gov/…/0000320193
1032Novo Nordisk pipeline review2026-02-20watchhttps://…/annual-report-2025

Notice company_id in the second table. Report 101 does not spell out "Apple Inc." It stores 1 — the ID of the company it belongs to. That stored pointer is called a foreign key, and Lesson 20.2 teaches it fully.

Why the ID matters more than the name

Company names change. Tickers change. Novo Nordisk could rebrand a division; Apple could rename a product line that your display shows prominently. If reports identified their company by name, every rename would orphan or corrupt history.

The ID solves this. Record 1 stays record 1 while names, tickers, and sectors evolve around it. Every report pointing at 1 still points at the right company. Names are for humans to read; IDs are for the system to remember. Text search cannot substitute: it breaks on renames, typos, and duplicates, while an ID either matches or it does not.

Store more than you display

Look again at the tables. A reader-facing report card might show only the title, date, and rating. The database row keeps much more: which company it belongs to, the exact source URL, when the record was created. A production row would typically also keep source_name, retrieved_at (when your app fetched the source — distinct from the report date), status (draft, published, superseded), owner_id (which user saved it), and period_end (the fiscal period described, because "reported in February" and "describes Q4" differ).

The rule: store what future questions will need, not only what the current screen shows. The screen shows five fields. The database keeps fifteen, because next month someone will ask "which claims came from this source?", "what did we know before March?", or "which of my saves are stale?" Provenance from Class 18 — source URL, owner, date, retrieval time — lives here, attached to each record, not in a separate document nobody opens.

What the user sees          What the database keeps
─────────────────           ──────────────────────────
Title, date, rating     →   + source URL, source name
                            + retrieved_at, period_end
                            + status, owner_id
                            + company_id (the link)

Do-now sketch workflow: from app to two tables in 15 minutes

The companies and research_reports tables above were not guessed. They came from this five-step workflow. Run it on paper before you touch any tool:

1. Pick one app. One sentence: "Sonariq saves research reports about public companies." 2. List two questions it must answer. "Which reports belong to this company?" and "What did we already find on this company, newest first?" 3. Name the tables. One table per kind of thing: companies (the thing that persists) and research_reports (the work done about it). Plural, lowercase, no spaces. 4. Give each table five fields with types. Copy the pattern from the tables above: every table gets an id (integer, never reused), one or two human names (ticker: text, title: text), one date (created_at: date, report_date: date), and — for the child table — the pointer (company_id: integer → companies.id). Every field gets a type on the same line: text, integer, date, timestamp, boolean. 5. Write the uniqueness sentence. "One row in companies is one company, and no two rows share the same ticker." "One row in research_reports is one saved report, and no two rows share the same id." If you cannot fill the blanks, the table is not defined yet.

This sketch is what you hand a coding agent. Not "make a database for stocks" but: "Create tables companies and research_reports with these five fields and types each; research_reports.company_id points at companies.id; one company per ticker." The agent writes syntax. You supply the app sentence, the two questions, and the uniqueness rule.

Bad sketch vs. fixed sketch

Beginners almost always produce the left version first. The fix is mechanical:

BAD: research_reports
  title | company_name | tag | image_url | button_label
  "Apple Q4 notes" | "Apple Inc." | "tech" | "…/img.png" | "View"
  "Apple services" | "Apple inc." | "tech" | "…/img2.png" | "View"
  Problem: no id, no types, company spelled two ways,
  no date to sort by, no pointer — two rows claim
  different companies that are the same company.

FIXED: research_reports
  id: integer | company_id: integer → companies.id
  title: text | report_date: date | rating: text
  101 | 1 | "Apple Q4 filing notes" | 2026-02-10 | hold
  102 | 1 | "Apple services-margin follow-up" | 2026-03-01 | buy
  Uniqueness: one row is one saved report,
  and no two rows share the same id.
  Company name lives once in companies; reports point at id 1.

When you run the Exercise below, check your draft against this contrast: if your five fields have no id, no date or timestamp, and no pointer or owner, you wrote the left column. Swap two display fields for an id and a date, add the uniqueness sentence, and you have the right column.

What a database is not

Three boundaries prevent expensive confusion later in this part:

1. A database is not a search engine. It answers precise questions — "all reports for company 1 since January" — perfectly. It does not rank by meaning. When a user phrases a question ten different ways, that is the retrieval problem Class 22 solves on top of stored records. 2. A database is not AI memory. A model's context window holds the current conversation. A database holds the product's durable records across all users and sessions. Retrieval systems copy selected database material *into* a model's context; the database itself does not think. 3. A database is not a data provider. EDGAR owns filings. FRED owns macro series. Your database holds *your copies and your work*: retrieved facts with provenance, user saves, your reports and judgments. The provider remains the source of truth for its facts; your database is the source of truth for what your product did with them.

Check your understanding

1. What survives a closed laptop: an API response, browser memory, or a database record? 2. In your own words, what is the difference between a row and a column? 3. Why does report 101 store company_id = 1 instead of the text "Apple Inc."? 4. Name two fields an app should store but not necessarily display — and the future question each one answers.

Exercise: sketch one table

Pick an app you actually use — a reading list, a workout log, a price watchlist, a support queue. Write a DATABASE-SKETCH.md file with:

  • The table name (plural, lowercase, e.g. saved_items).
  • Five fields, each with a data type (text, integer, date, timestamp, boolean).
  • One sentence stating what makes a row unique — the field or combination no two rows may share.

Finish line: a committed DATABASE-SKETCH.md you can read aloud: "one row is one ___, and no two rows share the same ___."

Verify: for three real examples from the app, fill in all five fields. Every example gets a distinct uniqueness value. If two examples collide, your uniqueness rule is wrong — refine it before continuing.

Common failure mode: choosing five display fields ("title, image, color, blurb, button label") with no ID, no timestamp, and no owner. If a field could not answer a future question, replace it with one that can.

What comes next

One table remembers one kind of thing. Real products remember several kinds of things that connect — companies *and* reports, users *and* saves, claims *and* sources. Next you will learn to design those connections around the questions your product must answer, instead of building one giant table shaped like the first screen.

ARTICLE DISCUSSION

JOIN THE
CONVERSATION.

0 COMMENTS

BYEBUY ACCOUNT ACCESS

Sign in

Use your account to save routes and make the catalogue yours.

Enter your email and we’ll send a secure sign-in link and code.

NEW ROUTES ADDED WEEKLY · 9,235 CATALOGUE ENTRIES · BUILD · DEPLOY · QUERY · STACK · SAY BYE TO BUY · NEW ROUTES ADDED WEEKLY · 9,235 CATALOGUE ENTRIES · BUILD · DEPLOY · QUERY · STACK · SAY BYE TO BUY ·