E' una casistica abbastanza comune in molte applicazioni web.
Supponiamo di avere una certa entità, per esempio un "prodotto", che avrà la sua tabella mysql con tutti gli attributi predefiniti: id, nome, descrizione, etc. etc.
Si vuole poter dare la possibilità all'utente - amministratore dell'applicazione di personalizzare i prodotti aggiungendo campi a sua scelta. Quindi magari se il prodotto che lui tratta sono libri vorrà aggiungere il campo "ISBN" e il campo "numero_pagine", il primo stringa e il secondo numerico, se vende dildo vorrà aggiungere la misura (valutata in GM secondo lo standard internazionale) etc. etc. con tutti gli altri esempi possibili che la fantasia può suggerire.
Ora, esistono che io sappia (ma sono qua per questo, per saperne di più), due scuole di pensiero per gestire questa situazione:
1) effettuare "a runtime" l'ALTER TABLE sulla tabella prodotti (o su una tabella di appoggio in relazione 1:1 con prodotti) per aggiungere / modificare / rimuovere i campi personalizzati.
2) usare una tabella campi personalizzati fatta circa in questo modo:
id_prodotto | nome_campo | valore_campo
Dove valore_campo è un campo stringa molto grande (un LONGTEXT per esempio).
(fanno così Wordpress e phplist per esempio)
Il primo approccio, quello dell'ALTER TABLE è potenzialmente molto pesante e rischioso. Pesante perché per farlo il mysql crea ogni volta una copia dell'intera tabella, ci salva le modifiche, poi rinomina la tabella originale, rinomina la copia modificata con il nome originale e infine cancella la tabella originale. Per tabelle molto grandi questa operazione può essere quindi lentissima, e oltrettutto richiede il doppio dello spazio su disco per contenere la tabella e la sua copia provvisoria.
E' inoltre rischioso perché l'operazione non è ATOMICA, può quindi in caso di problemi essere interrotta a metà (per esempio nel punto in cui la tabella originale è stata rinominata ma la copia non ancora) lasciando quindi il database inutilizzabile. Per riparare questa situazione è necessario inoltre l'accesso al filesystem dove sono memorizzati fisicamente i file delle tabelle, cosa che non si ha quasi mai in hosting.
Il secondo approccio non ha gli svantaggi del precedente ma ne ha di suoi:
Intanto la struttura non sarebbe più normalizzata correttamente,
ci sarebbe quindi la necessità di effettuare sempre una query aggiuntiva per leggere i campi aggiuntivi del prodotto e mostrarli all'applicazione php che li usa come se fossero campi "standard", il formato del campo valore sarebbe sempre "stringa" per qualsiasi tipo di informazione, con conseguente spreco di spazio, e inoltre, se io volessi per esempio indicizzare il campo personalizzato ISBN per effettuare velocemente ricerche ma non il campo numero_pagine non potrei farlo, sarei obbligato a indicizzare totalmente il campo "valore_campo" o a non indicizzarlo per niente.
Insomma, entrambi i metodi secondo me hanno più controindicazioni che vantaggi, e quindi chiedo a voi qualche idea alternativa per dare una soluzione al problema iniziale, tenendo presente che ho a disposizione MySQL5.
Grazie (e scusate la lunghezza del post)