A 09-01 vam veure què llegir i a 09-02 on estudiar i practicar. Falta el tercer vèrtex, i és el que converteix la resta en feina real: amb què. Aquesta lliçó és l'inventari d'eines amb què es treballa de debò amb bases de dades —motors a la teva pròpia màquina, clients, disseny, migracions, dades de prova, diagnòstic i còpies— i, sobretot, el criteri de quines necessites ja i quines no necessites encara.

Perquè l'error dominant en aquesta matèria no és fer servir poques eines, és acumular-les. És fàcil acabar amb tres clients gràfics instal·lats, dues eines de diagrames, un gestor de migracions que no es fa servir i cap còpia de seguretat configurada. L'apartat final proposa un kit mínim de cinc peces amb el qual es pot començar demà, i una llista explícita del que pots ignorar sense remordiment.

Tot el que hi ha aquí està orientat que puguis fer el que l'última lliçó del mòdul 8 et demanava: agafar un dels casos de VallBici o l'esquema de BiblioRed, muntar-lo a la teva màquina i trencar-lo.

Advertiment important. Les versions dels motors i de les eines avancen constantment; les opcions de línia d'ordres canvien; i les llicències i els models de negoci de les eines també canvien —hi ha projectes que han passat de lliures a comercials i a l'inrevés—. Les ordres d'aquesta lliçó són correctes en la seva forma general, però comprova sempre la sintaxi i els noms de paquet a la documentació de la teva versió. I la regla que governa tota la resta: la documentació oficial mana sobre el que digui qualsevol curs, inclòs aquest. Tampoc no s'hi cita cap preu ni cap condició de pla gratuït, perquè canvien sense avís: verifica a la font oficial abans de contractar res.

Contingut

  1. Motors a la teva màquina: instal·lació i arrencada
  2. Docker i Docker Compose: l'entorn de 08-03 en una ordre
  3. Bases de dades gestionades al núvol
  4. Clients de consola: psql i mongosh
  5. Clients gràfics
  6. Disseny i diagrames
  7. Migracions i control de versions de l'esquema
  8. Dades de prova
  9. Rendiment i diagnòstic
  10. Còpies de seguretat, monitoratge i administració
  11. El kit mínim
  12. Errors Habituals i Consells
  13. Exercicis
  14. Conclusió: el tancament del curs

  1. Motors a la teva màquina: instal·lació i arrencada

Tenir el motor instal·lat localment no és negociable. Pots aprendre molt contra una base de dades gestionada, però no la pots apagar a mitja transacció per veure què passa, i aquest tipus d'experiment és exactament el que et falta.

Motor Quan instal·lar-lo Pes Dona continuïtat a
PostgreSQL Sempre. És el motor de referència del curs i el que resol el 90 % dels casos Mitjà Tot el curs
SQLite Sempre; ja el tens gairebé segur. Per a proves ràpides, prototips i anàlisi de fitxers Nul 01-02, 01-04
MongoDB Si has de treballar amb documents o vols refer 08-02 Mitjà 03-03, 08-02
Redis Si has de refer 08-03 o treballar amb cau i dades efímeres Baix 03-02, 08-03
Elasticsearch Només si has de refer la part de cerca de 08-03. És el més pesat Alt 08-03
Neo4j / Cassandra Només per curiositat o per necessitat concreta. No els instal·lis "per si de cas" Alt 03-02

PostgreSQL

# Debian / Ubuntu
sudo apt update
sudo apt install postgresql postgresql-contrib

# macOS amb Homebrew
brew install postgresql@16
brew services start postgresql@16

# Comprovar que el servei és viu (Linux amb systemd)
sudo systemctl status postgresql
sudo systemctl enable --now postgresql

Després de la instal·lació a Linux existeix l'usuari del sistema postgres, que és el superusuari del motor. El primer pas raonable és crear el teu propi rol i la teva pròpia base de dades, en lloc de treballar sempre com a superusuari —just el que es va argumentar a 06-04:

# Entrar com a superusuari del motor
sudo -u postgres psql

# Dins de psql: crear rol i base de dades per al projecte
CREATE ROLE bibliored_app WITH LOGIN PASSWORD 'canvia-la';
CREATE DATABASE bibliored OWNER bibliored_app;
\q
# Connectar-se ja amb el rol d'aplicació
psql -h localhost -U bibliored_app -d bibliored

