MySQL progettazione di un database per un mobilificio versione del documento: 1.1 Luca Scrimin
Requisiti Consideriamo un mobilificio, che vuole vendere i suoi prodotti on-line. Innanzitutto, nel catalogare gli oggetti, vengono stabilite delle categorie, poste in una gerarchia 1. Ognuno di questi oggetti è caratterizzato da uno stile, da un materiale (finitura) e da una fascia di prezzo. Inoltre, gli oggetti sono caratterizzati da una misura, cosi composta: lunghezza larghezza profondità Ma è anche possibile che esistano più versioni dello stesso oggetto disponibile alla vendita con differenti misure. Le differenti versioni del medesimo oggetto, sono catalogate e ciascuna è accompagnata con 0 o più foto, di cui è nel nostro interesse memorizzare: la posizione nel disco rigido una didascalia Progettazione concettuale e logica Prendiamo in considerazione il primo gruppo di requisiti, questo è lo schema concettuale: Senza perdere la BCNF, nella progettazione logica, possiamo accorpare in Oggetto, le chiavi esterne relative ai concetti di stile, finitura e fascia di prezzo, in accordo con i tipi di associazioni 1:N. Per realizzare la gerarchia, si utilizza una tabella aggiuntiva chiamata categoria, che riproduce un albero gerarchico, in cui ogni nodo ha un identificativo, un nome, ed un riferimento al nodo padre, sotto forma di chiave esterna. 1 Questa gerarchia potrà essere ampliata con il passare del tempo 2
Prendiamo in considerazione il secondo gruppo di requisiti, questo è lo schema concettuale: Senza perdere la BCNF, nella progettazione logica, possiamo accorpare in Misura, la chiave esterna relativa al concetto di oggetto, in accordo con il tipo di associazione 1:N mentre utilizzeremo una relazione separata per l'associazione A2 che non può essere accorpata in quanto di tipo N:N. Come creare velocemente tutte quante le tabelle I comandi per la creazione delle tabelle sono contenuti in appendice A. Si possono eseguire tutti in una volta, creando prima il database con il comando: mysqladmin -u root -p create mobilificio E poi creando le tabelle, eseguendo il file mob.sql con il comando: mysql -u root -p mobilificio < mob.sql Possiamo notare, che abbiamo usato le innovative tabelle InnoDB, che fra le tante novità introdotte, supportano i vincoli di chiave esterna, consentendo la creazione di una base di dati più robusta. Come popolare la base di dati Questa è una operazione che difficilmente può essere eseguita senza un programma 2, in quanto i dati relativi ad un oggetto devono essere scorporati e inseriti in più tabelle. Proviamo ugualmente 2 Dopo la progettazione logica e la normalizzazione c'è una frammentazione dei dati. E' un bene, per non avere anomalie di inserimento, cancellazione e modifica. 3
senza per ora l'ausilio di un programma a simulare a mano questo meccanismo. Per farlo utilizziamo i comandi inseriti in appendice B. Si possono eseguire tutti in una volta eseguendo il file ins.sql, con il comando: mysql -u root -p mobilificio < ins.sql Al termine verranno memorizzati due oggetti. Possiamo inoltre verificare, la funzionalità dei vincoli di chiave esterna cercando di cancellare ad esempio uno stile usato da un oggetto. 4
Appendice A: mob.sql DROP TABLE IF EXISTS stile; CREATE TABLE stile ( tipostile int NOT NULL auto_increment, nomestile varchar(20) NOT NULL, descrizionestile varchar(200), PRIMARY KEY (tipostile), UNIQUE (nomestile) DROP TABLE IF EXISTS finitura; CREATE TABLE finitura ( tipofinitura int NOT NULL auto_increment, nomefinitura varchar(20) NOT NULL, descrizionefinitura varchar(200), PRIMARY KEY (tipofinitura), UNIQUE (nomefinitura) DROP TABLE IF EXISTS fasciaprezzo; CREATE TABLE fasciaprezzo ( codp int NOT NULL auto_increment, prezzomin int NOT NULL, prezzomax int NOT NULL, PRIMARY KEY (codp) DROP TABLE IF EXISTS categoria; CREATE TABLE categoria ( catid int NOT NULL auto_increment, catname varchar(60) NOT NULL, parentcatid int, ts timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, PRIMARY KEY (catid), CONSTRAINT cat01 FOREIGN KEY (parentcatid) REFERENCES categoria(catid) ) ENGINE= InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci; DROP TABLE IF EXISTS oggetto; CREATE TABLE oggetto ( cod char(7) NOT NULL, stile int NOT NULL, finitura int NOT NULL, fasciaprezzo int NOT NULL, categoria int NOT NULL, ts timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, PRIMARY KEY (cod), CONSTRAINT ogg01 FOREIGN KEY (stile) REFERENCES stile(tipostile), CONSTRAINT ogg02 FOREIGN KEY (finitura) REFERENCES finitura(tipofinitura), CONSTRAINT ogg03 FOREIGN KEY (fasciaprezzo) REFERENCES fasciaprezzo(codp), CONSTRAINT ogg04 FOREIGN KEY (categoria) REFERENCES categoria(catid) ) ENGINE= InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci; DROP TABLE IF EXISTS misura; CREATE TABLE misura ( codm int NOT NULL auto_increment, L int NOT NULL, H int NOT NULL, 5
P int NOT NULL, cod char(7) NOT NULL, PRIMARY KEY (codm), CONSTRAINT mis01 FOREIGN KEY (cod) REFERENCES oggetto(cod) DROP TABLE IF EXISTS foto; CREATE TABLE foto ( codf int NOT NULL auto_increment, posizione varchar(100), didascalia varchar(200), PRIMARY KEY (codf) DROP TABLE IF EXISTS a2; CREATE TABLE a2 ( codm int NOT NULL, codf int NOT NULL, ts timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, PRIMARY KEY (codm, codf), CONSTRAINT a201 FOREIGN KEY (codm) REFERENCES misura(codm), CONSTRAINT a202 FOREIGN KEY (codf) REFERENCES foto(codf) 6
Appendice B: ins.sql INSERT INTO stile (tipostile, nomestile) VALUES (1, 'contemporaneo'), (2, 'classico'), (3, 'barocco'), (4, 'mistico'); INSERT INTO finitura (tipofinitura, nomefinitura) VALUES (1, 'pelle'), (2, 'legno'), (3, 'tessuto'), (4, 'metallo'), (5, 'plastica'), (6, 'vetro'); INSERT INTO fasciaprezzo (codp, prezzomin, prezzomax) VALUES (1, 0, 200),(2, 200, 400),(3, 400, 600),(4, 600, 800),(5,800,1000), (6,1000, 1500),(7,1500, 2000),(8,2000,2500),(9,2500,3000),(10, 3000, 10000); INSERT INTO categoria (catid, catname, parentcatid) VALUES (1, 'mobili', NULL), (2, 'tavoli e sedie', 1), (3, 'tavoli', 2), (4, 'sedie', 2), (5, 'sgabelli', 2), (6, 'tavolini', 2), (7, 'consolle', 2), (8, 'cucine', 1), (9, 'mobili per cucina', 8), (10, 'cucine in muratura', 8), (11, 'cucine monoblocco', 8), (12, 'divani e poltrone', 1), (13, 'divani angolari', 12), (14, 'divani a due posti', 12), (15, 'divani a tre posti', 12), (16, 'divani a quattro o più posti', 12), (17, 'divani letto', 12), (18, 'poltrone', 12); INSERT INTO oggetto (cod, stile, finitura, fasciaprezzo, categoria) VALUES ('xxxbb', 4, 2, 2, 3), ('aaaqq', 1, 3, 3, 15); INSERT INTO misura (codm, L, H, P, cod) VALUES (1,1500,800,1200, 'xxxbb'), (2,2000,800,1000, 'xxxbb'), (3,3000,1000,600, 'aaaqq'); INSERT INTO foto (codf, posizione, didascalia) VALUES (1, 'c:\fototavoli\xxxbb1.jpg', 'tavolo mistico - 1 foto, formato 1'), (2, 'c:\fototavoli\xxxbb11.jpg', 'tavolo mistico - 2 foto, formato 1'), (3, 'c:\fototavoli\xxxbb2.jpg', 'tavolo mistico - formato 2'), (4, 'c:\fotodivani3posti\aaaqq.jpg', 'divano contemporaneo'); INSERT INTO a2 (codm, codf) VALUES (1, 1), (1, 2), (2, 3), (3, 4); 7