Un modello di Database per una collezione Musicale

Sin dai tempi del VB6 ho portato avanti un progetto che mi ha consentito di testare le nuove tecnologie che si sono susseguite in questi anni. E’ un progetto nato per mettere ordine nella mia eterogenea collezione di materiale musicale. Infatti, nonostante abbia testato decine e decine di software, non sono mai stato soddisfatto dalla loro maniera di organizzare i dati. Vi anticipo che in questo campo sono un freak; quindi le mie richieste ai più parranno eccessive.
Il modello di database che adotto attualmente è in parte derivato da quello introdotto sul sito web MusicBrainz che offre ai suoi utenti un web service REST-based per estrazione di dati. Un altro sito che offre gratuitamente dati in formato XML è DiscoGS. Questi due siti sono stati fondamentali nella scrittura di programmi accessori che ho utilizzato per riempire il mio database. In uno dei prossimi post vedremo come si possono eseguire query su questi web service.

La prima tabella (e di conseguenza il primo oggetto) di cui voglio parlarvi è quella degli artisti, Artists ( consentitemi d’ora in poi, di utilizzare la lingua inglese). Un Artist è un musicista, una persona che produce materiale sonoro o che partecipa alla produzione di materiale sonoro. Mentre in MusicBrainz un Artist può essere anche un gruppo di persone, nel mio approccio un Artist è sempre una singola persona. Nel database MusicBrainz, gli U2 sono un Artist; nel mio caso nella tabella Artists ho 4 record: Bono Vox, Larry Mullen, Adam Clayton, the Edge (i 4 membri degli U2). Perché questa scelta? Un gruppo musicale non è un’entità monolitica e immutabile. Consideriamo l’esempio dei Pearl Jam: nel corso della loro vita musicale alla batteria si sono succeduti ben 5 Artist. Da appassionato musicale, questa è un’informazione che voglio conservare nel mio database. Ogni canzone, inoltre, ha degli autori dei testi e dei compositori musicali. Molti gruppi tengono a sottolineare questi ruoli nei libretti associati al loro materiale. Così, la canzone “Alive” dei Pearl Jam ha come “Composer” Vedder e Gossard (cantante e chitarrista del gruppo). Ultimo motivo per conservare tutte le individualità all’interno di un gruppo, è dato dalle molteplici apparizioni di singoli elementi di un gruppo ad altri progetti musicali. Ad esempio, al concerto per la raccolta di fondi per il Tibet hanno partecipato i Pearl Jam, ma non al completo: erano presenti solo Eddie Vedder e Mike McCready.
I campi della tabella Artists sono quelli che riteniamo più idonei alla descrizione dell’Artist. Al momento, sono i seguenti
![clip_image001[4] clip_image001[4]](http://dotnetcampania.org/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/salvatore.metablogapi/1018.clip_5F00_image0014_5F00_thumb_5F00_1200BDD4.png)
" border="0" alt="clip_image001
" src="http://dotnetcampania.org/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/salvatore.metablogapi/5277.clip_5F00_image0016_5F00_thumb_5F00_3CC8FC19.png" width="212" height="188" />
La seconda tabella, chiamata Groups, definisce gli aggregati di Artist che hanno prodotto in maniera ufficiale un prodotto musicale. L’esempio più immediato è il nome che appare sulla copertina di un disco. Da notare che nel mio approccio un Group può anche essere composto da un solo Artist (nell’immagine Bob Dylan).
Un Group è caratterizzato da un nome, da una data di formazione e una di eventuale scioglimento, da un campo di descrizione e da una foto. Nel caso di Group costituito da un singolo Artist, la data di scioglimento può corrispondere a quella di abbandono delle scene o della sua morte.
Sarete sorpresi dal fatto che in Groups non compaia alcuna relazione con la tabella Artists. Il GroupID è uno short-cut rapido nei casi in cui non siamo interessati alla storia del Group. Quindi la tabella dei Dischi (che vedremo a breve) presenterà una chiave esterna che si collegherà a Groups.
La terza tabella Group_Histories contiene la storia di un gruppo musicale ed è collegata a Groups.

La prima formazione dei Pearl Jam, nata nel Giugno 1990 e sciolta ad Aprile 1991 era composta da Vedder, McCready, Gossard, Ament e Krusen. Avremo dunque una chiave esterna per collegare la tabella all’entry Pearl Jam in Groups. Come colleghiamo la tabella Artists? Una soluzione potrebbe essere quella di definire in Group_Histories un congruo numero di campi del tipo Artist_1_ID,….., Artist_N_ID. Ma quando ci dobbiamo fermare? Se ne inserissimo 10. quanti sarebbero i Group che necessitano di tanti campi? Davvero pochi. La scelta di sovraprogettare una tabella per soddisfare casi rari non mi è mai piaciuta. Una seconda alternativa (che ho usato più spesso in passato) sarebbe quella di creare una terza tabella il cui singolo record sia definito dalla coppia di chiavi GroupPastID e ArtistID. Nel caso dei Pearl Jam, per il singolo record di esempio avrei bisogno di 5 record (uno per ogni Artist) in questa tabella di collegamento. La soluzione è impeccabile ma necessita di una tabella aggiuntiva costituita da sole chiavi esterne.
La mia soluzione nasce dall’osservazione che una singola stringa (il campo GroupArtists) contenente gli ID degli Artist separati da una virgola fornisce tutta l’informazione necessaria: 11,12,13,14,17.
La seguente immagine mostra come in sole 6 record sia compresa tutta la storia dei Pearl Jam.

La semplificazione del database è evidente ma è chiaro che ci sono dei costi da pagare:
1) Dovremo essere noi a gestire l’integrità referenziale dei dati assicurandoci che la stringa GroupArtists contenga ID esistenti nella tabella Artist.
2) Dovremo analizzare tante stringhe!
I vantaggi di questo approccio diventano ancora più evidenti quando consideriamo la tabella delle canzoni: Songs. Come associamo una canzone ad un Group? Da un lato voglio avere immediatamente l’informazione che una canzone è di un dato gruppo; dall’altro voglio preservare gli Artist che l’hanno composta. Ecco la tabella Songs caratterizzata dal fatto di non avere chiavi esterne.

