Effettuare un SEARCH & REPLACE all’interno di un campo con valori serializzati in MySQL non è una cosa semplice come potrebbe sembrare a prima vista. L’utilizzo della semplice funzione REPLACE di MySQL, infatti, potrebbe portare (quasi sicuramente) a risultati inaspettati e creare una certa "instabilità" nella nostra base dati.
Una stringa serializzata (che costituisce una rappresentazione particolare di un array), infatti, è costruita secondo una sintassi logica particolare che potrebbe facilmente essere corrotta da interventi di sostituzione testuale puri e semplici!
La sintassi di una stringa serializzata
Per comprendere la complessità di un array serializzata vediamo un esempio. Supponiamo di dover serializzare questa matrice:
// definisco array
$esempio = array(
0 => 'mela',
1 => 21,
2 => true,
3 => null
);
// stampo a video la versione serializzata
echo serialize($esempio);
L’output del mio codice PHP sarà il seguente:
a:4:{i:0;s:4:"mela";i:1;i:21;i:2;b:1;i:3;N;}
Analizziamolo:
- a:4:{ … } – "a:4" ci dice che stiamo serializzando un array di 4 elementi
- tra le parentesi graffe troviamo il contenuto dell’array:
- i:0; – indica l’indice numerico del primo item
- s:4:"mela"; – indica una stringa di 4 caratteri con valore "mela"
- i:1; – indica l’indice numerico del secondo item
- i:21; – indica un numero intero con valore 21
- i:2; – indica l’indice numerico del terzo item
- b:1; – indica un valore booleano "true"
- i:3; – indica l’indice numerico del quarto item
- b:1; – indica un valore null
La sintassi di una stringa realizzata è la seguente:
- Array – a:size:{ … }
- Stringa – s:size:value;
- Intero – i:value;
- Booleano – b:value; (1 = "true", 0 = "false")
- Null – N;
Modificare dati serializzati: la giusta via
La cosa migliore per effettuare la modifica di un campo serializzato consiste nell’utilizzare un linguaggio di programmazione (ad esempio PHP) con cui estrarre la stringa, deserializzarla (trasformandola in array), effettuare la modifica voluta, serializzare nuovante ed effettuare un UPDATE del campo.
Modificare stringhe all’interno di dati serializzati utilizzando solo SQL
Quella appena descritta è la strada corretta, tuttavia esiste anche una scorciatoia che prevede l’utilizzo esclusivo di istruzioni SQL. Il limite di questa tecnica è che funziona correttamente solo se si vuole effettuare la sostituzione integrale di una stringa all’interno di un campo serializzato, non sostituzioni parziali!
Per fare un esempio supponiamo di voler agire sull’ipotetico campo "colori" della tabella "prodotti" al cui interno è contenuta l’array serializzata dei colori disponibile per ciascun dato prodotto. Supponiamo di voler sostituire il colore "rosso" con "arancione":
SET @search := 'rosso';
SET @replace := 'arancione';
UPDATE prodotti SET colori = REPLACE(colori, CONCAT('s:', LENGTH(@search), ':"', @search, '"'), CONCAT('s:', LENGTH(@replace), ':"', @replace, '"'));
La sequenza di istruzioni SQL viste sopra effettuerà correttamente la modifica senza compromettere la validità dei dati, tuttavia è sempre opportuno effettuare un backup prima di effettuare query "rischiose" come quelle che prevedono UPDATE di campi complessi come quelli contenenti dati serializzati.