Una base de datos que vive en la RAM
SQLite tiene un nombre de archivo especial: :memory:. Si abres una base de datos con ese nombre, SQLite se salta el disco por completo y toda la base de datos vive en la RAM. Las tablas, los índices, las transacciones, las claves foráneas... todas las funciones se comportan exactamente igual. La única diferencia es que, al cerrar la conexión, la base de datos desaparece.
Desde la línea de comandos:
sqlite3 :memory:
Ya estás en el prompt de SQLite con una base de datos sqlite en memoria, recién creada y vacía. Crea una tabla, inserta algunas filas y consúltalas; todo funciona como siempre:
Sales de la sesión y esos datos se esfuman. No queda ningún archivo en disco, porque nunca se llegó a crear.
Por qué te conviene usarla
Una base de datos que no sobrevive a un reinicio suena más a bug que a funcionalidad. Pero en realidad resulta muy útil en tres escenarios.
Tests. Cada test arranca con una base de datos limpia en milisegundos. Nada de limpiar archivos temporales, nada de estado residual del run anterior, nada de fixtures compartidos que se quedan bloqueados. La mayoría de las suites de tests en Python, Node y Go que usan SQLite abren :memory: justamente por esto.
Análisis desechable. Cargas un CSV, lanzas unas cuantas consultas y a la papelera. Más rápido que levantar una base de datos de verdad y más cómodo que parsear el archivo a mano cada vez.
Caché y espacio de trabajo. Dentro de un programa de larga duración, una base de datos SQLite en memoria es un motor de consultas ad-hoc sorprendentemente bueno para datos que ya tienes cargados.
El hilo conductor: quieres SQL, pero no quieres persistencia.
Rendimiento: más rápido, pero sin milagros
Una base de datos SQLite en memoria se salta el disco, así que las escrituras que normalmente irían al sistema de archivos pasan a ser simples actualizaciones en RAM. Las cargas de trabajo limitadas por I/O ganan velocidad de forma notable. Las que están limitadas por CPU —planificación de consultas compleja, ordenaciones grandes— apenas cambian, porque SQLite ya cacheaba en memoria las páginas calientes de todos modos.
Una demostración rápida de lo idéntica que es la sintaxis:
Eso lo ejecutamos contra una base de datos en memoria, pero es exactamente el mismo SQL que correrías contra un archivo. Al motor de la base de datos le da igual.
SQLite en memoria vs archivo: cuándo usar cada uno
El compromiso es sencillo y vale la pena dejarlo claro:
- Base de datos en archivo (
mydata.db): Sobrevive a los reinicios. Varios procesos pueden abrirla a la vez. Aguanta caídas (en modo WAL, casi siempre). Úsala cuando necesites recordar cosas. - Base de datos en memoria (
:memory:): Desaparece al cerrar la conexión. Es privada de la conexión que la abrió (por defecto). Más rápida para trabajo desechable con muchas escrituras. Ideal para tests, pruebas rápidas y cachés efímeros.
Si tienes dudas, lo que quieres es un archivo. Lo de memoria es el caso especial.
Cada conexión tiene su propia base de datos en memoria
Hay un detalle que pilla a mucha gente: abrir :memory: dos veces te da dos bases de datos totalmente distintas. No comparten tablas, no comparten datos, ni siquiera se ven entre sí.
-- Terminal 1
sqlite3 :memory:
sqlite> CREATE TABLE t (x); INSERT INTO t VALUES (1);
-- Terminal 2
sqlite3 :memory:
sqlite> SELECT * FROM t;
Error: no such table: t
No es un fallo, es así por diseño. :memory: significa "una base de datos privada para esta conexión". Lo mismo ocurre dentro de un mismo programa: si tu código abre dos conexiones a :memory:, cada una tendrá su propia base de datos aislada.
Compartir una base de datos SQLite en memoria entre conexiones
Si necesitas que varias conexiones vean la misma base de datos en memoria, SQLite lo permite mediante nombres de archivo URI y la caché compartida. La cadena mágica es file::memory:?cache=shared:
sqlite3 'file::memory:?cache=shared'
Cualquier conexión dentro del mismo proceso que abra esa URI exacta se une a la misma base de datos. Cuando cierres todas, la base desaparece.
También puedes asignarle un nombre a la base de datos en memoria, lo cual resulta útil cuando necesitas tener varias bases compartidas pero independientes:
sqlite3 'file:mydb?mode=memory&cache=shared'
El nombre mydb aquí es solo una etiqueta — sigue sin haber ningún archivo. Dos conexiones que abran file:mydb?mode=memory&cache=shared comparten la misma base de datos; en cambio, una conexión que abra file:other?mode=memory&cache=shared obtendrá otra distinta.
Guardar una base de datos SQLite en memoria a disco
A veces haces todo el trabajo en memoria y, al terminar, decides que quieres conservar el resultado. La CLI ofrece el dot-command .backup justo para esto:
sqlite3 :memory:
sqlite> CREATE TABLE results (id INTEGER, score REAL);
sqlite> INSERT INTO results VALUES (1, 0.91), (2, 0.87);
sqlite> .backup snapshot.db
sqlite> .quit
snapshot.db ahora es una base de datos en archivo común y corriente, con el mismo contenido. Puedes abrirla más tarde con sqlite3 snapshot.db y retomar justo donde lo dejaste.
Lo inverso también funciona: .restore carga una base de datos desde un archivo a la memoria de la conexión actual:
sqlite3 :memory:
sqlite> .restore snapshot.db
sqlite> SELECT * FROM results;
Desde el código de tu aplicación, la API en C de SQLite expone la misma maquinaria de sqlite3_backup_init, y la mayoría de los bindings de cada lenguaje la envuelven. Por ejemplo, el módulo sqlite3 de Python tiene Connection.backup().
Un error muy común
A veces se intenta "guardar" una base de datos SQLite en memoria adjuntando un archivo y copiando los datos así:
Eso funciona para copias sencillas de tablas, pero no preserva índices, triggers, vistas ni claves foráneas tal cual estaban. Si quieres una copia fiel de toda la base de datos, usa .backup (o la API de backup): hace una copia binaria exacta a nivel de página.
Lo que te llevas
:memory:es un nombre de archivo especial de SQLite que crea una base de datos en RAM, sin respaldo en disco.- El SQL es idéntico al de una base de datos en archivo: mismas tablas, mismas consultas, mismas restricciones.
- Cada conexión a
:memory:es privada; usa URIs con caché compartida (file::memory:?cache=shared) cuando varias conexiones necesiten compartir la misma. - Es la herramienta ideal para tests, análisis desechables y cachés de vida corta — no para nada que tenga que sobrevivir a un reinicio.
- Cuando decidas conservarla, pasa la base de datos en memoria a disco con
.backup.
Lo que viene: crear tablas
Ya has visto pasar CREATE TABLE en algún ejemplo. La próxima página baja el ritmo y lo recorre como toca: definiciones de columnas, tipos, las restricciones que les puedes poner y esas pequeñas decisiones que hacen que un esquema sea agradable de mantener.
Preguntas frecuentes
¿Cómo se crea una base de datos SQLite en memoria?
Abre SQLite usando el nombre especial :memory: en lugar de una ruta. Desde la CLI sería sqlite3 :memory:; desde una librería, basta con pasar :memory: como nombre de archivo en la llamada de conexión. La base de datos vive en RAM y desaparece en cuanto cierras la conexión.
¿Qué es :memory: en SQLite?
:memory: es un nombre de archivo "mágico" que SQLite interpreta como: "no uses un archivo, guárdalo todo en RAM". Tienes una base de datos SQLite completa — tablas, índices, transacciones, todo — pero nada se escribe en disco. Cada conexión que abre :memory: recibe su propia base de datos privada.
¿Pueden dos conexiones compartir una base de datos SQLite en memoria?
Por defecto no: cada conexión a :memory: está aislada. Para compartirla, ábrela con una URI tipo file::memory:?cache=shared y activa la caché compartida. Todas las conexiones que abran esa misma URI dentro del mismo proceso verán la misma base de datos.
¿Se puede guardar en disco una base de datos SQLite en memoria?
Sí. Usa el comando .backup desde la CLI o la API de backup de tu librería para copiar la base de datos en memoria a un archivo. Otra opción es hacer ATTACH de un archivo y luego INSERT INTO file.tabla SELECT * FROM main.tabla para volcar los datos.