Interludio: l'mSQL

di Nando Santagata
lac0658@iperbole.bologna.it

Questa volta parliamo di databases e dell'interfacciamento al Web.
È spesso utile disporre di insiemi di dati da lasciar interrogare agli utenti e la soluzione di buttare tutto in un file ASCII ed usare il grep non è sempre la soluzione migliore: le relazioni tra i dati possono essere complesse e può essere necessario usare un modello relazionale per descriverle.

Data la natura del Web, dovendo scegliere un gestore di dati è opportuno porre attenzione più alla velocità di risposta, che alla potenza del prodotto.
Personalmente ho provato qualche gestore di dati disponibile per Linux (Postgres, Lincks, mSQL), e il più veloce mi è sembrato essere mSQL.

mSQL, pur essendo un gestore di database relazionale SQL, è molto parco nell'uso delle risorse del sistema ed è molto veloce.
Di contro però l'SQL che implementa è molto stringato: scordatevi le sofisticatezze di RDBMS blasonati come Oracle o Informix!

Mancano completamente le funzioni che possono normalmente essere utilizzate nella clausola SELECT (implicit functions), non si possono innestare più SELECTs una dentro l'altra, mancano anche la clausola GROUP BY e il tipo di dati DATE...
È il prezzo che si deve pagare per un codice più agile, più adatto ai problemi che andremo ad affrontare, che, anche se non esattamente real-time, richiedono tempi di risposta comunque contenuti.

L'mSQL è facilmente utilizzabile da molti scripting languages, tra cui il Perl, cosa che lo rende molto appetibile per chi scrive programmi CGI.
Inutile dire che poter usare la potenza di strumenti come il Perl, rende facile supplire alle relative debolezze del linguaggio di interrogazione.

Supponiamo che vi siate già procurati i sorgenti dell'mSQL.
Entrate nella directory che è stata creata scompattando il pacchetto e date il comando:

$ make target

A questo punto nella mia installazione è stata creata la sottodirectory targets/Linux-1.2.13-i486 (ovviamente se avete una diversa versione del Kernel o del processore, il nome della directory sarà diverso).
Spostatevi nella directory appena creata e date il comando:

$ ./setup

Dovrete rispondere a qualche domanda sulla configurazione che desiderate dare al pacchetto: è possibile accettare i defaults proposti (io faccio così di solito).
A questo punto potete far partire il make, che compilerà il pacchetto.
Terminata la compilazione installate il tutto come utente root: entrate come root o eseguite il comando:

$ su -c 'make install'

A questo punto, sempre come utente root, dovete creare l'Access Control List (ACL).
Il modo più rapido di costruirsi un ACL è quello di rinominare quello di esempio che è stato installato. Ovviamente in futuro potrete studiarvi il manuale, che si trova in /usr/local/Minerva/doc e decidere quali privilegi dare ai singoli utenti.

Spostatevi nella directory /usr/local/Minerva. Troverete un file msql.acl.sample, rinominatelo in msql.acl. A questo punto, sempre da root, lanciate il demone mSQL:

$ /usr/local/Minerva/bin/msqld &

Se tutto è andato bene fino a questo momento dovreste avere il server in memoria, quindi siete pronti a creare un database.
In una installazione dell'mSQL possono convivere più databases e all'interno di un database mSQL possono esserci diverse tavole, ognuna contenente i suoi dati: è un po' come una gerarchia di directories.

Lanciamo il comando:

$ /usr/local/Minerva/bin/msqladmin create prova

in modo da creare un database di prova, in cui costruiremo le nostre tavole. Il sistema dovrebbe rispondervi:

Database "prova" created.

Ora possiamo tornare ad operare come utente vulgaris: non abbiamo più bisogno dei privilegi di root.
Da questo punto in poi useremo spesso i comandi contenuti nella directory /usr/local/Minerva/bin, quindi per evitare di dover scrivere tutte le volte il path completo, ammettiamo che abbiate aggiunto questa directory all'elenco contenuto nella variabile PATH.

Per assicurarci che tutto sia stato eseguito a dovere diamo il comando:

$ relshow

Questo è lo Schema Viewer di cui si parla nella documentazione. Lanciato senza parametri elenca i databases presenti nella vostra installazione, dando come paramentro un database elenca le tavole al suo interno, dando due parametri (database e tavola) elenca i campi presenti nella tavola.

Il sistema dovrebbe rispondere:

  +-----------------+
  |    Databases    |
  +-----------------+
  | prova           |
  +-----------------+

Ora creiamo una prima tavola. Dato che abbiamo installato un database SQL, dobbiamo rivolgerci a lui nella sua lingua, utilizzando un interprete di comandi SQL.
L'interprete fornito, o Terminal Monitor, come viene chiamato nella documentazione, si chiama... indovinato: msql.

Lanciamo il Terminal Monitor, specificandogli il database su cui andremo ad operare:

$ msql prova

Il Monitor risponderà:

Welcome to the miniSQL monitor.  Type \h for help.


mSQL > 
Ora possiamo scrivere al prompt le nostre frasi SQL, terminandole con un \g per mandarle in esecuzione.
Come prima cosa creiamo una tavola. Proviamo a reimplementare la rubrica telefonica di cui ci eravamo serviti in uno dei primi articoli di questa serie. Mentre l'altra volta usammo un file ASCII, questa volta inseriremo i nostri dati in un vero database relazionale.
La tavola che creeremo conterrà il nome e cognome della persona, il suo indirizzo e il numero di telefono. Lo statement SQL che serve per creare questa tavola è il seguente:

