MySQL v.5.0: nuove funzionalita'

La versione 5 di MySQL introduce importanti nuove funzionalita' nell'RDBMS Free piu' diffuso al mondo.
In questo documento sono riportati i principali nuovi elementi introdotti dalla versione 5.0 oltre a qualche altra notizia utile:

Per una descrizione generale del DBMS conviene leggere Introduzione a MySQL e Qualcosa in piu' su MySQL

Naturalmente la migliore e piu' completa sorgente di informazioni e' il sito ufficiale MySQL ed in particolare i manuali on-line, ma forse troverete qualcosa di utile anche qui! Questo documento e' stato preparato utilizzando la versione 5.0.15 di MySQL su un Linux Red Hat EL 3 ed e' stato successivamente aggiornato per la versione 5.0.45 di MySQL, ma e', mutatis mutandis, valido anche per altre versioni.

View

Che dire? Se leggete questo documento qualcosa sui DB lo conoscete gia' e non c'e' bisogno di parlare delle viste! Finalmente presenti su MySQL, aderiscono strettamente allo standard ANSI e sono, nei casi in cui e' possibile, updateable.
Naturalmente la sintassi e'

CREATE VIEW vista AS SELECT ...

Catalog

Dalla versione 5.0 e' disponibile il CATALOG ovvero il Data Dictionary, contenente la descrizione di tutti gli oggetti definiti in MySQL, e' visibile sotto forma di tabelle.
Cosa si puo' vedere nel catalog? E' piu' facile navigarlo con l'SQL che spiegarlo:

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| test               |
+--------------------+
3 rows in set (0.00 sec)

mysql> select table_catalog, table_schema, table_name, engine
    -> from information_schema.tables;
+---------------+--------------------+---------------------------------------+--------+
| table_catalog | table_schema       | table_name                            | engine |
+---------------+--------------------+---------------------------------------+--------+
| NULL          | information_schema | CHARACTER_SETS                        | MEMORY |
| NULL          | information_schema | COLLATIONS                            | MEMORY |
| NULL          | information_schema | COLLATION_CHARACTER_SET_APPLICABILITY | MEMORY |
| NULL          | information_schema | COLUMNS                               | MyISAM |
| NULL          | information_schema | COLUMN_PRIVILEGES                     | MEMORY |
| NULL          | information_schema | KEY_COLUMN_USAGE                      | MEMORY |
| NULL          | information_schema | ROUTINES                              | MyISAM |
| NULL          | information_schema | SCHEMATA                              | MEMORY |
| NULL          | information_schema | SCHEMA_PRIVILEGES                     | MEMORY |
| NULL          | information_schema | STATISTICS                            | MEMORY |
| NULL          | information_schema | TABLES                                | MEMORY |
| NULL          | information_schema | TABLE_CONSTRAINTS                     | MEMORY |
| NULL          | information_schema | TABLE_PRIVILEGES                      | MEMORY |
| NULL          | information_schema | TRIGGERS                              | MyISAM |
| NULL          | information_schema | VIEWS                                 | MyISAM |
| NULL          | information_schema | USER_PRIVILEGES                       | MEMORY |
...
Chiaro no? MySQL v.5.0 crea un nuovo database chiamato information_schema che contiene sotto forma di tabelle tutte le definizioni di oggetti presenti. Le tabelle sono utilizzabili con normali SELECT SQL utilizzando join, condizioni e quanto serve per estrarre le informazioni necessarie dal catalogo.

Stored Procedures

Le stored procedure consentono di memorizzare programmi nella base dati. Le stored procedure sono particolamente efficenti nel trattare grandi quantita' di dati e permettono di isolare logiche di trattamento delle informazioni. Ma forse e' piu' semplice partire con un esempio:

use test;
DROP PROCEDURE IF EXISTS test1;
DELIMITER '/';

CREATE PROCEDURE test1
  (IN tot INTEGER) 
 LANGUAGE SQL
 DETERMINISTIC 
 MODIFIES SQL DATA
 SQL SECURITY DEFINER
 COMMENT 'Test Procedure' 
BEGIN 
DECLARE i         INTEGER DEFAULT 0;

