65 - Creación de tablas sin el campo rowid

Hemos dicho que SQLite cuando se crea una tabla en forma automática se crea un campo autoincremental. En el caso que la tabla defina un campo de tipo 'integer primary key' dicho campo será un alias del rowid.

Hay situaciones que para optimizar los espacios de almacenamiento y las velocidades en las ejecuciones de las consultas podemos crear tablas sin el campo rowid.

Para forzar a SQLite que no cree el campo 'rowid' debemos utilizar la cláusula 'without rowid' como línea final en la instrucción 'create table'.

Problema resuelto

Trabajar con la tabla "usuarios". Procedemos a eliminarla en el caso que exista:

drop table if exists usuarios;

Creamos la tabla especificando que no cree el campo 'rowid':

create table usuarios(
	nombre text primary key,
	clave text
) without rowid;

Cuando se crea una tabla con la cláusula 'without rowid' debe obligatoriamente definirse el 'primary key' sino se produce un error en la creación de la tabla.

Insertemos algunas filas en la tabla:

insert into usuarios(nombre,clave) values ('marcos','zaddwdf1');
insert into usuarios(nombre,clave) values ('ana','123qtew');
insert into usuarios(nombre,clave) values ('luis','gfd32dsd');

Mostremos todos los datos mediante un select:

select * from usuarios;

Tratemos de mostrar el campo 'rowid':

select rowid from usuarios;

Se genera el siguiente mensaje de error:

rowid con without rowid

Eliminemos la tabla "usuarios":

drop table usuarios;

Ahora procedemos a crearla sin la cláusula 'without rowid':

create table usuarios(
	nombre text primary key,
	clave text
);

Insertemos algunas filas en la tabla:

insert into usuarios(nombre,clave) values ('marcos','zaddwdf1');
insert into usuarios(nombre,clave) values ('ana','123qtew');
insert into usuarios(nombre,clave) values ('luis','gfd32dsd');

Ahora si procedamos a mostrar los campos nombre, clave y rowid:

select rowid, nombre, clave from usuarios;

rowid sin without rowid

Acotaciones.

La cláusula 'without rowid' se encuentra solo en SQLite, no es compatible con ningún otro motor de base de datos SQL como MySQL, SQL Server, Oracle etc. En estos otros sistemas de gestión de base de datos todas las tablas se comportarían como tablas 'without rowid'. Sin embargo, cuando SQLite se diseñó por primera vez, solo usaba rowids enteros para las claves de fila para simplificar la implementación. Este enfoque funcionó bien durante muchos años. Pero a medida que las demandas sobre SQLite crecieron, la necesidad de tablas en las que la clave primaria realmente se correspondía con la clave de fila subyacente se hizo más aguda.
El concepto 'without rowid' fue agregado para satisfacer esa necesidad sin romper la compatibilidad con los miles de millones de bases de datos SQLite que ya estaban en uso en ese momento.

Es conveniente utilizar la cláusula 'without rowid' para tablas que definan claves primarias que no sean de tipo 'integer' o claves formadas por más de un campo.

Una tabla que define 'without rowid' es una optimización que puede reducir los requisitos de almacenamiento y procesamiento.