shop appDBMSusers.csvCREATE TABLE users ( id INTEGER PRIMARY KEY, name TEXT NOT NULL, city TEXT);SELECT nameFROM usersWHERE city = 'Oslo';INSERT INTO users VALUES (4, 'Max', 'Lima');UPDATE usersSET city = 'Rome'WHERE id = 2;DELETE FROM usersWHERE id = 4;CREATE TABLE orders ( id INTEGER PRIMARY KEY, user_id INTEGER REFERENCES users(id), item TEXT);SELECT u.name, o.itemFROM orders AS oJOIN users AS u ON o.user_id = u.idORDER BY o.id;f = open('users.csv')for line in f: if 'Oslo' in line: print(line)db.users.find( { name: "Ada" }){"name": "Ada", "orders": ["tea","cake"]}idnamecity1AdaParis2Sam3LinaOsloCairoRome4MaxLimaLimaiduser_iditem11tea23mug31cake42pennameLinanameitemAdateaLinamugAdacakeSampenid 2all
Back row: the app, the DBMS, a plain file and a documentCards: the query, the users and orders tables, the result, a documentEnvelopes carry statements and answers; gold arcs are foreign-key linksAt the back: the shop app that uses the data, the DBMS that runs the database, a plain file and a MongoDB-style document for comparison. In the middle: the query card, the users table and the orders table. In front: the result card. The users table's primary key is id; each order's user_id is a foreign key that points at one users id. SELECT asks, INSERT, UPDATE and DELETE change rows, and a JOIN pairs every order with its user. Without ORDER BY, SQL does not promise any order for the rows of an answer. The JOIN asks for ORDER BY o.id; the figure shows rows in id order.

Tables and keys

  1. A relational database keeps data in tables. Each table has a schema: a fixed list of named columns, each with a type. The users table has id, name and city, and each row is one user. CREATE TABLE sets that schema.

Ask and change

Two tables

Why a database

What happens

;; step 1/11 · tables
the schema of users:
  CREATE TABLE users (
    id INTEGER PRIMARY KEY,
    name TEXT NOT NULL,
    city TEXT);

  id name city
  1  Ada  Paris
  2  Sam  Cairo
  3  Lina Oslo

3 rows (one per user) x 3 columns (one per fact)
every value in a column has that column’s type

Without ORDER BY, SQL does not promise any order for the rows of an answer. The JOIN asks for ORDER BY o.id; the figure shows rows in id order. SQLite only checks foreign keys after PRAGMA foreign_keys = ON (they are off by default, for backward compatibility). PostgreSQL and MySQL’s InnoDB check them by default.