WHILE i  < tot
  DO
   INSERT INTO DUMMY (X) VALUES ('X');
   SET i = i + 1;
END WHILE;

 COMMIT ;
END/
DELIMITER ';'/
Per richiamare la procedura il comando e' CALL test1(3). Chiaramente la procedura richiamata inserira' tre record nella tabella DUMMY... ma gli elementi interessanti sono altri:

Un'importante considerazione e' relativa all'utilizzo del binary-log (necessario per la replication e per la modalita' di recovery point-in-time). Vengono infatti imposti una sintassi specifica per indicare le modifiche svolte sui dati e limiti alle tipologie di Stored Procedures utilizzabili, per rendere replicabili le azioni svolte dalle stored procedures sui server su cui viene replicato il DB. Infatti sul binary log viene riportata la stored procedure richiamata ed il risultato di questa deve essere replicabile per poter riapplicare il log. Per tale ragione e' importante dichiarare se il comportamento della stored procedure e' deterministico (ovvero si ripete sempre uguale a fronte degli stessi dati) e se vengono modificati dati.
Poiche' il thread di replicazione gira in stato privilegiato sugli slave e' richiesto il privilegio SUPER oppure l'impostazione del parametro --log-bin-trust-routine-creators.
Chiaro? Beh se lo avete capito allora spiegatelo anche a me!

Analogamente alle Stored Procedures possono essere definite le Function che hanno la caratteristica di restituire un valore e possono essere richiamate dagli statement SQL. La sintassi e' analoga a quella delle Stored Procedures ma e' presente qualche limitazione in piu'... ad esempio non e' possibile richiamare statement che esplicitamente o implicitamente effettuino un COMMIT o un ROLLBACK.

Trigger

I Trigger permettono di associare ad un evento (eg. INSERT) un'azione da svolgere. Le azioni possono essere di validazione dei dati oppure di modifica. La sintassi e':

CREATE TRIGGER nome [BEFORE|AFTER] [INSERT|UPDATE|DELETE]
    ON tabella FOR EACH ROW statement
Un trigger BEFORE viene eseguito prima dello statement che lo ha attivato e, se fallisce, lo statement non viene eseguito. Un trigger AFTER viene eseguito dopo lo statement che lo ha attivato per ogni riga che e' stata coinvolta.
In caso di fallimento dello statement, dei trigger o della transazione che li contiene tutte le modifiche effettuate subiscono un rollback, naturalmente se l'Engine supporta le transazioni.

Lo statement ha la stessa sintassi che abbiamo visto per le stored procedure (eg. BEGIN ... END) e quindi... rileggete!
In realta' su un trigger non tutti i comandi SQL sono disponibili ma vi sono alcune limitazioni. Non sono infatti concessi comandi che alterano il flusso della transazione (eg. COMMIT).
All'interno di un trigger e' possibile riferirsi ai valori presenti nella tabella prima o dopo l'operazione SQL indicandoli come OLD.column_name e NEW.column_name rispettivamente. I valori OLD sono in sola lettura mentre i valori NEW possono essere modificati.

Ottimizzatore e performances

La nuova versione e' un poco piu' pesante? Forse si... ma e' normale quando sono presenti nuove funzionalita'. Sono inoltre presenti diverse nuove caratteristiche che possono essere sfruttate per ottenere un notevole miglioramento delle prestazioni.

Sono molte le modifiche sull'ottimizzatore: migliore gestione del multijoin, l'utilizzo dell'index merge, ...

La Query Cache mantiene in memoria gli ultimi statement SQL eseguiti ed il relativo risultato. Nel caso in cui statement identici vengano richiesti piu' volte questi ottengono immediatamente la risposta senza necessita' di rieseguire la parsificazione o la ricerca dei dati. Si tratta di un caso frequente, quindi la Query Cache risulta generalmente vantaggiosa, ma e' possibile disabilitarla agendo sui parametri di configurazione o con lo statement SET GLOBAL query_cache_size=0;

Le Stored Procedures hanno ottime prestazioni e rendono notevolmente piu' veloci attivita' in cui lo scambio dati con il client e' pesante.
Le Stored Procedures vengono parsificate al momento del lancio. Questo rende piu' semplice la gestione, non vi sono oggetti invalidi, ... pero' penalizza il primo lancio che richiede la parsificazione dello statement. Tuttavia i lanci successivi non richiedono piu' tale operazione e sono molto veloci.

