Module 1: Foundations of SQL and the Relational Model ⏱ 18 min

Why SQL — the Language of Data

By the end of this lesson you will be able to:
  • Explain what a relational database is and why SQL is how you query it
  • Read the rows-and-columns structure of a table and predict what SELECT returns
  • Run your first real queries against a live in-browser database

Almost every application you touch — your bank, your playlist, the form you just filled in — is a thin skin over a database. The buttons and pages exist to collect and show information; the database is where that information actually lives, quietly remembering it between visits.

SQL (Structured Query Language) is how you ask a database questions, and it has done that job for fifty years across Postgres, MySQL, SQLite, BigQuery, and Oracle. The query you write against the toy database in this lesson would run, almost unchanged, against a billion-row warehouse.

That makes SQL the most portable skill in this entire course. Analysts, backend engineers, data scientists, and product managers all reach for it. You learn the ideas once and carry them between companies, languages, and decades.

flowchart LR
  APP["An application"] --> DB[("Database")]
  DB --> T1["departments"]
  DB --> T2["employees"]
  DB --> T3["projects"]
  style DB fill:#0e7490,color:#fff
  style APP fill:#3776ab,color:#fff
One database holds many tables; each table keeps a single kind of fact.

The relational mental model

A relational database stores information in tables — grids of rows and columns, much like a spreadsheet, but with rules that keep the data trustworthy. Each table holds one kind of thing, and each row in that table describes one individual.

The database for this course has three tables:

  • departmentsid, name, city
  • employeesid, name, department_id, role, salary, hired_on
  • projectsid, name, department_id, status, budget

A row is one record — Ada Nilsen, a specific engineer. A column is one attribute shared by every record — salary, the amount each person earns. Keeping those two words straight is what makes every error message ahead of you readable.

erDiagram
  DEPARTMENTS ||--o{ EMPLOYEES : "has"
  DEPARTMENTS ||--o{ PROJECTS : "owns"
  DEPARTMENTS {
    int id
    text name
    text city
  }
  EMPLOYEES {
    int id
    text name
    int department_id
    text role
    int salary
  }
  PROJECTS {
    int id
    text name
    int department_id
    text status
  }
Our database: employees and projects each belong to a department.

What makes it 'relational'

The clever part is the links between tables. Notice that employees has a department_id column, and so does projects. Those are not real attributes of a person or a project — they are pointers. An employee whose department_id is 1 belongs to Engineering, because 1 is the id of the Engineering row in departments.

A pointer like this is called a foreign key, and it is the reason the model is named relational. The data is split across tables so that each fact is stored exactly once, and the foreign keys let a query follow the pointers and stitch the pieces back together for a single answer. One employee who is also a marketer no longer needs two copies of the department name; the link does the work.

SQL is declarative — you say what, not how

Most programming you have done tells the computer how to do something, one step at a time. SQL is different: you describe the result you want, and the database works out how to produce it. You never tell it to loop over rows or walk an index; you state which table, which rows, and which columns, and you trust the engine to fetch efficiently.

That is why a short SQL query can answer a question that would take many lines of Python. You trade fine-grained control for leverage — and for the kind of question databases exist to answer, leverage is exactly what you want.

flowchart LR
  Q["You: name and salary<br/>of the top earners"] --> S["SQL describes<br/>the result"]
  S --> E[("Database engine<br/>decides the how")]
  E --> R["A new table<br/>of answers"]
  style Q fill:#3776ab,color:#fff
  style R fill:#0e7490,color:#fff
Declarative: you describe the answer you want; the database chooses how to compute it.
Your first real query — read it aloud, then press Run.
SELECT name, city
FROM departments;

Choosing columns with SELECT

Read that query aloud as "select the name and city columns from the departments table." The list between SELECT and FROM is called projection — you pick which columns to show and in what order, and the rest are hidden. Want a different view of the same rows? Change only the column list and run it again.

If you want every column and would rather not type them all, write SELECT *. The star means "all of them." It is excellent while exploring an unfamiliar table, but for real queries you should name the columns you mean, so the result stays predictable even if the table grows new columns later on.

Same idea, different table — projection lets you choose any columns from any table.
SELECT name, salary
FROM employees;
SELECT * returns every column at once — handy for a first look at a table.
SELECT *
FROM projects;
Exercise

Which table would you query to find out how much someone earns?

Exercise

In the employees table, what does a single row represent?

Exercise

List the name and role of every employee in the company.

SELECT name, role
FROM employees
;
Exercise

List the name and budget of every project.

SELECT name, budget
FROM 
;
Exercise

Show every column of the departments table — id, name, and city.

SELECT 
FROM departments
;

Recap

  • A database holds many tables; each table stores one kind of fact as rows (records) and columns (attributes).
  • A foreign key like department_id is a pointer linking a row in one table to a row in another — the 'relational' in relational database.
  • SQL is declarative: you state the shape of the answer, not the steps to reach it.
  • SELECT chooses columns (projection); SELECT * chooses all of them, and the answer comes back as a new table.

Next you will open up the schema and see exactly how those tables, columns, and keys fit together — the relational model that the rest of the course stands on.

Checkpoint quiz

What does the department_id column on employees represent?

In SELECT name, city FROM departments; — what does FROM specify?

What makes SQL different from most programming you may have done?

Go deeper — technical resources