Linux Fu: las bases de datos son sistemas de archivos de nivel superior

Es curioso cómo la tecnología informática exótica finalmente falla o se convierte en algo común. Érase una vez tener más de un usuario en una computadora a la vez era alta tecnología, por ejemplo. Luego, hay cosas que no han captado mucho como una pantalla vectorial o una memoria direccionable por contenido. El uso de almacenamiento masivo, especialmente unidades de disco, en computadoras, aunque está muy extendido. Pero una vez fue una técnica exótica y no era tan simple como lo es hoy.

Sin embargo, me sorprende que el sistema de archivos, como sabemos, no haya cambiado mucho a lo largo de los años. Ciertamente, en comparación con, digamos, la década de 1960, tenemos un desempeño mucho mejor. Y tenemos muchas mejoras en cuanto a velocidad, cifrado, cifrado, compresión, etc. Pero la naturaleza fundamental de cómo almacenamos y accedemos a los archivos en los programas de computadora está estancada. Pero no tiene por qué serlo. Conocemos mejores formas de organizar los datos, pero por alguna razón muchos de nosotros no los usamos en nuestros programas. Sin embargo, resulta que es bastante simple y les mostraré cómo con una aplicación de juguete que podría ser el comienzo de una base de datos para los elementos electrónicos en mi laboratorio.

Puede guardar dichas bases de datos en un archivo limitado por comas o usar algo como JSON. Pero usaré una base de datos SQLite empaquetada para evitar tener un servidor de base de datos pesado y todo el dolor que eso conlleva. ¿Reemplazará la base de datos detrás del sistema de reserva de aerolíneas? No. Pero, ¿funcionará para la mayor parte de lo que probablemente haga? Usted apuesta.

Abstracción

Si lo piensa, el sistema de archivos no es más que una abstracción sobre la unidad de disco. Por lo general, no sabemos ni nos importa dónde exactamente hello.c se conserva. Ni siquiera nos importa si está encriptado o comprimido. Podría traerse a través de una red o todas sus piezas podrían esparcirse aleatoriamente por el disco. Por lo general, no nos importa. ¿Qué pasa si abstrae el sistema de archivos en sí?

Esa es casi la idea de una base de datos. Si tengo una lista de, por ejemplo, elementos electrónicos, podría almacenarlos en un archivo limitado por comas y leerlo con una hoja de cálculo. O podría usar una base de datos completa. El problema con las bases de datos es que tradicionalmente necesita algún programa de servidor como MySQL, SQLServer u Oracle, por ejemplo. Puede abstraer la interfaz de la base de datos, pero es una solución bastante pesada en comparación con simplemente abrir un archivo y usarlo normalmente.

Sin embargo, existe una biblioteca de uso común llamada SQLite, que proporciona una base de datos bastante robusta que puede vivir en un archivo sin un servidor externo o mantenimiento. Existen limitaciones, por supuesto, pero para muchos programas simples puede brindar los beneficios de una base de datos sin una carga ni un gasto.

La herramienta adecuada para el trabajo adecuado

Por supuesto, hay límites. Sin embargo, si está ejecutando su propio formato de archivo para algo, podría considerar cambiar a SQLite y tratarlo como una base de datos. Según el sitio web del proyecto, hacerlo puede ahorrar espacio y aumentar la velocidad de acceso. Además, una vez que lo detecta, es más fácil. También es más fácil escalar más adelante si decide cambiar a una base de datos real.

Si está almacenando bases de datos enormes (como una escala de terabytes) o necesita muchos usuarios simultáneos, especialmente escribir en la base de datos, es posible que esto no sea adecuado para usted. El sitio web de SQLite tiene una buena página sobre usos que son buenos y no óptimos para la biblioteca.

Otra ventaja: hay un programa de línea de comandos (y algunas variantes de GUI como el navegador en la imagen adjunta) que le permiten trabajar con bases de datos SQLite sin escribir código. Por lo tanto, puede hacer cosas como completar sus datos o examinar su base de datos sin escribir SQL en absoluto. Para un formato de archivo personalizado, probablemente debería hacer todo usted mismo o completar y depurar los datos con una herramienta general que no conozca sus datos específicos.

Mi tarea

