Technics‎ > ‎

Gestión de datos en Matlab desde SQLite


Instalación de la librería mksqlite


mksqlite es una librería para Windows creada por Martin Kortmann bajo licencia GNU Lesser General Public License. La instalación de la misma es sencilla:






  1. Descargar la librería mksqlite de http://developer.berlios.de/projects/mksqlite/
  2. Descomprimir el zip en la carpeta donde se desea instalar.
  3. Agregar en el path de Matlab la carpeta de mksqlite. (File → SetPath → Add Folder).


Creación de la base de datos


La base de datos se puede crear desde el Matlab usando comandos SQL, pero para mayor comodidad existen herramientas gráficas que facilitan la tarea.
El plugin para Firefox "Sqlite Manager" (bajo licencia Mozilla Public License), es una GUI cross Platform para administración de bases de datos SQLite. Se actualiza con frecuencia automáticamente y puede importar archivos xml y csv. Los pasos a seguir son:
  1. Descargar e instalar Mozilla Firefox: http://www.getfirefox.com/
  2. En Firefox, instalar Sqlite Manager: https://addons.mozilla.org/en-US/firefox/addon/5817
  3. Abrir el plugin, desde el menu de Firefox (Herramientas → SQLite Manager)


Conexión a la base de datos


La conexión a la base de datos se realiza de la siguiente manera:

mksqlite(dbid, 'open', databasefile);

Si la base a conectar no existe, se crea con el nombre/ruta especificados.
El primer parámetro (dbid) no es obligatorio y es necesario sólo cuando se va a trabajar con más de una base de datos. Es de tipo numérico y en el caso de utilizarlo se debe pasar como primer parámetro de cualquier instrucción enviada a la librería. 

%Abrir conexión
mksqlite(1,'open','C:\proyecto\myDataBase.sqlite');

%Ejecución de sentencias.
resp = mksqlite(1,'SELECT * FROM coordenadas');

%Cerrar conexión
mksqlite(1,'close');

Ejecución de queries


Las consultas de tipo SELECT devuelven un array struct de tantas filas como registros haya encontrado.

resp = mksqlite('SELECT x, y FROM coordenas');
resp(1).x %devuelve el valor de la columna x del primer registro.

Concatenación de valores


Para armar las sentencias de SQL, se puede concatenar un string colocando los elementos entre [ ]  y separándolos por un espacio. También se deben convertir los números a strings con las funciones int2str y num2str. 

id = 4;
table = 'figuras';
resp = mksqlite(['SELECT * FROM ' table ' where id=' int2str(id)]);

Iteración sobre la respuesta

Este es un ejemplo de iteración sobre una respuesta de mksqlite. Se guardan en una matriz de enteros los datos del array struct que devuelve la consulta.

%Ejecución del query
resp = mksqlite('SELECT y, x FROM coordenadas ORDER BY id');

%Obtención de la cantidad de registros
respCount = size(resp,1);

%Alocación del espacio
A = zeros(respCount,2);

%Carga de valores
for i=1:respCount
A(i,1) = resp(i).y;
A(i,2) = resp(i).x;
end

Optimización


Trabajar con la base en memoria


Utilizar la base totalmente en memoria sin bajar a disco acelera muchísimo los tiempos de ejecución de los queries. Si no se requiere de persistencia en el tiempo ésta es la mejor optimización. 

Para poder hacer esto hay que  hacer un open sin especificar ningún nombre de archivo:

mksqlite(dbid, 'open');

Esta sentencia abre una conexión a una DB nueva que se almacena únicamente en memoria. Luego de hacer la conexión, hay que crear las estructuras de las tablas y popular los datos iniciales necesarios. Al funcionar en memoria, este proceso se hace ejecuta rápidamente.

PRAGMA synchronous


Determina si el motor debe esperar a que se complete la escritura en disco para continuar. Desactivándolo se obtiene un rendimiento significativo (en el orden de unas 40 veces más rápido).

mksqlite('PRAGMA synchronous=OFF');

PRAGMA count_changes


Por defecto cada vez que se ejecuta un comando SELECT, DELETE o UPDATE el motor cuenta la cantidad de registros afectados. De no utilizarse esta función se puede desactivar para aumentar el rendimiento.

mksqlite('PRAGMA count_changes=OFF');

PRAGMA temp_store 


Especifica donde deben alojarse las tablas y archivos temporales de la base de datos. Default(0), Archivo(1), Memoria(2).

mksqlite('PRAGMA temp_store=2');

Uso de BEGIN y COMMIT


Por cada consulta ejecutada el motor crea una nueva transacción con su respectiva escritura en el journal. Para evitar esta pérdida de rendimiento, las consultas sucesivas se deben agrupar en una única transacción encerrándolas entre BEGIN y COMMIT

mksqlite('BEGIN');
% ...
% Transacciones
% ...
mksqlite('COMMIT');

Autores

  • Investigadores de PROA.