Tutta l’informazione sugli autori è contenuta nella stringa song_Authors_ID. Vediamo come esempio la canzone “Alive” dei Pearl Jam.

Abbiamo due separatori: il punto e virgola e la virgola. A sinistra del punto e virgola appare l’ID del Group (Pearl Jam) ossia la chiave della tabella Groups. A destra abbiamo gli ID degli Artist autori della canzone, separati da una virgola. La flessibilità è assoluta: consideriamo il caso della canzone “The Saints Are Coming” composta dagli U2 e dai Green Day, due gruppi musicali, e scritta da Bono, cantante degli U2. La Stringa Song_Authors_ID sarà semplicemente: “1,51;2”: quindi a sinistra del Punto e Virgola appariranno i due Group e a destra l’Artist.
Procediamo con la costruzione della tabella che conterrà gli elementi della nostra collezione che definiamo come Release di un Group.
E’ necessaria una tabella che descriva su quale mezzo fisico viene distribuita la Release. Utilizzando il gergo di Music Brainz definiamo la tabella Format_Types. In figura sono mostrati i record attualmente contenuti nel mio database. Questa tabella è frutto del progresso tecnologico e quindi evolve nel tempo.

Occorre poi una tabella che descriva il tipo di Release. La notazione usata è quella di MusicBrainz.

La Tabella Release è “classica” nella sua concezione e non necessita di particolari descrizioni. L’unica osservazione è che bisogna evitare l’atroce e diffusissima formula AAVV, ossia Autori Vari. Ad ogni Release dovrà corrispondere un Group quanto più possibile significativo. Prendiamo in considerazione il caso peggiore: una compilation di canzoni degli anni ’80! Definiremo un Group dal nome “Gruppo Artisti degli Anni 80” e poi andremo ad inserire in GroupHistories un record con la lista di tutti i Group compresi al suo interno.

La tabella Release contiene l’immagine della copertina associata al materiale. Devo ammettere che non ho ancora deciso quale sia la soluzione migliore: conservare l’immagine nel database o semplicemente il percorso del file sul disco. Immagazzi nare tutto nel database è ovviamente la scelta più coerente, tuttavia quando si passa alla costruzione delle interfacce utente Il data binding di un controllo a un campo immagine non è un’operazione banale (soprattutto in progetti WPF o Slverlight) .

L’ultima tabella da analizzare è quella delle Tracks contenute in una Release. Esistono due ordini di problemi che complicano la sua definizione:
- Chi sta cantando
- Cosa si sta cantando
Prendiamo un concerto dei Pearl Jam in cui ad un certo punto venga invitato sul palco Ben Harper. Questo nuovo aggregato di Artist esegue una canzone che è in realtà la somma (Medley è il termine preciso) di due altre canzoni: una dei Pearl Jam e la seconda di Neil Young. Ovviamente si potrebbe inserire tutto in un bel campo “Note” ma con gli anni ho imparato che questo tipo di campo serve spesso solo a coprire gli errori di progettazione o le tardive indicazioni di un cliente.
Il campo stringa SongID contiene la lista delle Songs contenute nella Track separate da una virgola. Il campo TrackPerformerRelationID è una stringa contenente due separatori (; e ,) per darci la possibilità di includere tutti gli Artist e Group coinvolti nell’esecuzione della Track.
Dal punto di vista dell’interfaccia utente, una pagina web associata ad una Track sarà qualcosa del genere

con 3 cloud (nella zona a sfondo grigio): la prima relativa al Group, la seconda agli Artist che han partecipato alla sua esecuzione, la terza alle Song contenute nella Track.
Concludendo, le richieste di un appassionato di musica (me stesso) mi hanno spinto a progettare un database sperimentale che godesse delle seguenti qualità; semplicità, flessibilità e completezza di informazione. Il compito di estrarre tale informazione non è necessariamente più complesso ma è sicuramente diverso dall’eseguire query su viste piene di join.