Standard

MySQL non e' mai stato molto vicino allo standard SQL ANSI ma la versione 5.0 colma la maggioranza delle lacune. Il committment e' di aderire allo standard se non vi sono svantaggi prestazionali!
La versione 5.0 aderisce in modo molto stretto allo standard ANSI comprese le recenti nuove funzionalita' previste nell'ultimo rilascio SQL:2003. Da questo punto di vista MySQL risulta piu' conforme allo standard rispetto ad altri RDBMS commerciali.
E' anche possibile scegliere tra diversi dialetti SQL impostando SET sql_mode= ai diversi mode disponibili (molto comodi sono gli alias ANSI, ORACLE, TRADITIONAL, ...). In questo modo il controllo all'aderanza allo standard risulta semplificato.
L'accresciuta precisione nel trattamento dei numeri nella versione 5.0 consente a MySQL di essere conforme allo standard anche su questo punto.

La modalita' piu' tipica per accedere a MySQL da applicazioni Java e' quella di utilizzare un driver JDBC. MySQL Connector/J e' un driver JDBC-3.0 Type 4 ovvero un driver 100% pure Java conforme allo standard 3.0 JDBC. La versione 3.0 delle API JDBC e' la piu' recente (sono in fase di definizione le specifiche per la versione 4.0) ed include i datatype SQL:1999 e lo scroll dei result set. JDBC-3.0 e' un componente della Java 2 Platform, Standard Edition, versione 1.4 (J2SE).

Altra modalita' per accedere a MySQL e' mediante un driver ODBC. Il piu' aggiornato e' il driver MyODBC 3.51 conforme alle specifiche ODBC 3.5x level 1 (core API + level 2 features). Probabilmente il piu' diffuso su client e' MyODBC 2.50 conforme alle specifiche ODBC 2.50 level 0 (con level 1 and 2 features).

Aderenza agli standard o meno le differenze tra RDBMS restano! E questo appare evidente quando e' necessario produrre applicazioni in grado di operare su piu' RDBMS o effettuare una migrazione. Da questo punto di vista il MySQL Migration Toolkit e' un'ottimo aiuto.

Il tool si occupa in modo completo della migrazione dei dati, dalla creazione delle DDL al trasferimento fisico. L'utente/amministratore ha la possibilita' di intervenire in tutti i passi del wizard. Lo strumento e' facile e veloce con DB di limitate dimensioni ma puo' essere utilmente sfruttato anche per migrazioni pesanti grazie alla possibilita' di generare l'SQL ed al Bulk Load. Gli RDBMS supportati sono molteplici e, come principale requisito, vi e' solo un driver JDBC.

La prima sequenza di passi del wizard consente la definizione dei metadati ovvero di indicare quali sono gli schemi ed le definizioni da migrare. La seconda serie di passi riguarda la migrazione dei dati vera e propria.

Una nota: le Stored Procedures (eg. Oracle) vengono riconosciute ma non vengono, ancora, tradotte automaticamente.

Varie ed eventuali

I paragrafi precedenti hanno presentato le principali funzionalita' e caratteristiche della versione 5.0, tuttavia le novita' introdotte sono molte di piu'. Tra i molti elementi non riportati in precedenza:

E' probabile qualche piccolo cambiamento e bug fixing nella versione 5.0 che e' comunque gia' un'ottima versione anche perche' ha avuto un test molto lungo ed attento.

La versione 5.1 e' attualmente in fase beta... I principali interventi sono rivolti al supporto di basi dati di notevoli dimensioni. Il Partitioning e lo Scheduling sono elementi fondamentali per un Dataware House.
Per la versione 5.2 e' prevista l'implementazione delle Foreign Key (attualmente presente solo per l'Engine InnoDB), ...
Quindi a presto!


Testo: MySQL v.5.0: nuove funzionalita'
Data: 32 Ottobre 2005
Versione: 1.1.1 - 1 Novembre 2007
Autore: mail@meo.bogliolo.name