Migrazione di Estatica al framework open source Symfony (parte II)

Pubblicato il 30/06/2009 - Last updated: 01/08/2009


Modificare il database

La base dati è il primo punto su cui ho deciso di intervenire
Andando a rivedere la struttura del database ho notato numerose cose che si potevano migliorare, alcune derivate da errori di gioventù relativi alla progettazione del database, altre derivate dal fatto che nel frattempo sono cambiate alcune necessità del sito e questo è un buon momento per intervenire e apportare miglioramenti.
In ultimo l'utilizzo dell'ORM Doctrine ha suggerito altre modifiche per seguire le convenzioni adottate da questa libreria.

Di seguito ho riassunto tutti i punti su cui intervenire:

  • Utilizzare per i nomi delle tabelle e dei campi, solo caratteri minuscoli. Se il nome è composto da più parole, utilizzare il simbolo di underscore _
    Questo suggerimento favorisce la portabilità su altri database. Infatti il comportamento con le maiuscolo varia da DB a DB e quindi è meglio evitare il loro utilizzo.
    Inoltre essendo che vengono generate delle classi con il nome delle tabelle, ed essendo che le classi hanno per convenzione la prima lettera maiuscola, utilizzare i nomi delle tabelle in minuscolo permette di evitare possibili confusioni.
  • Utilizzare "id" come nome della chiave primaria di ciascuna tabella
    Facciamo un esempio. Se abbiamo una tabella "anagrafica", ognuno di noi probabilmente tenderà a mettere un nome diverso per la chiave primaria secondo una propria convenzione personale, ad esempio "idAnagrafica", "id_anagrafica", "id_ana".
    Utilizzando la convenzione "id" suggerita da Doctrine, si potranno utilizzare alcuni "automatismi" nel riconoscimento delle relazioni tra tabelle.
    Riprendendo l'esempio della tabella "anagrafica" chiameremo "id" la chiave primaria e "anagrafica_id" le eventuali foreign key presenti in altre tabelle.
  • Utilizzare utf-8 per i dati.
    Spesso, sopratutto in progetti di qualche anno fa i dati non erano in utf-8, ma in altre codifiche come latin1 o altro. Latin1 era il settaggio di default per mySql e altri famosi database. Al giorno d'oggi è meglio lavorare sempre in utf-8 per evitare brutte sorprese.
    Se dovete progettare un nuovo database fate attenzione a crearlo in utf-8, se avete un database già esistente in altro formato è estremamente consigliato convertirlo in utf-8.
  • Uniformare i nomi dei campi
    Un difetto dato da successive modifiche e aggiunte ad un database è quello di avere perso la coerenza nei nomi, risultando disordinato e poco preciso.
    Questo potrebbe essere il momento giusto per una revisione ai nomi dei campi ed eventualmente a quello delle tabelle, per avere nomi descrittivi e chiari.
    Una ragione in più per mettere ordine è che l'ORM genererà classi e metodi con tali nomi.
  • Internazionalizzazione del sito
    Il sito aveva già un sistema di internazionalizzazione di base per mostrare alcuni campi del database in lingue diverse.
    Doctrine però utilizza un suo specifico metodo completamente diverso e quindi è necessario fare le opportune modifiche.
Il fatto di dover modificare un database con dati presenti, comporta vari problemi e due possibili soluzioni:
  • Fare le modifiche nel database della nuova versione del sito e poi creare uno script che copi i dati dalla vecchia versione a quella nuova.
    Pro: non è necessario modificare il codice del vecchio sito
    Contro: è necessario creare un programma per copiare i dati dal database vecchio a quello nuovo
    Uno script, ad esempio scritto in PHP per travasare una considerevole quantità di dati, può richiedere parecchio tempo, da quando si lancia a quando l'operazione viene terminata.
    Faccio un esempio per dare un'idea.
    In un altro progetto, su un database il cui dump sql è di 40 MB, lo script in PHP che rimappa i dati da un vecchio db ad uno nuovo, richiede circa 4 ore. In questo caso essendo che viene utilizzato sia il programma nella vecchia versione, che in quella nuova, il porting viene lanciato tutte le notti in modo da avere il db allineato giornalmente. Per utilizzare questa soluzione è necessario avere accesso al file php.ini del server per modificare il tempo massimo di esecuzione del codice PHP.
  • Fare le modifiche nel database della vecchia versione, modificare il vecchio codice in modo da seguire le modifiche effettuate sul db.
    Pro: il database del vecchio e nuovo sito può essere in comune (quindi lo stesso); nel server è possibile fare girare contemporaneamente (su due cartelle diverse) il vecchio sito e quello nuovo
    Contro: è necessario modificare il codice del vecchio sito

Come potete vedere ognuna delle due strade ha i pro e i contro. Con la prima non bisogna modificare il vecchio codice, di contro il programma di porting potrebbe richiedere molto tempo sia nella realizzazione, che nella esecuzione. Inoltre nel secondo caso, quello dell'utilizzo di una identica struttura del database possiamo, oltre che sviluppare in una macchina di test, mettere online il sito in una cartella segreta e vedere in diretta come si comporta con il database effettivo.

La scelta dipende da molti fattori legati al tipo di progetto e alle modalità di sviluppo. In questo caso la scelta è caduta sulla seconda modalità.

Il primo step per il riordino del database è stato il passare alla codifica utf-8.
Se tutti i dati seguono la stessa codifica, tale modifica è molto agevole utilizzando phpMyAdmin.
Nel nostro caso purtroppo le codifiche dei dati erano "mischiate" e nella stessa tabella erano già presenti caratteri illeggibili derivati da inserimenti con codifiche errate, spostamenti di server con differenti configurazioni, versioni di MySql, ecc.
E' stato quindi necessario fare delle sostituzioni a basso livello, facendo un backup in formato sql e andando a fare dei cerca e sostituisci "manuali" tramite sed.
Ecco un esempio dei comandi lanciati:
cat estatica.sql | sed 's/ù/ù/g' > estatica1.sql
cat estatica1.sql | sed 's/ì/ì/g' > estatica2.sql
cat estatica2.sql | sed 's/è/è/g' > estatica3.sql

Per le modifiche ai nomi delle tabelle, ai nomi dei campi ed eventuali modifiche ai tipi, abbiamo utilizzato le Doctrine Migrations. In questo modo è possibile fare delle modifiche al database tramite codice, tenere traccia delle versioni ed eventualmente tornare indietro a modifiche precedenti, in modo preciso e ordinato.