~/VibeHandbook
PDF gratis

Capítulo 14 · 03

Fundamentos del diseño de esquemas

Un esquema es el plano de tus datos: qué tablas existen, qué columnas tienen y cómo se relacionan. Un buen diseño de esquema es sobre todo sentido común más unos pocos hábitos.

  • Una tabla por "cosa." Usuarios, publicaciones, pedidos: cada uno recibe su propia tabla.
  • Toda fila necesita un ID único (una clave primaria).
  • Enlaza tablas con claves foráneas, no copiando datos de un lado a otro.
  • Elige tipos honestos. El dinero es un decimal, no un float. Las fechas son marcas de tiempo, no texto.
  • No dupliques. Si el correo de un usuario vive en cinco tablas, tarde o temprano tendrás cinco correos distintos.

Aquí hay un esquema sencillo para un blog, del tipo que la IA generará por ti:

CREATE TABLE users (
    id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    email       TEXT NOT NULL UNIQUE,
    created_at  TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE TABLE posts (
    id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    author_id   UUID NOT NULL REFERENCES users(id),
    title       TEXT NOT NULL,
    body        TEXT NOT NULL,
    published   BOOLEAN NOT NULL DEFAULT false,
    created_at  TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE INDEX idx_posts_author ON posts(author_id);

Esa línea author_id ... REFERENCES users(id) es la clave foránea. Conecta cada publicación con exactamente un usuario real, de modo que la propia se niega a almacenar una publicación sin un autor válido:

   users                          posts
   ┌─────────────┐                ┌─────────────┐
   │ id  (PK) ◀──┼────────────────┤ author_id   │  (FK → users.id)
   │ email       │   one user      │ id  (PK)    │
   │ created_at  │   has many      │ title       │
   └─────────────┘   posts         │ body        │
                                   │ published   │
        1  ────────────────────▶  *└─────────────┘
       (one)                    (many)

Fíjate en REFERENCES (una clave foránea que ata una publicación a un usuario real) y en las restricciones NOT NULL y UNIQUE. Estas son barandillas que la base de datos impone por ti, de modo que los datos malos no puedan colarse aunque tu código tenga un error.

Una restricción que vale la pena añadir a propósito es qué sucede cuando el padre desaparece. Por defecto, eliminar un usuario cuyas publicaciones aún lo referencian fallará, que a menudo es lo que quieres. Pero puedes ser explícito: REFERENCES users(id) ON DELETE CASCADE elimina también las publicaciones, mientras que ON DELETE RESTRICT bloquea la eliminación. Elegir a propósito es mejor que descubrir el comportamiento por defecto de la manera difícil, en producción. El mismo instinto de "dejar que la base de datos te proteja" aplica a una restricción CHECK (CHECK (price >= 0)): rechaza datos sin sentido en el origen en vez de confiar en que cada ruta de código valide.

¿Lo quieres sin conexión?

Descarga el libro entero en PDF o EPUB — gratis.