SQLite y PostgreSQL en la práctica
💡 🎯 Al terminar esta lección podrás…
- Explicar las diferencias de arquitectura entre SQLite y PostgreSQL.
- Usar las terminales
sqlite3ypsql. - Adaptar el SQL entre los dos motores.
- Conectar una aplicación de Node.js a cada uno con consultas parametrizadas.
1.Dos motores, dos filosofías
SQL es el lenguaje; SQLite y PostgreSQL son dos programas (motores) que lo entienden. Lo que aprendiste hasta aquí sirve para ambos, con pequeñas diferencias que verás en esta lección.
| SQLite | PostgreSQL | |
|---|---|---|
| Arquitectura | Una biblioteca: la base de datos es un solo archivo; no hay servidor | Cliente-servidor: un servidor que escucha y al que te conectas |
| Instalación | Casi nula (viene en muchos sistemas) | Hay que instalar y configurar el servidor |
| Usuarios y permisos | No tiene (los permisos son los del archivo) | Roles, contraseñas y permisos por tabla |
| Concurrencia | Muchas lecturas; una escritura a la vez | Muchos usuarios leyendo y escribiendo a la vez |
| Tipos | Flexibles: la columna sugiere el tipo, no lo impone | Estrictos: rechaza un texto en una columna entera |
| Ideal para | Aprender, apps móviles y de escritorio, prototipos y sitios pequeños | Aplicaciones web con muchos usuarios y datos importantes |
Una buena ruta: aprende y prototipa con SQLite y pasa a PostgreSQL cuando tu aplicación necesite varios usuarios y control de acceso. Como el SQL básico es el mismo, el cambio es pequeño.
2.SQLite en la práctica
Descarga las «command-line tools» desde sqlite.org/download (en macOS ya viene instalado; en Linux, sudo apt install sqlite3). Comprueba la instalación abriendo una terminal:
sqlite3 tienda.db
Si tienda.db no existe, se crea al guardar algo. Dentro del programa escribes SQL terminado en ; y comandos de punto (sin ;) que controlan el programa:
| Comando | Para qué sirve |
|---|---|
.help | Ver todos los comandos |
.tables | Listar las tablas |
.schema productos | Ver el CREATE TABLE de una tabla |
.headers on y .mode column | Mostrar los resultados con encabezados y en columnas |
.read tienda.sql | Ejecutar un archivo de SQL |
.quit | Salir |
Un flujo de trabajo típico: escribes tu esquema en tienda.sql, lo cargas con .read y consultas. También puedes ejecutar una instrucción sin entrar al programa:
sqlite3 -header -column tienda.db "SELECT nombre, precio FROM productos WHERE precio > 100 ORDER BY precio;"
Con los datos de la tienda, esa consulta devuelve:
Resultado esperado
| nombre | precio |
|---|---|
| Teclado | 120.00 |
| Webcam | 150.00 |
| Monitor FHD | 650.00 |
| Monitor 4K | 899.00 |
💡 Consejo · Recuerda las claves foráneas
En SQLite, cada vez que abras una conexión debes ejecutar PRAGMA foreign_keys = ON; si quieres que se cumplan (lección 5). En PostgreSQL ya lo están.
3.PostgreSQL en la práctica
Instálalo desde postgresql.org/download (el instalador de Windows incluye psql y un panel gráfico). Durante la instalación elegirás una contraseña para el usuario administrador postgres: guárdala. El servidor se queda funcionando en segundo plano.
psql -U postgres
Igual que SQLite, psql tiene sus propios comandos, que empiezan por una barra invertida:
| Comando | Para qué sirve |
|---|---|
\l | Listar las bases de datos |
\c tienda | Conectarte a la base tienda |
\dt | Listar las tablas |
\d productos | Describir una tabla |
\i tienda.sql | Ejecutar un archivo de SQL |
\q | Salir |
Aquí, además de las tablas, creas la base de datos y un usuario propio para tu aplicación (no uses postgres en tus programas):
CREATE DATABASE tienda;
CREATE ROLE tienda_app LOGIN PASSWORD 'cambia-esta-clave';
GRANT ALL PRIVILEGES ON DATABASE tienda TO tienda_app;
Con la base creada, tu esquema casi no cambia. Lo único que debes adaptar es la sintaxis que ves en la siguiente sección.
4.Diferencias de sintaxis que debes conocer
La mayor parte del SQL es idéntico. Estas son las diferencias que más te encontrarás:
SELECT 'Teclado' LIKE 'tec%' AS coincide,
'Mon' || 'itor' AS junto,
typeof(1) AS tipo1,
typeof('1') AS tipo2;
Resultado esperado
| coincide | junto | tipo1 | tipo2 |
|---|---|---|---|
| 1 | Monitor | integer | text |
LIKE y || funcionan igual en ambos motores, pero en PostgreSQL LIKE distingue mayúsculas y para ignorarlas se usa ILIKE. En el siguiente laboratorio tienes la lista de equivalencias.
Sobre los tipos: SQLite acepta un texto en una columna INTEGER y lo guarda tal cual:
CREATE TABLE prueba (n INTEGER);
INSERT INTO prueba VALUES ('hola');
SELECT n, typeof(n) AS tipo FROM prueba;
Resultado esperado
| n | tipo |
|---|---|
| hola | text |
PostgreSQL rechazaría esa inserción con invalid input syntax for type integer: "hola". Es una ventaja: los errores se detectan al guardar, no meses después.
5.Pruébalo: traductor de SQLite a PostgreSQL
Elige una tarea y mira cómo se escribe en cada motor. Úsalo como chuleta cuando cambies de uno a otro.
6.Conectar desde Node.js
Tu aplicación se conecta a la base de datos con una biblioteca. El patrón es el mismo en ambos motores: abrir la conexión, enviar la consulta con parámetros (nunca pegando valores en el texto; lo verás en la lección 8) y recibir un arreglo de filas. Los ejemplos usan módulos ES ("type": "module" en tu package.json).
SQLite con better-sqlite3 (npm install better-sqlite3). Es síncrono y muy simple:
import Database from 'better-sqlite3';
const db = new Database('tienda.db');
db.pragma('foreign_keys = ON');
const minimo = 100;
const filas = db.prepare('SELECT nombre, precio FROM productos WHERE precio > ?').all(minimo);
console.log(filas);
PostgreSQL con pg (npm install pg). Es asíncrono y usa un pool de conexiones:
import pg from 'pg';
const pool = new pg.Pool({ connectionString: process.env.DATABASE_URL });
const minimo = 100;
const { rows } = await pool.query(
'SELECT nombre, precio FROM productos WHERE precio > $1',
[minimo]
);
console.log(rows);
await pool.end();
La variable DATABASE_URL tiene este aspecto (los datos son ejemplos): postgres://tienda_app:cambia-esta-clave@localhost:5432/tienda. Va en una variable de entorno o en un archivo .env que no se sube a Git.
⚠️ Importante · Los marcadores cambian
SQLite usa ? como marcador de parámetro; PostgreSQL usa $1, $2… Es otra diferencia que debes recordar al mover código de un motor a otro.
7.Errores frecuentes
- Copiar un
CREATE TABLEde un motor a otro sin adaptarlo (AUTOINCREMENT,SERIAL,GENERATED … AS IDENTITY). - Terminar un comando de punto con
;en SQLite (.tables;) o escribir SQL sin;final: el programa se queda esperando. - Usar
LIKEen PostgreSQL esperando que ignore mayúsculas: necesitasILIKE. - No activar
PRAGMA foreign_keys = ONen SQLite al conectar desde tu programa. - Conectar tu aplicación como
postgres(administrador): crea un rol propio con los permisos justos. - Escribir la contraseña de la base dentro del código y subirla a un repositorio: usa variables de entorno.
- Mezclar marcadores:
?enpgo$1enbetter-sqlite3da error. - Olvidar cerrar el pool (
pool.end()) en un script: el programa no termina.
📒 Apuntes para llevar
- SQLite es un archivo sin servidor, perfecto para aprender y prototipar; PostgreSQL es un servidor para aplicaciones con muchos usuarios.
- Mismo SQL en lo esencial; cambian los identificadores automáticos,
ILIKE, funciones de fecha y el tipado (flexible frente a estricto). - SQLite:
sqlite3 tienda.db,.tables,.schema,.read,.quit. - PostgreSQL:
psql -U postgres,\l,\c,\dt,\d,\i,\q. - En PostgreSQL crea una base y un rol propio para tu app; no uses el administrador.
- En Node.js:
better-sqlite3(parámetros?) ypg(parámetros$1). - Guarda la cadena de conexión en una variable de entorno, no en el código.
8.Glosario
| Término | Significado |
|---|---|
| Motor de base de datos | Programa que guarda los datos y ejecuta las consultas SQL (SQLite, PostgreSQL, MySQL…). |
| Cliente-servidor | Arquitectura en la que un servidor atiende las peticiones de varios clientes que se conectan a él. |
| psql | Terminal interactiva de PostgreSQL. |
| Comando de punto | Orden propia del programa sqlite3 que empieza con . y no es SQL. |
| Rol | Usuario o grupo de PostgreSQL con permisos propios. |
| Cadena de conexión | Texto con usuario, clave, servidor, puerto y base a la que conectarse. |
| Pool de conexiones | Conjunto de conexiones abiertas que se reutilizan entre consultas. |
| Tipado estricto | Cuando el motor rechaza valores que no corresponden al tipo de la columna. |
🧠 Comprueba lo aprendido
Elige una respuesta en cada pregunta. Verás al instante si acertaste y por qué.
¿Dónde guarda SQLite una base de datos?
SQLite es una biblioteca: la base entera es un archivo (tienda.db).
¿Cuál de estos es un motor cliente-servidor?
PostgreSQL funciona como un servidor al que se conectan los clientes.
¿Qué comando de psql lista las tablas?
.tables es de SQLite; en psql se usa \dt.
¿Cómo se escribe un marcador de parámetro en el paquete pg de Node.js?
pg usa $1, $2…; better-sqlite3 usa ?.
¿Dónde conviene guardar la contraseña de la base de datos de tu aplicación?
Las credenciales no deben subirse al repositorio; se leen de variables de entorno.
Tu progreso se guarda en este navegador y se refleja en el índice del curso.
💡 🚀 ¡Ahora te toca!
La práctica fija lo aprendido. Pasa al ejercicio de esta lección.