Questa citazione non riguarda l'uso dell'XML come formato di archiviazione in generale (per il quale va bene, a seconda dei requisiti), ma per lo spazio di database .
Quando le persone parlano di database, di solito indicano sistemi di archiviazione che memorizzano enormi quantità di dati, spesso nell'intervallo di gigabyte o terabyte. Un database è potenzialmente molto più grande della quantità di RAM disponibile sul server che lo memorizza. Dal momento che nessuno ha mai bisogno di tutti i dati in un database in una volta, i database dovrebbero essere ottimizzati per il recupero rapido di sottoinsiemi selettivi dei loro dati: questo è l'istruzione SELECT
e i database relazionali e le soluzioni NoSQL ottimizzano la loro memoria interna formato per il recupero veloce di tali sottoinsiemi.
XML, tuttavia, non si adatta veramente a questi requisiti. A causa della sua struttura di tag nidificata, è impossibile determinare dove nel file viene memorizzato un determinato valore (in termini di un offset di byte in un file) senza percorrere l'intero albero del documento, almeno fino alla corrispondenza. Un database relazionale ha indici e la ricerca di un valore in un indice, anche con un'implementazione di ricerca binaria primitiva, è una sola ricerca O (log n), e quindi ottenere i valori effettivi non è altro che una ricerca di file (ad es. fseek(data_file_handle, row_index * row_size)
), che è O (1). In un file XML, il modo più efficace è di eseguire un parser SAX sul documento, facendo moltissime letture e ricerche prima di arrivare ai dati reali; difficilmente puoi ottenerlo meglio di O (n), a meno che non usi gli indici, ma poi, dovresti ricostruire l'intero indice per ogni inserimento (vedi sotto).
L'inserimento è ancora peggio. I database relazionali non garantiscono l'ordine delle righe, il che significa che possono semplicemente aggiungere nuove righe o sovrascrivere qualsiasi riga contrassegnata come "eliminata". Questo è estremamente veloce: il DB può solo tenere un gruppo di posizioni scrivibili in giro; ottenere una voce dal pool è O (1) a meno che il pool non sia vuoto; Nel peggiore dei casi, il pool è vuoto e deve essere creata una nuova pagina, ma anche questa è O (1). Al contrario, un database basato su XML dovrebbe spostare tutto dopo il punto di inserimento per creare spazio; questo è O (n). Quando gli indici entrano in gioco, le cose diventano ancora più interessanti: gli indici tipici dei database relazionali possono essere aggiornati con una complessità relativamente bassa, ad esempio O (log n); ma se si desidera indicizzare i file XML, ogni inserimento modifica potenzialmente la posizione su disco di ogni valore nel documento, quindi è necessario ricostruire l'intero indice . Ciò vale anche per gli aggiornamenti, poiché l'aggiornamento, ad esempio, del contenuto di testo di un elemento, può modificarne le dimensioni, il che significa che l'XML consecutivo deve spostarsi. Un database relazionale non deve assolutamente toccare l'indice se si aggiorna una colonna non indicizzata; un database XML dovrebbe ricostruire l'intero indice per ogni aggiornamento che modifica la dimensione del nodo XML aggiornato.
Questi sono i lati negativi più importanti, ma ce ne sono altri. L'XML è molto prolisso, e va bene per le comunicazioni da server a server, perché aggiunge sicurezza (il server ricevente può eseguire tutti i tipi di controlli di integrità sull'XML e se qualcosa è andato storto nel trasferimento, è improbabile che il documento convalidi ). Per l'archiviazione di massa, tuttavia, si tratta di uccisioni: non è raro avere il sovraccarico del 100% o più per i dati XML (non è raro vedere rapporti di sovraccarico nell'intervallo del 1000% per cose come i messaggi SOAP), mentre l'archiviazione DB relazionale tipica gli schemi hanno solo un overhead costante per i metadati della tabella, più un piccolo bit per riga; la maggior parte del sovraccarico nei database relazionali proviene da larghezze di colonna fissa. Se hai un terabyte di dati, un overhead del 500% è semplicemente inaccettabile, per molte ragioni.