El paquet postgresql-contrib mereix una nota: porta extensions que voldràs, entre elles pg_stat_statements (apartat 9), pg_trgm (cerca per similitud, la que es va comparar amb Elasticsearch a 08-03) i btree_gist (necessària per a les restriccions d'exclusió sobre rangs).

SQLite

# Debian / Ubuntu
sudo apt install sqlite3

# macOS: ve amb el sistema; per a la versió més recent
brew install sqlite

# Ús: la base de dades és un fitxer, no hi ha servidor ni servei
sqlite3 proves.db
-- Dins de sqlite3
.databases
.tables
.schema prestecs
.mode box          -- sortida llegible en columnes
.headers on
.quit

SQLite és l'eina més infravalorada de l'inventari. Per provar una idea d'esquema, per analitzar un CSV amb SQL o per portar dades d'exemple en un repositori, no hi ha res més ràpid. Recorda el de 01-02: el seu tipatge és dinàmic i el seu model de concurrència és d'un únic escriptor, així que no és un substitut de PostgreSQL per a una aplicació amb diversos usuaris escrivint alhora.

MongoDB i Redis

# MongoDB: els paquets oficials s'instal·len afegint el repositori
# del fabricant; consulta la guia d'instal·lació del teu sistema a
# https://www.mongodb.com/docs/
sudo systemctl enable --now mongod
mongosh

# Redis
sudo apt install redis-server        # Debian / Ubuntu
brew install redis                   # macOS
sudo systemctl enable --now redis-server
redis-cli ping                       # ha de respondre PONG

Per a MongoDB i Redis, i encara més per a Elasticsearch, la via recomanable en una màquina de treball no és instal·lar-los com a serveis del sistema, sinó aixecar-los amb contenidors. És el que ve a continuació.

  1. Docker i Docker Compose: l'entorn de 08-03 en una ordre

Instal·lar quatre motors com a serveis del sistema significa quatre serveis arrencant sempre, quatre configuracions per mantenir i una desinstal·lació penosa el dia que vulguis netejar. Amb contenidors, tot l'entorn és un fitxer de text que pots versionar, compartir i destruir sense deixar rastre.

# Aixecar un PostgreSQL solt en 30 segons
docker run --name pg-proves \
  -e POSTGRES_PASSWORD=secret \
  -p 5432:5432 \
  -d postgres:16

# Connectar-se des del mateix contenidor
docker exec -it pg-proves psql -U postgres

# Destruir-lo sense deixar rastre
docker rm -f pg-proves

I aquest és el fitxer que aixeca l'entorn del cas poliglota de 08-03: PostgreSQL com a font de la veritat transaccional, MongoDB per a telemetria i fitxes, i Redis per a la disponibilitat en temps real.

# docker-compose.yml — entorn del cas poliglota de VallBici (08-03)
# Ús:  docker compose up -d      /  docker compose down -v  (esborra les dades)
services:

  # --- PostgreSQL: font de la veritat del nucli transaccional ---------------
  postgres:
    image: postgres:16                 # fixa la versió major; no facis servir "latest"
    container_name: vallbici-postgres
    environment:
      POSTGRES_USER: vallbici
      POSTGRES_PASSWORD: desenvolupament  # només per a local; mai en producció
      POSTGRES_DB: vallbici
    ports:
      - "5432:5432"                    # amfitrió:contenidor
    volumes:
      - pgdata:/var/lib/postgresql/data          # dades persistents
      - ./sql:/docker-entrypoint-initdb.d:ro     # scripts .sql que s'executen
                                                 # només la primera vegada
    healthcheck:                       # perquè altres serveis esperin
      test: ["CMD-SHELL", "pg_isready -U vallbici"]
      interval: 5s
      retries: 10

  # --- MongoDB: telemetria, fitxes enriquides i incidències -----------------
  mongo:
    image: mongo:7
    container_name: vallbici-mongo
    environment:
      MONGO_INITDB_ROOT_USERNAME: vallbici
      MONGO_INITDB_ROOT_PASSWORD: desenvolupament
    ports:
      - "27017:27017"
    volumes:
      - mongodata:/data/db

  # --- Redis: disponibilitat en temps real, sessions i reserves -------------
  redis:
    image: redis:7
    container_name: vallbici-redis
    command: ["redis-server", "--appendonly", "yes"]   # persistència AOF
    ports:
      - "6379:6379"
    volumes:
      - redisdata:/data

volumes:
  pgdata:
  mongodata:
  redisdata:
docker compose up -d          # aixecar-ho tot
docker compose ps             # veure estat
docker compose logs -f postgres
docker compose down           # aturar, conservant els volums
docker compose down -v        # aturar i ESBORRAR les dades

Quatre detalls del fitxer que mereixen atenció, perquè són els que separen un compose de joguina d'un d'útil:

  1. Versió fixada (postgres:16, no postgres:latest). Amb latest, un dia actualitzes la imatge sense voler i el format de dades deixa de ser compatible.
  2. Volums amb nom. Sense ells, docker compose down s'endú les teves dades per davant. Amb ells, sobreviuen fins que demanis explícitament -v.
  3. docker-entrypoint-initdb.d. Qualsevol .sql que deixis a ./sql s'executa en crear la base de dades per primera vegada. És el lloc natural de l'esquema de BiblioRed o de VallBici: clonar el repositori i docker compose up -d et deixa l'esquema creat.
  4. healthcheck. Permet que la teva aplicació —o un contenidor de migracions— esperi que PostgreSQL estigui realment acceptant connexions, no només arrencat.

Si a més vols Elasticsearch per reproduir la cerca d'estacions, afegeix-lo com un servei més; tingues en compte que consumeix bastant més memòria que els altres tres junts i que sol necessitar ajustos de memòria de la màquina amfitriona.

  1. Bases de dades gestionades al núvol

Una base de dades gestionada és el mateix motor, operat per un altre: còpies de seguretat, actualitzacions, alta disponibilitat i monitoratge venen inclosos. Per aprendre no les necessites; per publicar un projecte propi són molt còmodes.

Tipus d'oferta Exemples consolidats Quan té sentit
PostgreSQL gestionat pels grans proveïdors Amazon RDS i Aurora, Google Cloud SQL, Azure Database for PostgreSQL Quan ja treballes en aquell núvol
PostgreSQL de proveïdors especialitzats Neon, Supabase, Crunchy Bridge, entre d'altres Projectes propis i prototips; solen tenir capa gratuïta
MongoDB gestionat MongoDB Atlas Refer 08-02 sense instal·lar res; inclou conjunts de dades d'exemple
Redis gestionat Redis Cloud i equivalents de cada núvol Cau en un projecte publicat
Cerca gestionada Elastic Cloud i equivalents Quan Elasticsearch local et resulta massa pesat

Sobre les capes gratuïtes. Diverses d'aquestes ofertes tenen capa gratuïta o crèdit inicial, i són perfectament adequades per a un projecte d'aprenentatge publicat. Però les condicions —límits d'emmagatzematge, pauses per inactivitat, caducitat— canvien amb freqüència, així que consulta-les al web oficial del proveïdor en el moment en què les vulguis fer servir. I dues cauteles pràctiques: primera, activa sempre les alertes de despesa abans de crear res, perquè la manera de facturació per ús et pot sorprendre; segona, una base de dades gestionada no t'eximeix de saber administrar: si no entens què és un VACUUM o què implica el nivell d'aïllament, el tauler bonic no et salvarà.

  1. Clients de consola: psql i mongosh

Comencem pels clients de consola i no pels gràfics deliberadament. psql no és l'opció bàsica: és l'eina més potent de totes les que apareixen en aquesta lliçó. Tot el que existeix en un client gràfic existeix a psql, i bastant del que hi ha a psql no existeix en cap client gràfic. A més està sempre disponible: al servidor, dins del contenidor, per SSH, en un script.

Metacomandes de psql que més es fan servir

Reprenen el que a 01-04 es va anomenar el catàleg del sistema: cadascuna d'aquestes metacomandes és, en realitat, una consulta al catàleg escrita per tu sense adonar-te'n.

Metacomanda Què fa
\l Llista les bases de dades del servidor
\c bibliored Es connecta a una altra base de dades
\dt Llista les taules de l'esquema actual
\d prestecs Descriu una taula: columnes, tipus, índexs, claus foranes
\d+ prestecs Igual, amb mida en disc, emmagatzematge i descripcions
\di Llista els índexs
\dn Llista els esquemes
\du Llista els rols i els seus atributs (continuació directa de 06-04)
\df Llista les funcions
\sf nom_funcio Mostra el codi font d'una funció
\x Alterna la sortida expandida (una columna per línia); imprescindible amb taules amples
\timing Activa el temps d'execució de cada consulta
\e Obre l'última consulta al teu editor
\i fitxer.sql Executa un fitxer SQL
\copy taula FROM 'dades.csv' CSV HEADER Importa/exporta CSV des del client (no requereix permisos de servidor)
\watch 2 Repeteix l'última consulta cada 2 segons; excel·lent per observar comptadors
\? / \h CREATE INDEX Ajuda de metacomandes / ajuda de sintaxi SQL
\q Sortir

Dos costums que valen molt i costen poc: activar \timing sempre, perquè cada consulta et digui el que triga; i fer servir \watch per observar en viu un comptador mentre una altra sessió treballa —és la manera més directa de veure els fenòmens de concurrència de 06-02 sense cap eina addicional.

Un fitxer ~/.psqlrc amb les teves preferències fa la resta:

-- ~/.psqlrc
\set QUIET 1
\timing on
\x auto
\set HISTSIZE 10000
\set PROMPT1 '%[%033[1;32m%]%n@%/%[%033[0m%]%R%# '
\pset null '(null)'
\set QUIET 0

Aquell \pset null '(null)' és més útil del que sembla: per defecte un NULL i una cadena buida es veuen exactament igual a la sortida, i aquella confusió ha costat moltes hores de depuració a molta gent.

mongosh

// Metacomandes i operacions habituals de mongosh
show dbs
use vallbici
show collections

db.trajectes.countDocuments({ estat: "tancat" })
db.trajectes.findOne()
db.trajectes.find({ bicicleta_id: 417 }).sort({ inici: -1 }).limit(5)

db.trajectes.getIndexes()
db.trajectes.createIndex({ bicicleta_id: 1, inici: -1 })

// L'equivalent d'EXPLAIN: continuació directa de 06-03
db.trajectes.find({ bicicleta_id: 417 })
            .explain("executionStats")

db.stats()
db.trajectes.stats()

mongosh és un intèrpret de JavaScript complet, no només un client. Hi pots escriure bucles, funcions i carregar fitxers amb load('script.js'), cosa que el converteix en l'eina natural per generar dades de prova o per a migracions puntuals de documents.

  1. Clients gràfics

Un client gràfic aporta tres coses reals: navegar un esquema desconegut molt més de pressa, veure els resultats en una graella còmoda i generar diagrames per enginyeria inversa. No aporta —i convé no enganyar-se— cap capacitat que no tingui la consola.

Eina Motors admesos Llicència Punt fort Per a qui
DBeaver Community (https://dbeaver.io/) Moltíssims, via JDBC: PostgreSQL, MySQL, SQLite, Oracle, SQL Server, i NoSQL a l'edició comercial Lliure (edició Community) El navegador universal: un sol client per a tot, amb diagrames per enginyeria inversa Qui toca diversos motors diferents
pgAdmin (https://www.pgadmin.org/) Només PostgreSQL Lliure Cobertura total de PostgreSQL, inclosa administració: rols, còpies, estadístiques Qui viu a PostgreSQL i fa administració
MongoDB Compass (des de https://www.mongodb.com/) Només MongoDB Gratuït del fabricant Explorar documents sense esquema conegut, construir canalitzacions d'agregació visualment i veure explain() gràfic Qualsevol que treballi amb MongoDB
TablePlus (https://tableplus.com/) Diversos, relacionals i alguns NoSQL Comercial, amb mode de prova limitat Rapidesa i interfície molt cuidada Qui passa el dia en un client i valora l'ergonomia
Beekeeper Studio (https://www.beekeeperstudio.io/) Diversos relacionals Comunitat lliure + edició comercial Alternativa lleugera i senzilla Qui vol alguna cosa simple i lliure
DataGrip (JetBrains) Molts Comercial Integració amb la resta d'eines de JetBrains, refactorització i autocompletat excel·lents Qui ja fa servir aquell ecosistema
Extensions de l'editor de codi (per exemple, extensions de bases de dades per a VS Code) Segons extensió Variable No sortir de l'editor per llançar una consulta Qui només necessita consultes ràpides al costat del codi

Recomanació honesta. Instal·la'n un. Si toques diversos motors, DBeaver. Si només PostgreSQL i fas administració, pgAdmin. Si treballes amb MongoDB, Compass a més de l'anterior perquè fa coses que cap altre no fa. Tenir tres clients relacionals instal·lats és un senyal gairebé infal·lible que no se n'ha après bé cap.

I un advertiment que es repeteix en el temps: les llicències de les eines canvien. Projectes que van començar lliures han passat a models comercials i alguns a l'inrevés. Comprova la llicència vigent abans de recolzar un flux de treball d'equip en una eina concreta.

  1. Disseny i diagrames

A 04-02 vas dibuixar diagrames entitat-relació i a 04-03 els vas transformar en esquemes. Aquestes són les eines amb què això es fa fora d'un curs.

Eina Enfocament Llicència / model Punt fort Per a qui
Mermaid (https://mermaid.js.org/) Diagrama com a text, dins del repositori Lliure El diagrama viu al costat del codi, es versiona i es veu a les plataformes de repositoris Tothom; és el que s'ha fet servir en aquest curs
dbdiagram.io (https://dbdiagram.io/) Diagrama com a text en un llenguatge propi, al navegador Comercial amb nivell gratuït Rapidíssim per esbossar i exportar el SQL de creació Esbossos i discussions de disseny
DrawSQL (https://drawsql.app/) Editor visual al navegador Comercial amb nivell gratuït Diagrames presentables per compartir amb no tècnics Documentació de cara a l'equip
pgModeler (https://pgmodeler.io/) Modelador d'escriptori específic de PostgreSQL Codi obert; binaris de pagament Modelatge complet amb generació i sincronització d'esquema Modelatge seriós i continuat sobre PostgreSQL
SchemaSpy (https://schemaspy.org/) Enginyeria inversa: documentació HTML des d'una base existent Lliure Documentar un esquema heretat que ningú no entén Qui aterra en un projecte sense documentació
DBeaver / pgAdmin (diagrames inclosos) Enginyeria inversa integrada Vegeu l'apartat 5 Veure el diagrama del que ja existeix sense instal·lar res més Ús diari

El criteri. Per a un diagrama que ha de viure en el temps —al repositori, revisat a cada canvi— fes servir Mermaid: és text, es versiona i es llegeix al README. Per a un esbós d'una tarda, dbdiagram.io. Per entendre un esquema aliè de seixanta taules, enginyeria inversa amb DBeaver o SchemaSpy i a partir d'aquí decideixes.

Aquest és l'erDiagram de Mermaid amb què pots començar a documentar el teu propi esquema; és exactament el format que has vist durant tot el curs:

erDiagram
    SOCI ||--o{ PRESTEC : "realitza"
    EXEMPLAR ||--o{ PRESTEC : "es objecte de"
    MATERIAL ||--o{ EXEMPLAR : "te"
    BIBLIOTECA ||--o{ EXEMPLAR : "custodia"
    PRESTEC ||--o| MULTA : "pot generar"

    SOCI {
        int soci_id PK
        text nom
        text email UK
        date data_alta
        bool actiu
    }
    MATERIAL {
        int material_id PK
        text titol
        text isbn UK
        int any_publicacio
    }
    EXEMPLAR {
        int exemplar_id PK
        int material_id FK
        int biblioteca_id FK
        text estat
    }
    PRESTEC {
        int prestec_id PK
        int soci_id FK
        int exemplar_id FK
        timestamptz data_prestec
        date data_devolucio_prevista
        timestamptz data_devolucio_real
    }
    MULTA {
        int multa_id PK
        int prestec_id FK
        numeric import
        bool pagada
    }

Guarda aquell bloc al README.md del teu projecte i actualitza'l a la mateixa confirmació en què canviïs l'esquema. És l'aplicació literal del "documentar i versionar l'esquema" de 04-01, i costa dos minuts.

  1. Migracions i control de versions de l'esquema

Aquest apartat és el més important de la lliçó, i el que més gent es salta.

A 04-01 es va dir que l'esquema cal documentar-lo i versionar-lo. Una migració és la manera professional de fer-ho: cada canvi de l'esquema és un fitxer, numerat i guardat al repositori al costat del codi, que s'aplica en ordre i del qual la base de dades porta registre. La conseqüència és que l'esquema deixa de ser el resultat d'una sèrie d'ALTER TABLE solts a la consola d'algú i passa a ser una seqüència reproduïble.

Per què això no és opcional. Quatre raons, totes comprovables el primer dia que treballes en equip:

  1. Reproductibilitat. Qualsevol clona el repositori, executa les migracions i obté exactament el teu esquema. Sense migracions, "muntar l'entorn" és preguntar a un company.
  2. L'esquema i el codi viatgen junts. La confirmació que afegeix la columna data_devolucio_real conté també el codi que la fa servir. Tornar enrere una versió reverteix les dues coses.
  3. Repetibilitat entre entorns. El que es va aplicar en desenvolupament s'aplica idèntic en preproducció i en producció, sense que ningú escrigui res a mà sota pressió.
  4. Història i auditoria. «Quan es va afegir aquest índex i per què?» té resposta: la confirmació, la seva data i el seu missatge.
Eina Format Ecosistema Punt fort
Flyway (https://flywaydb.org/) SQL pur numerat (V1__...sql) JVM, però usable des de línia d'ordres amb qualsevol llenguatge Simplicitat: són fitxers .sql i s'executen en ordre
Liquibase (https://www.liquibase.org/) XML, YAML, JSON o SQL JVM i línia d'ordres Canvis descrits de manera abstracta, amb reversió automàtica
Alembic Python SQLAlchemy Genera migracions a partir de la diferència amb els models
Migracions integrades en marcs de treball Segons el marc Django, Rails, Laravel, Entity Framework, Prisma, Ecto… Ja les tens: fes-les servir i no afegeixis una altra eina
Eines lleugeres (golang-migrate, dbmate, sqitch…) SQL pur Agnòstiques Un binari i fitxers SQL, sense dependències

Com triar. Si el teu marc de treball ja porta migracions, fes servir aquestes i punt. Si no fas servir marc, o vols SQL explícit i controlat, Flyway o una eina lleugera equivalent. Liquibase compensa en entorns amb diversos motors diferents i necessitat de reversió formal.

Un exemple mínim amb el format de fitxers SQL numerats, aplicat a BiblioRed:

-- V3__prestecs_index_soci_data.sql
--
-- Context: la consulta de l'historial de préstecs d'un soci feia
-- recorregut seqüencial sobre 500.000 files (vegeu EXPLAIN al tiquet #142).
-- L'ordre de les columnes no és arbitrari: soci_id és el filtre
-- d'igualtat i va primer; data_prestec dona l'ordre i va després.
-- Vegeu la lliçó 06-03 i «SQL Performance Explained».

CREATE INDEX CONCURRENTLY idx_prestecs_soci_data
    ON prestecs (soci_id, data_prestec DESC);
-- V4__reserves_sala_sense_solapaments.sql
--
-- Substitueix la comprovació de solapament que hi havia a l'aplicació
-- per una restricció del motor. Motiu: sota concurrència la comprovació
-- a l'aplicació falla (lliçó 06-02, escriptura esbiaixada).

CREATE EXTENSION IF NOT EXISTS btree_gist;

ALTER TABLE reserves_sala
    ADD COLUMN periode tstzrange;

UPDATE reserves_sala
   SET periode = tstzrange(inici, fi, '[)');

ALTER TABLE reserves_sala
    ALTER COLUMN periode SET NOT NULL,
    ADD CONSTRAINT reserves_sala_sense_solapaments
        EXCLUDE USING gist (sala_id WITH =, periode WITH &&);

Tres regles d'or sobre migracions, apreses totes per les males:

  1. Una migració aplicada no es modifica mai. Si estava malament, es corregeix amb una migració nova. Canviar un fitxer ja aplicat trenca la suma de verificació de l'eina i desincronitza els entorns.
  2. Tota migració ha de poder executar-se sobre dades reals. Afegir una columna NOT NULL sense valor per defecte a una taula amb dos milions de files falla; cal fer-ho en passos.
  3. CREATE INDEX CONCURRENTLY en producció. Un CREATE INDEX normal bloqueja les escriptures de la taula mentre dura. És l'exemple perfecte de com el que vas aprendre a 06-02 sobre bloquejos es tradueix en una decisió operativa concreta.

  1. Dades de prova

Un esquema amb dotze files no ensenya res. El planificador de consultes farà recorregut seqüencial sempre, qualsevol índex semblarà inútil i cap problema de concurrència no es manifestarà. Per aprendre rendiment necessites volum, i per a això hi ha tres camins.

Camí 1: generate_series, sense instal·lar res

És la via més ràpida i no requereix cap eina externa. Genera mig milió de préstecs versemblants per a BiblioRed:

-- 500.000 préstecs repartits entre 20.000 socis i 80.000 exemplars,
-- al llarg dels últims tres anys
INSERT INTO prestecs (soci_id, exemplar_id, data_prestec,
                      data_devolucio_prevista, data_devolucio_real)
SELECT
    1 + floor(random() * 20000)::int                        AS soci_id,
    1 + floor(random() * 80000)::int                        AS exemplar_id,
    ts                                                      AS data_prestec,
    (ts + interval '21 days')::date                         AS data_dev_prevista,
    CASE WHEN random() < 0.9                                -- 90 % retornats
         THEN ts + (random() * interval '35 days')
         ELSE NULL
    END                                                     AS data_dev_real
FROM generate_series(
        now() - interval '3 years',
        now(),
        interval '3 minutes'
     ) AS ts;

-- Imprescindible després d'una càrrega massiva: sense estadístiques fresques,
-- el planificador pren decisions amb informació falsa
ANALYZE prestecs;

-- Comprovació
SELECT count(*), min(data_prestec), max(data_prestec) FROM prestecs;

Aquell ANALYZE final no és un adorn. És la causa número u de "he creat l'índex i continua sense fer-lo servir" en proves casolanes: el planificador de 06-03 decideix amb estadístiques, i després d'una càrrega massiva les estadístiques estan obsoletes.

Un advertiment sobre el realisme: random() produeix una distribució uniforme, i les dades reals mai no són uniformes. A BiblioRed uns pocs títols concentren la majoria dels préstecs, i aquella asimetria és just el que fa interessants els índexs i els plans. Si vols proves realistes, esbiaixa la distribució expressament.

Camí 2: generadors de dades fictícies

Eina Què és Quan fer-la servir
Faker (biblioteques per a Python, JavaScript, PHP, Ruby…) Genera noms, adreces, correus, dates i textos versemblants, amb localització al català Quan necessites dades que semblin reals per a captures o demostracions
Mockaroo (https://mockaroo.com/) Generador al navegador que exporta CSV, JSON o SQL Prototips ràpids sense escriure codi
pgbench (ve amb PostgreSQL) Genera un esquema de prova i executa càrregues concurrents Mesurar el motor i observar concurrència real

pgbench mereix una menció a part perquè fa una cosa que els altres no fan: càrrega concurrent. Amb pgbench -c 20 -T 60 tens vint sessions escrivint alhora durant un minut, que és la manera de veure de debò el que a 06-02 vas veure amb dos terminals.

Camí 3: bases de dades d'exemple públiques

De vegades no vols muntar res: vols practicar consultes sobre un esquema no trivial que ja existeix.

Base de dades d'exemple Domini Motor habitual Bona per a
Pagila Lloguer de pel·lícules (versió PostgreSQL de Sakila) PostgreSQL L'estàndard de facto per practicar SQL a PostgreSQL; esquema ric i ben normalitzat
Sakila Lloguer de pel·lícules MySQL El mateix, al món MySQL
Chinook Botiga de música PostgreSQL, SQLite, i d'altres Molt portable; excel·lent amb SQLite per practicar sense servidor
Northwind Distribuïdora d'aliments Diversos El clàssic veterà; útil per la quantitat d'exercicis publicats que el fan servir
Conjunts d'exemple de MongoDB Atlas Diversos (restaurants, vols, cinema) MongoDB Practicar canalitzacions d'agregació sense crear dades

Es troben buscant el seu nom; solen distribuir-se com un fitxer SQL que es carrega amb psql -f. Amb Chinook a SQLite tens pràctica de consultes en menys d'un minut i sense instal·lar cap servidor.

  1. Rendiment i diagnòstic

Continuació directa de 06-03, on vas llegir el teu primer pla d'execució.

Eina Motor Què resol
EXPLAIN / EXPLAIN (ANALYZE, BUFFERS) PostgreSQL El pla estimat i el real, amb temps i accessos a disc
Visualitzadors de plans (per exemple https://explain.depesz.com/ i els visualitzadors gràfics integrats a pgAdmin i DBeaver) PostgreSQL Convertir un pla de 200 línies en alguna cosa llegible, assenyalant on se'n va el temps
pg_stat_statements PostgreSQL La consulta més important de totes: quines sentències consumeixen més temps acumulat al teu servidor
auto_explain PostgreSQL Registrar automàticament el pla de les consultes que superin un llindar
pgBadger PostgreSQL Anàlisi dels registres del servidor amb informes de consultes lentes, errors i esperes
pg_stat_activity PostgreSQL Què està executant cada sessió ara, i qui està bloquejant qui
.explain("executionStats") MongoDB L'equivalent d'EXPLAIN ANALYZE: quin índex es va fer servir i quants documents es van examinar
Perfilador de base de dades de MongoDB MongoDB Registrar operacions lentes per analitzar-les després
mongostat / mongotop MongoDB Activitat en viu del servidor

pg_stat_statements mereix la seva fitxa perquè canvia la manera de treballar. Sense ella, optimitzes la consulta de la qual algú s'ha queixat que va lenta. Amb ella, optimitzes la que més temps total consumeix, que moltes vegades és una consulta ràpida executada cent mil vegades al dia i de la qual ningú no es queixa.

-- Activar-la: requereix afegir-la a shared_preload_libraries i reiniciar
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;

-- Les deu consultes que més temps total consumeixen al servidor
SELECT
    substring(query, 1, 80)          AS consulta,
    calls,
    round(total_exec_time::numeric, 1) AS ms_total,
    round(mean_exec_time::numeric, 2)  AS ms_mitjana,
    rows
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;
-- I la consulta de diagnòstic en calent: qui bloqueja qui
SELECT pid, state, wait_event_type, wait_event,
       now() - query_start AS duracio,
       substring(query, 1, 60) AS consulta
FROM pg_stat_activity
WHERE state <> 'idle'
ORDER BY duracio DESC;

Aquella segona consulta és la que executaràs el dia en què l'aplicació "s'ha quedat penjada". Gairebé sempre la resposta és allà: una transacció oberta des de fa vint minuts que ningú no ha confirmat, bloquejant la resta. És 06-02 a la vida real.

  1. Còpies de seguretat, monitoratge i administració

Continuació de 06-04. Aquí només hi ha una regla que importi: una còpia de seguretat que no s'ha restaurat mai no és una còpia de seguretat, és una esperança.

Eina Per a què Nivell
pg_dump / pg_restore Còpia lògica d'una base de dades; portable entre versions Imprescindible
pg_dumpall Inclou rols i objectes globals del clúster Imprescindible si administres
pg_basebackup Còpia física del clúster complet Mitjà
pgBackRest (https://pgbackrest.org/) Còpies físiques incrementals, retenció, verificació i recuperació a un instant Producció
Barman Alternativa consolidada per al mateix Producció
mongodump / mongorestore Còpies lògiques de MongoDB Imprescindible amb MongoDB
Exportadors de mètriques + Prometheus + Grafana Taulers de connexions, mida, consultes lentes, retard de rèplica Producció
pgwatch i equivalents Monitoratge específic de PostgreSQL amb taulers a punt Producció

El mínim, que pots tenir funcionant aquesta tarda:

# Còpia lògica comprimida i en format personalitzat (permet restaurar
# taules soltes, a diferència de l'abocament en text pla)
pg_dump -h localhost -U bibliored_app -d bibliored \
        -Fc -f bibliored_$(date +%F).dump

# Restaurar sobre una base de dades NOVA: la prova que la còpia serveix
createdb bibliored_prova
pg_restore -d bibliored_prova bibliored_2026-08-02.dump

# Comprovació mínima: hi són, les files?
psql -d bibliored_prova -c "SELECT count(*) FROM prestecs;"
# MongoDB
mongodump  --uri="mongodb://localhost:27017/vallbici" --out=./copia
mongorestore --uri="mongodb://localhost:27017/vallbici_prova" ./copia/vallbici

Automatitzar-ho és un parell de línies més —una tasca programada que executi l'abocament, el comprimeixi i el copiï a un altre lloc— però la part que la gent omet no és l'automatització, és la restauració de prova. Posa al calendari una prova de restauració trimestral. És l'única manera de saber que la còpia existeix.

  1. El kit mínim

Tot l'anterior és l'inventari complet. Això és el que necessites de debò per començar demà.

# Eina Per què és imprescindible
1 PostgreSQL local (natiu o en contenidor) Sense motor propi no hi ha experimentació possible
2 psql És l'eina més potent de la llista i està sempre disponible
3 Docker + un docker-compose.yml Entorns reproduïbles, exhauribles i versionats
4 Un client gràfic (DBeaver o pgAdmin, un) Navegar esquemes aliens i veure resultats còmodament
5 Una eina de migracions (la del teu marc, o Flyway) L'esquema versionat no és opcional
6 EXPLAIN + pg_stat_statements Sense mesurar, optimitzar és endevinar

I això és el que no necessites encara, dit explícitament perquè no perdis temps:

Prescindible ara com ara Quan deixarà de ser-ho
Un segon i un tercer client gràfic Mai
Elasticsearch, Neo4j o Cassandra instal·lats Quan tinguis un problema concret que els demani
Eina de modelatge d'escriptori (pgModeler) Quan modelis esquemes grans de manera continuada
pgBackRest, Barman, Prometheus i Grafana Quan operis una base de dades de la qual depengui algú
Subscripció a un client comercial Quan el gratuït t'entrebanqui de debò, no abans
Eines de generació de dades amb interfície generate_series et cobreix gairebé tot

El consell que resumeix l'apartat: no acumulis eines abans de necessitar-les. Cada eina instal·lada té un cost de manteniment, d'actualització i d'atenció. Una eina s'adopta quan tens un problema que et fa mal i ella el resol, no quan la veus recomanada en una llista, inclosa aquesta.

Errors Habituals i Consells

Error 1: no tenir un motor local. Treballar només contra una base de dades compartida o gestionada significa no poder experimentar: no pots matar el procés, omplir el disc, provocar un interbloqueig ni restaurar una còpia a sobre. Tot el que és interessant d'aquest curs requereix una base de dades que puguis destruir.

Error 2: fer servir latest a les imatges de contenidor. Un dia actualitzes i el format de dades ja no és compatible amb la versió anterior. Fixa sempre la versió major.

Error 3: canviar l'esquema a mà a la consola. L'ALTER TABLE que vas escriure directament en producció no és enlloc: ni al repositori, ni a l'entorn del teu company, ni a la teva memòria d'aquí a tres setmanes. Tot canvi d'esquema, migració.

Error 4: provar el rendiment amb dues-centes files. Amb aquell volum el recorregut seqüencial guanya sempre i no aprendràs res sobre índexs. Genera centenars de milers de files i executa ANALYZE.

Error 5: oblidar ANALYZE després d'una càrrega massiva. És la causa més freqüent de "l'índex està creat però no es fa servir". El planificador decideix amb estadístiques, i després d'inserir mig milió de files estan obsoletes.

Error 6: confiar en una còpia de seguretat no restaurada. Restaura sobre una base de dades nova i compta les files. Trimestralment. Sense excepció.

Error 7: deixar transaccions obertes al client gràfic. Diversos clients treballen en mode de transacció manual: obres una pestanya, executes un UPDATE, te'n vas a dinar, i el bloqueig es queda allà aturant tothom. Comprova en quin mode està el teu client i revisa pg_stat_activity quan alguna cosa s'encalli.

Error 8: instal·lar quatre motors i no fer servir cap. L'entusiasme del mòdul 3 porta a instal·lar Cassandra i Neo4j "per provar-los". Instal·la'ls quan hi hagis de fer alguna cosa concreta, i esborra'ls si en un mes no ho has fet.

Consell 1: versiona tot el que envolta la base de dades. El docker-compose.yml, les migracions, el README amb l'erDiagram de Mermaid, els scripts de dades de prova i el de còpia de seguretat. Que clonar el repositori i executar dues ordres deixi l'entorn funcionant és un objectiu assolible i molt rendible.

Consell 2: aprèn psql abans que cap client gràfic. El gràfic s'aprèn en vint minuts quan ja saps què estàs fent; a l'inrevés, el gràfic amaga el que passa i frena l'aprenentatge.

Consell 3: tingues sempre a mà un fitxer de consultes de diagnòstic. Les de pg_stat_activity, pg_stat_statements, mida de taules i índexs i ús d'índexs. El dia de l'incident no és el moment d'escriure-les.

Consell 4: i de nou, la documentació oficial mana. Les versions avancen, les opcions canvien de nom i els valors per defecte es revisen d'una versió a una altra. Davant de qualsevol dubte entre el que diu aquesta lliçó i el que diu el manual de la teva versió, el manual té raó.

Exercicis

Aquests exercicis són de pràctica real: es resolen amb la màquina encesa, no de memòria. No hi ha una única resposta correcta; les solucions són respostes model raonades i la teva versió pot ser diferent i millor.

Exercici 1: munta l'entorn poliglota i trenca'l

Aixeca amb Docker Compose l'entorn de 08-03 (PostgreSQL + MongoDB + Redis), carrega a PostgreSQL l'esquema de VallBici o de BiblioRed i després:

  1. Comprova que els tres motors responen des del seu client de consola.
  2. Insereix almenys 300.000 files a la taula de trajectes o de préstecs amb generate_series, i executa ANALYZE.
  3. Trenca'l expressament: atura el contenidor de Redis amb l'aplicació en marxa i documenta què deixa de funcionar i què continua funcionant. Després, executa docker compose down (sense -v) i torna a aixecar-ho: comprova que les dades hi continuen sent.
  4. Executa docker compose down -v i torna a aixecar-ho: comprova que no hi són, i explica per què.
  5. Deixa el resultat en un repositori amb docker-compose.yml, els .sql d'inicialització i un README que permeti a una altra persona reproduir-ho en menys de deu minuts.

Exercici 2: versiona el teu esquema amb migracions

Agafa l'esquema de BiblioRed tal com el vas deixar al mòdul 5 i converteix-lo en una seqüència de migracions:

  1. Tria una eina i justifica l'elecció en dues línies.
  2. Escriu V1 amb l'esquema base i, almenys, tres migracions posteriors que representin canvis reals: un índex nou justificat per un EXPLAIN, una restricció d'integritat que avui és a l'aplicació, i una columna nova sobre una taula que ja té dades.
  3. La migració de la columna nova ha de poder executar-se sobre les 300.000 files de l'exercici 1 sense deixar la taula bloquejada un temps inacceptable. Explica com ho aconsegueixes.
  4. Documenta a cada fitxer per què es fa el canvi, no només què es fa.
  5. Comprova l'essencial: esborra la base de dades, executa les migracions des de zero i verifica que obtens el mateix esquema.

Exercici 3: tria el teu kit i justifica'l

Sense instal·lar res nou encara, escriu el teu kit personal d'eines per als propers sis mesos. Per a cada peça:

  1. Quina eina tries i per a quina tasca concreta.
  2. Contra quina alternativa la vas triar i per què —una raó real, no "és la més popular".
  3. Quina eina de la lliçó descartes explícitament i en quina condició la reconsideraries.
  4. Afegeix una prova de foc: descriu la tasca concreta amb què verificaràs d'aquí a un mes que l'elecció va ser encertada.

Solucions

Respostes model, no les úniques correctes. El que s'avalua és el raonament i que la màquina realment faci el que dius.

Solució 1 (resposta model)

Punts 1 i 2. Comprovació dels tres motors i càrrega de volum:

docker compose up -d
docker compose exec postgres psql -U vallbici -d vallbici -c "SELECT version();"
docker compose exec mongo mongosh --quiet --eval "db.adminCommand({ping:1})"
docker compose exec redis redis-cli ping

La càrrega es fa amb el generate_series de l'apartat 8, seguit sempre d'ANALYZE. Verificació: EXPLAIN (ANALYZE) d'una consulta filtrada per soci ha de passar de recorregut seqüencial a cerca per índex després de crear l'índex i executar ANALYZE; si no canvia, gairebé segur que falta l'ANALYZE.

Punt 3 — trencar-lo. Amb docker compose stop redis:

Què passa Per què
La pantalla de disponibilitat en temps real deixa d'actualitzar-se Redis és la font del comptador ràpid de bicis per estació
Les sessions actives es perden i cal tornar a autenticar-se Les sessions viuen a Redis
El desbloqueig i el cobrament d'un trajecte continuen funcionant Es resolen contra PostgreSQL, que és la font de la veritat
L'històric i les factures continuen consultables Són a PostgreSQL

Aquella taula és la comprovació empírica de la tesi de 08-03: «que Redis pugui caure sense impedir un sol cobrament és la prova que el repartiment està ben fet». Si en aturar Redis deixés de poder-se cobrar, el repartiment estaria malament i caldria revisar-lo.

Punts 4 i 5. docker compose down atura els contenidors però conserva els volums amb nom (pgdata, mongodata, redisdata), així que en tornar a aixecar-ho les dades hi són. down -v elimina aquells volums i, amb ells, les dades; a més, en recrear-se el volum de PostgreSQL buit, es tornen a executar els scripts de docker-entrypoint-initdb.d, que només corren quan el directori de dades està sense inicialitzar. Entendre aquella asimetria és just l'objectiu de l'exercici: el contenidor és exhaurible, el volum no.

Solució 2 (resposta model)

1. Elecció: fitxers SQL numerats amb Flyway o una eina lleugera equivalent. Raó: BiblioRed no fa servir cap marc de treball amb migracions pròpies, l'esquema es pensa en SQL i vull que el que s'aplica sigui exactament el que llegeixo, sense capa d'abstracció intermèdia.

2 i 3. La migració delicada —afegir una columna NOT NULL a una taula de 300.000 files— es fa en tres passos, no en un:

-- V5__prestecs_canal_alta.sql
--
-- Afegeix el canal pel qual es va formalitzar el préstec (taulell, web, app).
-- Es fa en tres passos per no bloquejar la taula: afegir la columna com a
-- nullable és una operació de metadades i és instantània; omplir i
-- després imposar NOT NULL evita reescriure la taula sencera sota bloqueig.

-- Pas 1: columna nullable (instantani, només metadades)
ALTER TABLE prestecs ADD COLUMN canal_alta text;

-- Pas 2: emplenament per lots (aquí, simplificat; en producció, per blocs
-- de N files amb confirmació intermèdia per no crear una transacció llarga)
UPDATE prestecs SET canal_alta = 'taulell' WHERE canal_alta IS NULL;

-- Pas 3: ja sense files nul·les, imposar la restricció
ALTER TABLE prestecs
    ALTER COLUMN canal_alta SET NOT NULL,
    ADD CONSTRAINT prestecs_canal_alta_valid
        CHECK (canal_alta IN ('taulell', 'web', 'app'));

L'índex justificat per EXPLAIN és el V3 de l'apartat 7, amb CONCURRENTLY i amb l'ordre de columnes raonat. La restricció que puja de l'aplicació al motor és el V4 de les reserves de sales sense solapaments.

4 i 5. El comentari de capçalera de cada fitxer explica el perquè —el tiquet, el pla d'execució que el va motivar, la lliçó del curs que el fonamenta— perquè d'aquí a un any el "què" es llegeix al SQL i el "per què" no és enlloc. La verificació final és la que dona sentit a tot l'exercici: dropdb bibliored && createdb bibliored, aplicar les migracions des de zero i comparar l'esquema resultant (pg_dump --schema-only) amb el de la base de dades original. Si no coincideixen, hi ha algun canvi que es va fer a mà i no és a cap migració: exactament el problema que aquest apartat ve a resoldre.

Solució 3 (resposta model)

Peça Elecció Davant de Per què Prova de foc a un mes
Motor local PostgreSQL 16 en contenidor Instal·lació nativa Puc tenir dues versions alhora i destruir-lo sense residus Aixecar l'entorn en una màquina nova en menys de deu minuts
Client principal psql amb .psqlrc propi Client gràfic És al servidor, al contenidor i al guió de desplegament Resoldre un incident sense obrir interfície gràfica
Client gràfic DBeaver pgAdmin També obro SQLite i MongoDB, i DBeaver els cobreix amb un sol client Explorar un esquema aliè de 40 taules i entendre'l en una tarda
Migracions Flyway amb SQL pur Liquibase No necessito reversió automàtica ni diversos motors; vull SQL llegible Reconstruir la base de dades des de zero i que l'esquema coincideixi
Diagrames Mermaid al README dbdiagram.io El diagrama s'ha de versionar amb l'esquema, no viure en un altre web Que el diagrama continuï correcte després de tres canvis d'esquema
Diagnòstic EXPLAIN + pg_stat_statements Eina comercial de monitoratge Vénen amb el motor i responen el 90 % de les preguntes Identificar la consulta que més temps total consumeix i millorar-la

Descarts explícits. Elasticsearch i Neo4j: no els instal·lo fins a tenir un requisit de cerca amb tolerància a errades o de recorregut de grafs que PostgreSQL amb pg_trgm o consultes recursives no cobreixi. pgBackRest: no fins que administri una base de dades de la qual depengui algú que no sigui jo; mentrestant, pg_dump automatitzat i restaurat trimestralment. Client comercial de pagament: no fins que DBeaver m'entrebanqui de debò.

Conclusió: el tancament del curs

Comencem pel que és petit i acabem pel que és gran.

El petit: de tot l'inventari d'aquesta lliçó, sis peces basten —PostgreSQL local, psql, Docker Compose, un client gràfic, una eina de migracions i EXPLAIN amb pg_stat_statements—. Amb això pots dissenyar, mesurar, versionar i recuperar, que és tot el que cal per treballar bé. Afegeix eines quan un problema real te les demani, i no abans. I recorda els dos advertiments que governen tot el mòdul 9: versions, llicències, preus i plans gratuïts canvien sense avís, i la documentació oficial mana sobre qualsevol curs, inclòs aquest.

I ara el gran, perquè amb aquesta lliçó es tanca el curs sencer.

Han estat nou mòduls i trenta-sis lliçons. Val la pena mirar enrere el recorregut complet, perquè des de dins no sempre es veu.

Vas començar a 01-01 amb una pregunta que semblava ingènua: què és una base de dades i per què no n'hi ha prou amb un full de càlcul. La resposta va ocupar el mòdul 1 sencer —tipus de bases de dades, cinquanta anys d'història des dels sistemes jeràrquics fins avui, i l'arquitectura per dins d'un gestor—. Al mòdul 2 vas aprendre el model relacional i SQL de debò: no només SELECT, sinó unions de diverses taules, agregació, subconsultes correlacionades i integritat referencial, amb la idea que ho vertebra tot: si la regla és d'integritat, viu a la base de dades. El mòdul 3 et va treure d'allà expressament per ensenyar-te NoSQL, les seves quatre famílies i el seu modelatge, i sobretot perquè veiessis el model relacional des de fora i entenguessis que és una elecció i no una llei natural.

Els mòduls 4 i 5 van ser els de l'ofici silenciós: dissenyar. Diagrames entitat-relació, transformació a esquemes, tipus de dades i restriccions, dependències funcionals, formes normals fins a la de Boyce-Codd, i —la part que molts cursos no expliquen— desnormalitzar expressament i saber justificar per què. El mòdul 6 va posar el sistema sota pressió: transaccions i ACID, dos terminals oberts veient amb els teus propis ulls una actualització perduda, plans d'execució llegits línia a línia, permisos i còpies de seguretat. El mòdul 7 van ser quatre lliçons d'exercicis sense xarxa. I el mòdul 8 et va fer construir de zero: BiblioRed en relacional, VallBici en documental, i finalment quatre motors repartint-se un servei municipal amb una taula que declarava, camp a camp, qui mana sobre què.

Què saps fer ara. Pots asseure't davant d'un domini que no coneixes, fer les preguntes correctes, dibuixar el model, transformar-lo en taules amb els seus tipus i les seves restriccions, normalitzar-lo, decidir on convé trencar la normalització i defensar-ho. Pots escriure consultes multitaula amb agregació sense buscar la sintaxi. Pots llegir un pla d'execució, decidir un índex i justificar l'ordre de les seves columnes. Pots raonar quin nivell d'aïllament necessita una operació i quina anomalia estàs acceptant. Pots decidir si un problema demana un document, una clau-valor, un graf o una taula, i —més important— quan no ho demana. I pots muntar l'entorn, versionar-lo i recuperar-lo.

Això no és poc. És, amb bastant precisió, el que s'espera d'algú que treballa amb dades amb criteri.

Què falta, dit amb honestedat: l'experiència. Cap lliçó no dona el que dona haver tingut una base de dades en producció amb gent depenent-ne. Ningú no entén del tot per què les còpies es proven fins que n'ha necessitat una; ningú no interioritza els nivells d'aïllament fins que ha vist dos cobraments duplicats un dimarts al matí. Això arriba amb el temps, i aquest curs l'únic que ha fet —que ja és bastant— és preparar-te per reconèixer-ho quan passi, en lloc de patir-ho sense entendre-ho.

Així que la invitació final és la mateixa que tancava 08-03, i ara tens totes les eines per acceptar-la: tria un dels casos —el BiblioRed relacional dels mòduls 4 i 5, el VallBici documental de 08-02, o el poliglota de 08-03—, munta'l a la teva màquina amb el docker-compose.yml d'aquesta lliçó, carrega'l amb mig milió de files, i trenca'l. Mata el contenidor de Redis i mira què continua funcionant. Obre dos terminals i provoca un interbloqueig. Esborra la base de dades sencera i restaura-la des de la teva còpia. Crea un índex que no serveixi de res i esbrina amb EXPLAIN per què no serveix. Cadascuna d'aquestes coses t'ensenyarà més que rellegir la lliçó corresponent, perquè el coneixement que es queda és el que es paga amb un error propi.

Gràcies per arribar fins aquí. Trenta-sis lliçons són moltes, i acabar un curs complet —no abandonar-lo al mòdul 3, que és el que li passa a la majoria de la gent amb la majoria dels cursos— diu alguna cosa real sobre com treballes. Les bases de dades són una de les poques àrees de la informàtica on el que aprens envelleix a poc a poc: l'article de Codd té més de cinquanta anys i continua sent la base del que has estudiat, i les decisions que ara saps prendre et continuaran servint quan canviïn els llenguatges, els marcs de treball i les modes.

Ja no hi ha lliçó següent. Hi ha una base de dades buida esperant que decideixis què hi va dins. Sort amb ella.

© Copyright 2026. Tots els drets reservats