mSQL > create table indirizzi
    -> ( id        int      primary key,
    ->   nome      char(40) not null,
    ->   indirizzo char(80),
    ->   tel       char(20) not null
    -> )\g

Il Monitor risponderà così:

Query OK.

A questo punto abbiamo creato la struttura della tavola. Questa conterrà un campo id che sarà la chiave univoca e avrà un indice univoco associato, il nome, che ovviamente dovrà essere non nullo, l'indirizzo, che possiamo ammettere anche di non conoscere, e quindi non imporremo l'attributo not null e il numero di telefono, tel, che sarà ovviamente non nullo (altrimenti perché creare una rubrica telefonica?-).

Verifichiamo che tutto sia andato per il verso giusto, usando il comando relshow per esplorare il nostro database:

$ relshow prova

Il sistema dovrebbe rispondere:

Database = prova

  +---------------------+
  |       Table         |
  +---------------------+
  | indirizzi           |
  +---------------------+

Ora che abbiamo una tavola possiamo permetterci di essere curiosi e chiedere delucidazioni sulla struttura di indirizzi:

$ relshow prova indirizzi

Il sistema dovrebbe rispondere:


Database = prova

Table    = indirizzi

 +-----------------+----------+--------+----------+-----+
 |     Field       |   Type   | Length | Not Null | Key |
 +-----------------+----------+--------+----------+-----+
 | id              | int      | 4      | Y        | Y   |
 | nome            | char     | 40     | Y        | N   |
 | indirizzo       | char     | 80     | N        | N   |
 | tel             | char     | 20     | Y        | N   |
 +-----------------+----------+--------+----------+-----+

Possiamo vedere che il campo id, che avevamo dichiarato primary key è stato automaticamente dichiarato anche Not Null.

Proviamo ora ad inserire qualche record, sempre usando il Terminal Monitor, questa volta in modo non interattivo.
Aprite il vostro editor preferito e scrivete:

insert into indirizzi (id, nome, indirizzo, tel)
values (1, 'Andrea Bianchi', 'V. dei ciclamini, 42', '01 123456')
\g
insert into indirizzi (id, nome, indirizzo, tel)
values (2, 'Franco Neri', 'V. dei salici, 69', '02 234567')
\g
insert into indirizzi (id, nome, indirizzo, tel)
values (3, 'Mario Rossi', 'V. delle rose, 13', '03 345678')
\g
insert into indirizzi (id, nome, indirizzo, tel)
values (4, 'Filippo Verdi', 'V.le dei pini, 17', '04 456789')
\g

Diamo a questo file il nome indirizzi.sql e al prompt scriviamo:

$ msql prova <indirizzi.sql

Il Monitor risponderà così:


Welcome to the miniSQL monitor.  Type \h for help.


mSQL >     ->     -> 
Query OK.




mSQL >     ->     -> 
Query OK.




mSQL >     ->     -> 
Query OK.




mSQL >     ->     -> 
Query OK.




mSQL > 
Bye!

$

Non molto eloquente, ma probabilmente avrà fatto il suo lavoro. Seguendo la nostra tradizione, siamo malfidi ed andiamo a controllare l'operato del Monitor, cercando di verificare che le righe siano effettivamente state immesse nella tavola. Lanciamo il monitor un'altra volta e diamo il comando:

select * from indirizzi\g

Il Monitor risponderà così:


Query OK.

4 rows matched.

 +----------+------------------------------------------+------------------------
----------------------------------------------------------+---------------------
-+
 | id       | nome                                     | indirizzo
| tel                  |
 +----------+------------------------------------------+------------------------
----------------------------------------------------------+---------------------
-+
 | 1        | Andrea Bianchi                           | V. dei
ciclamini, 42               
|
 | 2        | Franco Neri                              | V. dei
salici, 69
| 02 234567            |
 | 3        | Mario Rossi                              | V. delle
rose, 13
| 03 345678            |
 | 4        | Filippo Verdi                            | V.le dei
pini, 17
| 04 456789            |
 +----------+------------------------------------------+------------------------
----------------------------------------------------------+---------------------
-+

Questo è ciò che appare sul mio schermo largo 80 caratteri: il risultato non è molto comprensibile, ma possiamo almeno verificare che siano state rilevate quattro righe e, a parte la formattazione pietosa a causa della lunghezza del record, i dati sono proprio quelli immessi.
Se vogliamo una formattazione migliore dobbiamo munirci di una finestra con righe di circa 150 caratteri, o scriverci un programma che si interfacci al database e ci formatti i dati in modo da soddisfare il nostro delicato senso estetico.

Come abbiamo detto ci si può interfacciare all'mSQL attraverso vari linguaggi e questo è esattamente ciò che faremo nel prossimo articolo.
Nel frattempo, se non siete ferrati in SQL, avrete tempo di acquistare un libro sull'argomento (ce ne sono di ottimi in commercio) e di leggervelo.

A rileggerci alla prossima puntata.

Per dubbi, congratulazioni, correzioni, insulti & altro scrivete a Nando Santagata.