No quiero desarrollar una aplicación completa en una publicación, ni quiero enseñar SQL, el lenguaje de consulta estructurado que la mayoría de las bases de datos incluyen usando SQLite. Pero quiero mostrarles lo fácil que es comenzar una base de datos electrónica simple con C. El código C mostrará el menor de nuestros problemas. Las dos cosas que más desea comprender son cómo estructurar los datos (el esquema de la base de datos) y cómo ejecutar los datos iniciales. Incluso si desea que su programa agregue datos eventualmente, está bien comenzar con algunos datos inicialmente para que su programa esté en funcionamiento.

Bases de datos básicas

Una base de datos relacional moderna tiene una o más matrices. Cada tabla tiene filas de datos. Una fila tiene una o más columnas y cada columna tiene un tipo de datos. Por ejemplo, puede tener una columna de texto para un número de serie, un valor numérico real para un voltaje de punto de prueba y una viñeta para pasa / falla.

Cada tabla tiene un identificador único por fila. La base de datos le proporcionará uno si no lo hace, pero por lo general, usted mismo querrá proporcionar este identificador único. La base de datos lo ayudará automáticamente aumentando el número y asegurándose de que sea único para cada fila.

Si esto es todo, no tendría muchas ventajas sobre un archivo limitado por comas. Pero podemos hacer muchas cosas mejor una vez que tengamos esta estructura organizativa. Por ejemplo, es fácil pedirle a la base de datos que ordene los elementos o seleccione los tres voltajes más altos de la tabla.

Sin embargo, una de las mayores ventajas de una base de datos es poder realizar fusiones. Supuestamente tengo una lista de componentes: placa de computadora, resistencia, mango de batería y LED. Tengo una tabla que tiene una fila correspondiente a cada uno de ellos. Ahora suponga que quiero tener una matriz de conjuntos que constan de elementos.

Podría hacer un enfoque simple:

Table Component
ID    Name
===========
1     PCB
2     Resistor
3     LED
4     Battery Holder

Table Assembly
ID    Name       Components
============================
1     Blink1     PCB, Resistor, LED, Battery Holder
2     Blink2     PCB, Resistor, LED, Resistor, LED, Battery Holder



That's ugly and wasteful. A better approach would be to use three tables:

Table Component
ID Name
===========
1 PCB
2 Resistor
3 LED
4 Battery Holder

Table Assembly
ID Name 
=========
1 Blink1 
2 Blink2 

Table Assembly_Parts
ID    Component    Quan
=======================
1     1            1
1     2            1
1     3            1
1     4            1
2     1            1
2     2            2
2     3            2
2     4            1

Usando una operación de unión, puede vincular estas matrices para generar, lo que equivale a la primera matriz sin duplicar muchos datos.

