Mysql
 sql >> Database >  >> RDS >> Mysql

Mysql:archivia l'array di dati in una singola colonna

Prima di tutto, non vuoi davvero farlo. Una colonna in un RDBMS deve essere atomica, in quanto contiene una e una sola informazione. Il tentativo di memorizzare più di un dato in una colonna è una violazione della prima forma normale.

Se devi assolutamente farlo, devi convertire i dati in un modulo che può essere archiviato come un singolo elemento di dati, in genere una stringa. Potresti usare il meccanismo serialize() di PHP, l'analisi XML (se i dati sono un albero di documenti), json_encode(), ecc.

Ma come si interrogano tali dati in modo efficace? La risposta è che non puoi.

Inoltre, se qualcun altro rileva il tuo progetto in un secondo momento, lo infastidirai davvero, perché è orribile lavorare con i dati serializzati in un database. Lo so perché ho ereditato tali progetti.

Ho già detto che non vuoi davvero farlo? Devi ripensare al tuo progetto in modo che possa essere archiviato più facilmente in termini di righe atomiche. Utilizzare un'altra tabella per questi dati, ad esempio, e utilizzare chiavi esterne per correlarli al record principale. Si chiamano database relazionali per un motivo.

AGGIORNAMENTO :Mi è stato chiesto dei requisiti di archiviazione dei dati, ad esempio se una singola riga sarebbe stata più economica in termini di archiviazione. La risposta è, in casi tipici no, non lo è, e nei casi in cui la risposta è sì il prezzo che paghi non vale la pena pagare.

Se utilizzi una tabella dipendente da 2 colonne (1 colonna per la chiave esterna del record a cui appartiene il campione, una per un singolo campione), ogni colonna richiederà nel peggiore dei casi 16 byte (8 byte per una colonna di chiave longint, 8 byte per un numero in virgola mobile a doppia precisione). Per 100 record sono 1600 byte (ignorando l'overhead db).

Per una stringa serializzata, memorizzi nel migliore dei casi 1 byte per carattere nella stringa. Non puoi sapere quanto sarà lunga la stringa, ma se assumiamo 100 campioni con tutti i dati memorizzati per qualche coincidenza forzata che cadono tutti tra 10000,00 e 99999,99 con solo 2 cifre dopo il punto decimale, allora tu' stai guardando 8 byte per campione. In questo caso, tutto ciò che hai salvato è l'overhead delle chiavi esterne, quindi la quantità di spazio di archiviazione richiesta è di 800 byte.

Ciò ovviamente si basa su molte ipotesi, come la codifica dei caratteri sempre di 1 byte per carattere, le stringhe che compongono i campioni non sono mai più lunghe di 8 caratteri, ecc.

Ma ovviamente c'è anche il sovraccarico di qualsiasi meccanismo tu usi per serializzare i dati. Il metodo più semplice in assoluto, CSV, significa aggiungere una virgola tra ogni campione. Ciò aggiunge n-1 byte alla stringa memorizzata. Quindi l'esempio sopra ora sarebbe 899 byte, e questo è con lo schema di codifica più semplice. Le serializzazioni JSON, XML e persino PHP aggiungono tutti più caratteri overhead di questo e presto avrai stringhe molto più lunghe di 1600 byte. E tutto questo presupponendo la codifica dei caratteri a 1 byte.

Se è necessario indicizzare i campioni, i requisiti di dati aumenteranno in modo ancora più sproporzionato rispetto alle stringhe, poiché un indice di stringa è molto più costoso in termini di archiviazione rispetto a un indice di colonna a virgola mobile.

E, naturalmente, se i tuoi campioni iniziano ad aggiungere più cifre, la memorizzazione dei dati aumenta ulteriormente. 39281.3392810 non sarà memorizzabile in 8 byte come stringa, anche nel migliore dei casi.

E se i dati sono serializzati, il database non può manipolare. Non puoi ordinare i campioni, fare qualsiasi tipo di operazione matematica su di essi, il database non sa nemmeno che sono numeri!

Ad essere onesti, tuttavia, lo spazio di archiviazione è ridicolmente economico di questi tempi, puoi acquistare più unità TB per piccole somme. Lo storage è davvero così critico? A meno che tu non abbia centinaia di milioni di record, dubito che lo sia.

Potresti voler dare un'occhiata a un libro chiamato SQL Antipatterns