Skip to content

2.2 SQLite

SQLite es una de las bases de datos más desplegadas en el mundo.

La encontrarás en aplicaciones móviles, navegadores web, sistemas operativos y embebidos.

Es relacional, muy ligera y no requiere un servidor para funcionar, ya que almacena los datos en un único archivo.

  • Pros:
    • Muy ligera y rápida.
    • No requiere instalación de servidor.
    • Ideal para aplicaciones pequeñas y medianas.
    • Soporta transacciones ACID.
    • Escala bien para aplicaciones de escritorio y móviles.
  • Contras:
    • No es adecuada para aplicaciones de gran escala o con alta concurrencia.
    • Carece de algunas características avanzadas de bases de datos más grandes (como PostgreSQL o MySQL).
    • Si necesitas una base de datos distribuida o con alta disponibilidad, no es la mejor opción.
    • Carece de soporte de un sistema de usuarios y permisos.

Instalación

En la mayoría de las distribuciones de Linux, SQLite ya viene instalado por defecto. Si no lo tienes, puedes instalarlo con:

sudo apt install sqlite3

Diferencias con otras bases de datos

Aunque usamos SQL como lenguaje de consulta, SQLite tiene algunas diferencias en cuanto a su DDL (Data Definition Language) y DML (Data Manipulation Language) en comparación con otras bases de datos como MySQL o PostgreSQL. Algunas de las diferencias más notables son:

  • Tipos de datos: SQLite es más flexible con los tipos de datos. Por ejemplo, no requiere que declares un tipo de dato específico para una columna; puedes insertar cualquier tipo de dato en cualquier columna si no has especificado un tipo de dato.
  • Autoincremento: En SQLite, puedes usar INTEGER PRIMARY KEY AUTOINCREMENT para crear una columna que se incremente automáticamente. No es necesario especificar AUTO_INCREMENT como en MySQL.
  • Funciones de agregación: Algunas funciones de agregación pueden comportarse de manera diferente. Por ejemplo, SQLite no soporta GROUP BY con columnas que no están en la lista de selección a menos que se use ANY_VALUE().
  • Vistas: Las vistas en SQLite son más simples y no soportan algunas características avanzadas que podrías encontrar en otras bases de datos, como las vistas materializadas.

Tipos de datos

SQLite tiene un sistema de tipos de datos dinámico, lo que significa que no es necesario declarar un tipo de dato específico para una columna. Sin embargo, hay algunos tipos de datos comunes que puedes usar, son diferentes a los de MySQL o PostgreSQL, no esperes que una query que funcione en MySQL o PostgreSQL funcione en SQLite sin modificaciones.

  • INTEGER: Un número entero. Puede ser de 1, 2, 3, 4, 6, 8 bytes dependiendo del valor.
  • REAL Un número de punto flotante de 8 bytes.
  • TEXT: Una cadena de texto. Puede ser de cualquier longitud.
  • BLOB: Un objeto binario grande. Se utiliza para almacenar datos binarios como imágenes o archivos.
  • NULL: Un valor nulo.

A la hora de configurar cada datos, puedes usar varios modificadores para definir el comportamiento de las columnas:

  • PRIMARY KEY: Define una columna como clave primaria.
  • AUTOINCREMENT: Hace que la columna se incremente automáticamente con cada inserción.
  • NOT NULL: Asegura que la columna no puede contener valores nulos.
  • UNIQUE: Asegura que los valores en la columna son únicos.
  • DEFAULT: Define un valor por defecto para la columna si no se especifica uno al insertar.

El orden en el que usas estos modificadores puede variar, pero es común verlos en el siguiente orden:

REPL (Read-Eval-Print Loop)

Para iniciar el REPL de SQLite, simplemente ejecuta:

sqlite3

Esto abrirá una consola interactiva donde puedes ejecutar comandos SQL directamente.

Crear una base de datos

Para crear una nueva base de datos, simplemente especifica el nombre del archivo al iniciar SQLite:

sqlite3 mi_base_de_datos.db

Esto creará un archivo llamado mi_base_de_datos.db en el directorio actual y abrirá la consola de SQLite para interactuar con esa base de datos. A partir de este momento puedes lanzar algo como:

CREATE TABLE usuarios (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    password TEXT NOT NULL UNIQUE
);
INSERT INTO usuarios (name, password) VALUES ('admin', 'admin');

Crear una base de datos a partir de un .sql

Si tienes un archivo .sql con las instrucciones para crear una base de datos, puedes ejecutarlo directamente desde la línea de comandos:

sqlite3 mi_base_de_datos.db < script.sql

Esto ejecutará todas las instrucciones SQL contenidas en script.sql sobre la base de datos mi_base_de_datos.db.

Consultar una base de datos

Puedes lanzar consultas sobre una base de datos sin necesidad de abrir el REPL:

sqlite3 mi_base_de_datos.db "SELECT * FROM usuarios;"

Exportar una base de datos a un archivo .sql

Para exportar una base de datos a un archivo .sql, puedes usar el comando .dump dentro del REPL de SQLite:

sqlite3 mi_base_de_datos.db ".dump" > mi_base_de_datos.sql

Esto generará un archivo mi_base_de_datos.sql con todas las instrucciones SQL necesarias para recrear la base de datos.

PRAGMAS

SQLite utiliza comandos especiales llamados PRAGMAS para modificar el comportamiento de la base de datos o para obtener información sobre su estado.

Los PRAGMAS no son parte del estándar SQL, solo funcionan en SQLite.

Además, no debes confundir los pragmas con el DDL, no son algo que se quede configurado en la base de datos, sino que afectan a la sesión actual que estás utilizando.

Algunos ejemplos comunes de PRAGMAS son:

Habilitar claves foráneas

PRAGMA foreign_keys = ON;

Da igual que en tu tabla hayas definido claves foráneas, si no ejecutas este pragma, SQLite no las aplicará cuando insertes o borres datos.

Wal vs Journal Mode

PRAGMA journal_mode = WAL;
PRAGMA journal_mode = DELETE;

El journal mode define cómo SQLite maneja la integridad de los datos durante las transacciones. WAL (Write-Ahead Logging) es generalmente más rápido y permite mayor concurrencia, mientras que DELETE es el modo tradicional que puede ser más seguro en ciertos escenarios.

Ten en cuenta que SQLite es un archivo que usamos como bases de datos, escribir en disco es costoso, y el journal mode afecta directamente al rendimiento de las operaciones de escritura.

El WAL permite operaciones de lectura y escritura concurrentes, mejorando el rendimiento en aplicaciones con alta concurrencia. Si tu aplicación realiza muchas escrituras, WAL suele ser la mejor opción.

El modo DELETE bloquea la base de datos durante las escrituras, lo que puede ser más seguro en entornos con pocas escrituras concurrentes. Es el modo por defecto en muchas versiones de SQLite.

Modo de sincronización

PRAGMA synchronous = FULL;
PRAGMA synchronous = NORMAL;
PRAGMA synchronous = OFF;

El modo de sincronización controla como las transacciones se aseguran de que los datos se escriben correctamente en el disco.

  • FULL: Asegura la máxima integridad de los datos, pero puede ser más lento.
  • NORMAL: Ofrece un buen equilibrio entre integridad y rendimiento.
  • OFF: Maximiza el rendimiento, pero puede arriesgar la integridad de los datos en caso de fallos del sistema.

Todo esto da igual si no estás trabajando con transacciones, ya que los cambios se aplican inmediatamente.