Para mi base de datos de juguetes, crearé tres tablas: part contendrá las partes que tengo. La partnums La tabla contendrá tipos de piezas (p. ej., 7805 frente a 2N2222 o CDP1802. Por último, locations una mesa me dirá dónde guardo las cosas. Estas otras formas podrían estructurarse. Por ejemplo, podría haber una tabla para almacenar tipos de huellas: 2N2222 puede estar en TO92 o en montaje en superficie. Además crearé una vista que muestre todo desplegado como en el primer ejemplo. Una vista es algo que no se conserva, pero que sirve como mesa para la comodidad. De hecho, es solo una cuestión de la base de datos con la que puede trabajar.

Por supuesto que hay mucho más. Hay juntas internas y externas y muchos otros detalles y matices. Afortunadamente, hay mucho material para leer sobre bases de datos en la web, incluida la documentación de SQLite.

SQL suficiente

Para nuestros propósitos, solo usaremos un puñado de declaraciones SQL: create, insert, y select. Es factible sqlite3, donde puede ingresar comandos de la base de datos. Puede dar el nombre de la base de datos en la línea de comando y esa es la forma más fácil. Usar .exit cuando quieras salir.

Probablemente pueda averiguar la sintaxis SQL, ya que es bastante detallada:

create table part ( id integer not null primary key, name text, partnum integer, value text, 
   units text, quantity integer, photo blob, data text, location integer, footprint text);
create table partnums (id integer not null primary key, partnum text, desc text);

create table locations (id integer not null primary key, location text, desc text);

create view full as select part.id, name, partnums.partnum as part_number, value, units, 
   quantity, data, locations.location as location, footprint from part 
   inner join partnums on part.partnum = partnums.id inner join locations on locations.id=part.location

Acabo de hacer esas llamadas en el programa de línea de comandos sqlite3 aunque podría usar la GUI o, si quisiera, podría hacer que mi programa C ejecute esos comandos. También usé la línea de comando para insertar algunos registros de prueba. Por ejemplo:

insert into locations (location,desc) values ("Shop - storage II","Storage over computer desk in shop");
insert into partnums(partnum,desc) values("R.25W","Quarter Watt Resistor");
insert into part(partnum,quantity,location,value,units) values (2,111,1,"10K","ohms");

Para recuperar datos, utilizará el comando de selección:

select * from part;

select partnum, quantity from part where quantity<5;

Si desea saber más, hay muchos tutoriales de SQL en la web.

¡Programado!

Hasta ahora, nada de esto ha requerido programación. Asumiendo que tienes el libsqlite3-dev paquete o su equivalente, no necesita mucho para agregar funciones de base de datos a su programa C. Necesitarás incluir sqlite3.h. Si no puede encontrarlo, probablemente no tenga instalados los archivos de desarrollo. También necesitará conectarse con libsqlite3. Para un proyecto simple de un solo archivo, este archivo MAKE probablemente lo ayudará a comenzar:

CC=gcc
CFLAGS+=-std=c99 -g
LDFLAGS=-g
LDLIBS+=-lsqlite3

edatabase : main

main : main.c

El código en sí es simple. Debe abrir el archivo de la base de datos (sqllite3_open). En lugar de un archivo, puede pasar “: memory” para obtener una base de datos en memoria que no durará más allá de la vida útil de su programa. La llamada devolverá un anticipo a su base de datos. A continuación, debe analizar o preparar la declaración SQL que desea completar. Este podría ser cualquiera de los SQL que realizamos con la interfaz o muchas otras sentencias SQL. En mi caso, quiero extraer los datos de la vista completa y mostrarlos, así que analizaré:

select * from full;

Finalmente, llamas sqlite3_step y mientras vuelva SQLITE_ROW, puede procesar la cola con llamadas como sqlite3_column_text. Finalmente finalizas la base de datos y la cierras. Aquí está el código con el manejo de errores eliminado:

#include <sqlite3.h>
#include <stdio.h>

int main(int argc, char *argv[])
   {
   sqlite3 *db;
   sqlite3_stmt *sql;
   int rv;

   rv=sqlite3_open("parts.db",&db);
   rv=sqlite3_prepare_v2(db, "SELECT * from full", -1, &sql, NULL);
   do
     {
     rv=sqlite3_step(sql);
     if (rv==SQLITE_ROW)
        {
        printf("%s,",sqlite3_column_text(sql,0));
        printf("%sn",sqlite3_column_text(sql,2));
        }
     } while (rv==SQLITE_ROW); 
   sqlite3_finalize(sql);
   sqlite3_close(db);
   return 0;
}

O mira el código completo. En un caso en el que no le importaba pasar por las filas, es posible que haya llamado sqlite3_exec. Incluso la documentación reconoce que esto es solo una preparación completa, un paso y un final, por lo que puede entrar en una cadena y esperar a que funcione.

Por supuesto, hay muchas más llamadas. Por ejemplo, puedes llamar sqlite_column_int u otras llamadas para obtener tipos particulares. Puede vincular parámetros a llamadas SQL para establecer valores en lugar de crear una cadena. Pero esto le muestra lo fácil que es hacer un programa SQLite simple.

Entonces, la próxima vez que se le ocurra un nuevo formato de archivo, piense en usar SQLite en su lugar. Obtendrá herramientas gratuitas y, después de aprender SQL, encontrará que puede hacer muchas cosas sin escribir código real que no sean diferentes comandos SQL. Incluso puede usar la ramificación similar a Git para guardar versiones de su base de datos. Una vez más, algunas personas usan git como base de datos, pero nosotros no lo sugerimos.

  • Karl Ramboz dice:

    Tu idea de estancamiento es mi idea de estabilidad.

Marco Navarro
Marco Navarro

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *