You are on page 1of 39

Catalogazione di Astronavi in una

ambientazione Sci-
Valerio Martella
July 11, 2011

Contents
1
2

3
4

Introduzione.

Analisi dei requisiti

2.1

Analisi informale dei requisiti . . . . . . . . . . . . . . . . . . . .

2.2

Operazioni sui dati . . . . . . . . . . . . . . . . . . . . . . . . . .

2.3

Buisness Rules

Diagramma E-R Logico

Progettazione Fisica

4.1

Eliminazione delle generalizzazioni

4.2

Eliminaazione delle relazioni 1-n

4.3

Diagramma E-R Fisico . . . . . . . . . . . . . . . . . . . . . . . .

4.4

Scheda della Base di Dati

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

Implementazione
5.1

. . . . . . . . . . . . . . . . . . . . . . . . . . . .

Script di creazione

. . . . . . . . . . . . . . . . . . . . . . . . . .

Sicurezza

13

Triggers

14

7.1

Buisness rule 2

. . . . . . . . . . . . . . . . . . . . . . . . . . . .

14

7.2

Buisness rule 1

. . . . . . . . . . . . . . . . . . . . . . . . . . . .

14

7.3

Buisness rule 3

. . . . . . . . . . . . . . . . . . . . . . . . . . . .

7.4

Consistenza logica Tra Flotta e Incarico

. . . . . . . . . . . . . .

Query

16

8.1

Calcolo dei pianeti dove non presente una fabbrica

8.2

Calcolo dei marinai in attivit sulla nave N

8.3

Calcolo delle astronavi capaci di volo a curvatura maggiore di 5

8.4

15
15

. . . . . . .

. . . . . . . . . . . .

16
17
17

Calcolo della classica di navi da battaglia dotate di velivoli ordinata per il numero di velivoli avversari abbattuti

. . . . . . . . .

17

8.5

Calcolo del numero di navi e di otte di ogni fazione

. . . . . . .

17

8.6

Calcolo dell' uciale di grado maggiore a bordo della Nave N . .

17

8.7

Calcolo di tutte le otte con navi incapaci di volo a Curvatura di


una Fazione F . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

8.8

pianeta P
8.9

18

Calcolo di tutte le classi con almeno una nave costruita su un


. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

18

Calcolo di tutte le navi con armamenti non sottoposti a manuten. . . . . . . . . . . . . . . . . . . . . . . . .

18

8.10 Calcololo del numero di marinai di ogni razza per ogni nave . . .

zione da una data D

18

8.11 Calcolo del Marinaio che ha svolto la mansione M col grado pi


alto un una nave di classe C . . . . . . . . . . . . . . . . . . . . .
8.12 Calcolo dei Velivoli pilotati da Piloti di Grado G

19

. . . . . . . . .

19

8.13 Calcolo del numero di marinai attivi su ogni nave . . . . . . . . .

19

8.14 Calcolo dei Marinai che Sono di una specie originaria di un pianeta nel sistema "S" o che hanno avuto un incarico in una otta
stanziata su un pianeta nel sistema "S"

. . . . . . . . . . . . . .

19

8.15 Calcolo degli incarichi eettuati o su navi varate nel 2000 o da


marinai nati nel 2000 . . . . . . . . . . . . . . . . . . . . . . . . .

20

8.16 Calcolo delle navi con parti prodotte in pianeti con alte temperature 20

Query in Algebra Relazionale

20

9.1

Calcolo dei pianeti ove non presente una fabbrica . . . . . . . .

20

9.2

Calcolo dei velivoli pilotati da piloti di grado G . . . . . . . . . .

20

10 Ottimizzazione Query

21

1.69sec)
(0.06sec 0.00sec)
(0.76sec 0.48sec)
(2.45sec 0.05sec)
(1.21sec 0.13sec)
(1.21sec 0.13sec)

10.1 Ottimizzazione di 8.10 (2.56sec

. . . . . . . . . . . .

21

10.2 Ottimizzazione di 8.11

. . . . . . . . . . . .

24

. . . . . . . . . . . .

25

. . . . . . . . . . . .

27

. . . . . . . . . . . .

32

. . . . . . . . . . . .

33

10.3 Ottimizzazione di 8.13


10.4 Ottimizzazione di 8.14
10.5 Ottimizzazione di 8.15
10.6 Ottimizzazione di 8.16

11 Stored Procedure

36

12 Views

37

13 Transazioni

38

Introduzione.

In molte delle ambientazioni della fantascienza moderna uno degli elementi pi


importanti la presenza di  navi capaci di volo atmosferico e interplanetario,
se non interstellare o intergalattico a seconda della potenza dei motori (e del
livello di plausibilit dell'ambientazione presa in esame).

Che si parli degli

enormi StarDestroyers Imperiali di Star Wars alle piccole scorte classe Deant di Star Trek DS9. Gli sceneggiatori di questo genere di narrativa pongono

spesso l'accento sulle speciche e le caratteristiche di queste navi, dando spessore


e verosimigianza a racconti e telelm di fantascienza. Spesso dietro alle navi c'
una complessa organizzazione in otte e squadroni, provenienti da diverse organizzazioni come stati, imperi e unioni commerciali. Questo progetto si propone
di creare uno strumento utile a gestire tutto questo insieme di informazioni, che
consiste in:

Speciche tecniche delle navi

personale umano (spesso umano un termine riduttivo in questo ambito)

organizazione politica

Analisi dei requisiti

2.1 Analisi informale dei requisiti


Si vuole realizzare una basi dati in grado di gestire un numero arbitrario di
astronavi da guerra o esploratrici, tenendo conto del loro eventuale raggruppamento in otte che a loro volta sono raggruppate in fazioni. Una nave ha un
codice, un nome di varo e un modello o classe, che rappresenta le speciche tecniche comuni a navi costruite allo stesso modo inoltre una otta d'appartenenza
e un cantiere di varo.

Una classe di nave ha una lunghezza, una larghezza e

un'altezza espressi in decine di metri, una massa espressa in tonnellate, un motore a impulso, pu avere un motore di curvatura, degli scudi che hanno una
certa resistenza e pu essere o meno da guerra.

Un motore ha un modello,

una massa, un volume, un fabbisogno energetico. Un motore a impulso ha una


potenza espressa in newton e un carburante.

Un motore a curvatura non es-

sendo un normale motore ha soltanto un fattore di curvatura spaziale espresso


in un numero puro compreso tra 1 e 10 e il tipo di tecnologia usata. Una nave
da guerra ha diversi armamenti ,un numero di ponti di lancio usati per lanciare
dei  caccia da attacco a corto raggio detti Velivoli.

Ogni armamento ha un

Id identicativo, un numero di munizioni, una data di ultima manutenzione e


un modello. Un velivolo ha un codice,eventualmente pu avere un nick, e un
modello,inoltre ha un numero di velivoli abbattuti, o tacche.

Sia armamenti

che velivoli sono costruiti in fabbriche , ognuna delle quali ha una locazione geograca su un pianeta ed appartiene ad una Casa di Produzione ed sono di un
modello,un modello di velivolo ha una potenza massima, un modello di armamento ha una gittata massima e una cadenza di tiro, inoltre pu essere basato
su un innumerevole numero di tecnologie e principi, quindi opportuno inserire
una breve descrizione. Su ogni nave c' un equipaggio formato da marinai. Ogni
marinaio appartiene a una specie, ha un nome e un cognome (o equivalenti a seconda delle tradizioni della razza ed etnia cui appartiene, indicati quindi come
nome personale e nome di famiglia), una data di nascita, eventualmente una
data di morte e uno storico degli incarichi, in cui ogni incarico ha una data di
inizio incarico, eventualmente una data di ne incarico,un grado e una mansione. Un grado ha un nome e un certo valore nella scala gerarchica delle fazioni

cui appartiene. Una mansione ha un nome e un ponte su cui viene svolta. Una
specie ha un nome, un pianeta d'origine, un tipo di atmosfera respirabile pi
innumerevoli altre caratteristiche univoche e dicilmente prevedibili in fase di
progettazione. Ogni otta appartiene ad un Impero,uno stato o una generica
organizzazione o fazione, ha un porto di stanza ed un ammiraglio. Una fazione
ha un nome e ha il suo quartier generale su un pianeta. Un pianeta ha un nome
ed orbita in un sistema, ha una serie di coordinate spaziali, una temperatura
media, e la sua orbita ha un apogeo ed un perigeo.

2.2 Operazioni sui dati


si possono prevedere sul Database le seguenti richieste:
1. Calcolo dei pianeti dove non presente una fabbrica
2. Calcolo dei marinai in attivit sulla nave N
3. Calcolo delle astronavi capaci di volo a curvatura maggiore di 5
4. Calcolo della classica di navi da battaglia dotate di velivoli ordinata per
il numero di velivoli avversari abbattuti
5. Calcolo del numero di navi e di otte di ogni fazione
6. Calcolo dell uciale di grado maggiore a bordo della Nave N
7. Calcolo di tutte le otte con navi incapaci di volo a Curvatura di una
Fazione F
8. Calcolo di tutte le classi con almeno una nave costruita su un pianeta P
9. Calcolo di tutte le navi con armamenti non sottoposti a manutenzione da
una data D
10. Calcololo del numero di marinai di ogni razza per ogni nave
11. Calcolo del Marinaio che ha svolto la mansione M col grado pi alto un
una nave di classe C
12. Calcolo dei Velivoli pilotati da Piloti di Grado G
13. Calcolo del numero di marinai attivi su ogni nave
14. Calcolo dei Marinai che Sono di una specie originaria di un pianeta nel
sistema "S" o che hanno avuto un incarico in una otta stanziata su un
pianeta nel sistema "S"
15. Calcololo del numero di marinai di ogni razza per ogni nave

2.3 Buisness Rules


1. La data di nascita di un marinaio deve essere precedente alla sua data di
morte se presente
2. La data di inizio di un Incarico deve essere precedente alla sua data di ne
se precedente
3. Tutte le navi con almeno 5 ponti sono da considerarsi navi da guerra

Diagramma E-R Logico

Progettazione Fisica

4.1 Eliminazione delle generalizzazioni


Sono presenti due generalizzazioni:

Motore = Motore Impulso,Motore Curvatura

Nave = Nave da guerra,Nave esploratrice

nel primo caso si scelto di incorpare il padre nelle glie essendo profonda la
distinzione tra le due entit,nel secondo caso si scelto di incorpare le glie nel
padre,essendo la distinzione tra le due entit ebile, aggiungendo l' attributo
booleano IsWarship a Nave in modo da poter tener traccia della dierenza.

4.2 Eliminaazione delle relazioni 1-n


Le relazioni 1-n presenti sono:

Produzione Arm.

Produzione Vel.

Pilota

Nascita

Xenologia

Origine

Speciche

Tipologia Arm.

Tipologia Vel.

Fa_Fl

Fl_Na

Cl_Mc

Cl_Mi

Locazione

Inc_Mar

In_Gr

Compito

Stanza

QG

in tutti i casi la chiave della tabella che partecipa con cardinalit n posta come
chiave esterna (o foregin key) della tabella con cardinalit n.

4.3 Diagramma E-R Fisico

4.4 Scheda della Base di Dati


1. ModVelivolo (idModVelivolo, Max_Engine_Output)
2. ModArmamento (idMod_Armamento, FireRate, Descrizione. Gittata)
3. Mansione (idIncarico, Name, Ponte)
4. Pianeta (idPianeta, Nome, Sistema, Pos_x, Pos_y, Pos_z, AvrgTemperatura, Apogeo, Perigeo, isNotDestroyed)
5. MotoreImplz (idMotoreImplz, Output, EnergyReq, Massa, Carburante)
6. MotoreCurv (idMotoreCurv, Curvatura, EnergyReq, Massa, TecnologiaCurvatura)
7. Grado (IdGrado,HscalaComando, NomeGrado)
8. Fazione (idFazione, AllianceName, idPianeta)
9. Facility (idFacility, idPianeta, Residenza, CasaDIProd)
10. Specie (idSpecie, idPianeta, NameRace, AtmosferaReq, Note)

11. Flotta (idFleet, idFazione, idPianeta, Ammiraglio_Name, Ammiraglio_Cognome)


12. Class (Class, MotoreImplz_idMotoreImplz, MotoreCurv_idMotoreCurv,
NameClass, ISWarship, NoPonti,Lunghezza, Larghezza, Altezza, Massa,
PotenzaScudi)
13. Gerarchia ( idFazione, Grado_idGrado)
14. Marinaio (Matricola, idSpecie, idPianeta, Nome, Cognome, DataDiNascita,
DataDiMorte)
15. Velivolo (idVelivolo, ModVelivolo_idModVelivolo, Facility_idFacility, Pilota_Matricola, Nick, Tacche)
16. Nave (Codice, Class, Facility_idFacility, Flotta_IdFleet, Nome_Varo,
Data_varo)
17. Incarico (IdIncarico, Nave_Codice, Grado_IdGrado, Mansione_idIncarico,
Marinaio_Marticola, DataFineIncarico, DataInizioIncarico)
18. Armamento (idArmamento, Facility_idFacility, idModArmamento, Nave_Codice,
MunizioniRimaste, DataUltimaManutenzione)

Implementazione

5.1 Script di creazione


CREATE TABLE M o d V e l i v o l o

i d M o d V e l i v o l o INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,


Max_Engine_Output FLOAT( 6 , 2 ) NULL,

PRIMARY KEY( i d M o d V e l i v o l o )

ENGINE=InnoDB ;

CREATE TABLE ModArmamento (


idMod_Armamento INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
F i r e R a t e INTEGER UNSIGNED NOT NULL,
D e s c r i z i o n e VARCHAR( 8 0 0 ) NULL,
G i t t a t a FLOAT( 1 0 , 2 ) NULL,

PRIMARY KEY( idMod_Armamento )

ENGINE=InnoDB ;

CREATE TABLE M a n s i o n e

i d I n c a r i c o INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,


Name VARCHAR( 2 0 ) NOT NULL,

PRIMARY KEY( i d I n c a r i c o )

P o n t e VARCHAR( 2 0 ) NULL,

ENGINE=InnoDB ;

CREATE TABLE P i a n e t a

I d P i a n e t a INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,


Nome VARCHAR( 3 0 ) NOT NULL,
S i s t e m a VARCHAR( 3 0 ) NOT NULL,
Pos_y FLOAT( 5 , 2 ) NOT NULL,
Pos_x FLOAT( 5 , 2 ) NOT NULL,
Pos_z FLOAT( 5 , 2 ) NOT NULL,
A v r g T e m p e r a t u r a FLOAT( 4 , 1 ) NOT NULL,
Apogeo INTEGER UNSIGNED NOT NULL,
P e r i g e o INTEGER UNSIGNED NOT NULL,
I s N o t D e s t r o y e d BOOL NULL DEFAULT True ,

PRIMARY KEY( I d P i a n e t a )

ENGINE=InnoDB ;

CREATE TABLE M o t o r e I m p l z

i d M o t o r e I m p l z INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,

Output FLOAT( 4 , 1 ) NOT NULL,


EnergyReq FLOAT( 6 , 3 ) NOT NULL,
Massa FLOAT( 6 , 3 ) NOT NULL,
Carburante

VARCHAR( 2 0 ) NULL,

PRIMARY KEY( i d M o t o r e I m p l z )

ENGINE=InnoDB ;

CREATE TABLE MotoreCurv (


i d M o t o r e C u r v INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
C u r v a t u r a FLOAT( 3 , 2 ) NOT NULL,
EnergyReq FLOAT( 5 , 2 ) NOT NULL,
Massa FLOAT( 5 , 2 ) NOT NULL,
T e c n o l o g i a C u r v a t u r a VARCHAR( 3 0 ) NULL,

PRIMARY KEY( i d M o t o r e C u r v )

ENGINE=InnoDB ;

CREATE TABLE Grado (


I d G r a d o INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
HScalaComando INTEGER UNSIGNED NOT NULL,
NomeGrado VARCHAR( 2 0 ) NULL,

PRIMARY KEY( I d G r a d o )

ENGINE=InnoDB ;

CREATE TABLE F a z i o n e

I d F a z i o n e INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,


A l l i a n c e N a m e VARCHAR( 3 0 ) NOT NULL,
I d P i a n e t a INTEGER UNSIGNED NOT NULL,

PRIMARY KEY( I d F a z i o n e ) ,
FOREIGN KEY( I d P i a n e t a )
ON DELETE NO ACTION

REFERENCES P i a n e t a ( I d P i a n e t a )

ON UPDATE CASCADE )

ENGINE=InnoDB ;

CREATE TABLE F a c i l i t y

i d F a c i l i t y INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,


I d P i a n e t a INTEGER UNSIGNED NOT NULL,
R e s i d e n z a VARCHAR( 3 0 ) NULL,
CasaDIProd VARCHAR( 3 0 ) NULL,

PRIMARY KEY( i d F a c i l i t y ) ,
INDEX F a c i l i t y _ F K I n d e x 1 ( I d P i a n e t a ) ,
FOREIGN KEY( I d P i a n e t a )

REFERENCES P i a n e t a ( I d P i a n e t a )

ON DELETE RESTRICT

ON UPDATE CASCADE )

ENGINE=InnoDB ;

CREATE TABLE S p e c i e

i d S p e c i e INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,


I d P i a n e t a INTEGER UNSIGNED NOT NULL,
NameRace VARCHAR( 2 0 ) NOT NULL,
A t m o s f e r a R e q VARCHAR( 2 0 ) NULL,
Note BLOB NULL,
I s N e a r E x t i n c t i o n BOOL NULL DEFAULT False ,

PRIMARY KEY( i d S p e c i e ) ,
INDEX S p e c i e _ F K I n d e x 1 ( I d P i a n e t a ) ,
FOREIGN KEY( I d P i a n e t a )

REFERENCES P i a n e t a ( I d P i a n e t a )

ON DELETE NO ACTION

ON UPDATE CASCADE )

ENGINE=InnoDB ;

CREATE TABLE G e r a r c h i a

Grado_IdGrado INTEGER UNSIGNED NOT NULL,


I d F a z i o n e INTEGER UNSIGNED NOT NULL,

PRIMARY KEY( Grado_IdGrado ,

IdFazione ) ,

INDEX Fazione_has_Grado_FKIndex1 ( I d F a z i o n e ) ,
INDEX Fazione_has_Grado_FKIndex2 ( Grado_IdGrado ) ,
FOREIGN KEY( I d F a z i o n e )
ON DELETE CASCADE

REFERENCES F a z i o n e ( I d F a z i o n e )

ON UPDATE CASCADE,

FOREIGN KEY( Grado_IdGrado )


ON DELETE CASCADE

REFERENCES Grado ( I d G r a d o )

ON UPDATE CASCADE )

ENGINE=InnoDB ;

CREATE TABLE C l a s s

C l a s s INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,


M o t o r e I m p l z _ i d M o t o r e I m p l z INTEGER UNSIGNED NOT NULL,
MotoreCurv_idMotoreCurv INTEGER UNSIGNED NULL,
NameClass VARCHAR( 2 5 ) NULL,
I S W a r s h i p BOOL NOT NULL,
N o P o n t i INTEGER UNSIGNED NULL,
L u n g h e z z a FLOAT( 7 , 3 ) NOT NULL,

10

L a r g h e z z a FLOAT( 7 , 3 ) NOT NULL,


A l t e z z a FLOAT( 7 , 3 ) NOT NULL,
Massa FLOAT( 4 , 3 ) NOT NULL,
D e s c r i z i o n e BLOB NULL,
P o t e n z a S c u d i FLOAT( 4 , 2 ) NOT NULL,

PRIMARY KEY( C l a s s ) ,
INDEX Class_FKIndex2 ( MotoreCurv_idMotoreCurv ) ,
INDEX Class_FKIndex3 ( M o t o r e I m p l z _ i d M o t o r e I m p l z ) ,
FOREIGN KEY( MotoreCurv_idMotoreCurv )
ON DELETE RESTRICT

REFERENCES MotoreCurv ( i d M o t o r e C u r v )

ON UPDATE RESTRICT,

FOREIGN KEY( M o t o r e I m p l z _ i d M o t o r e I m p l z )
ON DELETE RESTRICT

REFERENCES M o t o r e I m p l z ( i d M o t o r e I m p l z )

ON UPDATE RESTRICT )

ENGINE=InnoDB ;

CREATE TABLE F l o t t a

I d F l e e t INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,


I d F a z i o n e INTEGER UNSIGNED NOT NULL,
I d P i a n e t a INTEGER UNSIGNED NOT NULL,
Ammiraglio_Name VARCHAR( 2 0 ) NULL,
Ammiraglio_Cognome VARCHAR( 2 0 ) NULL,

PRIMARY KEY( I d F l e e t ) ,
INDEX F l o t t a _ F K I n d e x 1 ( I d P i a n e t a ) ,
INDEX F l o t t a _ F K I n d e x 2 ( I d F a z i o n e ) ,
FOREIGN KEY( I d P i a n e t a )

REFERENCES P i a n e t a ( I d P i a n e t a )

ON DELETE RESTRICT

ON UPDATE CASCADE,

FOREIGN KEY( I d F a z i o n e )

REFERENCES F a z i o n e ( I d F a z i o n e )

ON DELETE CASCADE

ON UPDATE CASCADE )

ENGINE=InnoDB ;

CREATE TABLE M a r i n a i o

M a t r i c o l a INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,


I d P i a n e t a INTEGER UNSIGNED NOT NULL,
i d S p e c i e INTEGER UNSIGNED NOT NULL,
Nome

VARCHAR( 2 0 ) NOT NULL,

Cognome VARCHAR( 2 0 ) NOT NULL,


D a t a D i N a s c i t a DATE NULL,
DataDiMorte DATE NULL,

PRIMARY KEY( M a t r i c o l a ) ,
INDEX Marinaio_FKIndex1 ( I d P i a n e t a ) ,
INDEX Marinaio_FKIndex2 ( i d S p e c i e ) ,
FOREIGN KEY( I d P i a n e t a )
ON DELETE NO ACTION
FOREIGN KEY( i d S p e c i e )
ON DELETE RESTRICT

REFERENCES P i a n e t a ( I d P i a n e t a )

ON UPDATE NO ACTION,
REFERENCES S p e c i e ( i d S p e c i e )

ON UPDATE CASCADE )

ENGINE=InnoDB ;

11

CREATE TABLE V e l i v o l o

i d V e l i v o l o INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,


M o d V e l i v o l o _ i d M o d V e l i v o l o INTEGER UNSIGNED NOT NULL,
F a c i l i t y _ i d F a c i l i t y INTEGER UNSIGNED NOT NULL,
P i l o t a _ M a t r i c o l a INTEGER UNSIGNED NOT NULL,
N i c k VARCHAR( 1 5 ) NULL,
T a c c h e INTEGER UNSIGNED NULL,

PRIMARY KEY( i d V e l i v o l o ) ,
INDEX V e l i v o l o _ F K I n d e x 1 ( P i l o t a _ M a t r i c o l a ) ,
INDEX V e l i v o l o _ F K I n d e x 3 ( M o d V e l i v o l o _ i d M o d V e l i v o l o ) ,
INDEX V e l i v o l o _ F K I n d e x 4 ( F a c i l i t y _ i d F a c i l i t y ) ,
FOREIGN KEY( P i l o t a _ M a t r i c o l a )
ON DELETE RESTRICT

REFERENCES M a r i n a i o ( M a t r i c o l a )

ON UPDATE CASCADE,

FOREIGN KEY( M o d V e l i v o l o _ i d M o d V e l i v o l o )
ON DELETE RESTRICT

REFERENCES M o d V e l i v o l o ( i d M o d V e l i v o l o )

ON UPDATE CASCADE,

FOREIGN KEY( F a c i l i t y _ i d F a c i l i t y )
ON DELETE RESTRICT

REFERENCES

Facility ( idFacility )

ON UPDATE CASCADE )

ENGINE=InnoDB ;

CREATE TABLE Nave (


C o d i c e INT UNSIGNED NOT NULL AUTO_INCREMENT,
C l a s s INTEGER UNSIGNED NOT NULL,
F a c i l i t y _ i d F a c i l i t y INTEGER UNSIGNED NOT NULL,
F l o t t a _ I d F l e e t INTEGER UNSIGNED NOT NULL,
NomeVaro VARCHAR( 2 0 ) NOT NULL,
DataVaro DATE NULL,

PRIMARY KEY( C o d i c e ) ,
INDEX Nave_FKIndex1 ( F l o t t a _ I d F l e e t ) ,
INDEX Nave_FKIndex2 ( C l a s s ) ,
INDEX Nave_FKIndex3 ( F a c i l i t y _ i d F a c i l i t y ) ,
FOREIGN KEY( F l o t t a _ I d F l e e t )
ON DELETE RESTRICT

REFERENCES F l o t t a ( I d F l e e t )

ON UPDATE CASCADE,

FOREIGN KEY( C l a s s )

ON DELETE RESTRICT

REFERENCES C l a s s ( C l a s s )

ON UPDATE RESTRICT,
FOREIGN KEY( F a c i l i t y _ i d F a c i l i t y )
ON DELETE RESTRICT

REFERENCES

Facility ( idFacility )

ON UPDATE CASCADE )

ENGINE=InnoDB ;

CREATE TABLE I n c a r i c o

I d I n c a r i c o INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,


Nave_Codice INT UNSIGNED NOT NULL,
Grado_IdGrado INTEGER UNSIGNED NOT NULL,
M a n s i o n e _ i d I n c a r i c o INTEGER UNSIGNED NOT NULL,
M a r i n a i o _ M a t r i c o l a INTEGER UNSIGNED NOT NULL,
D a t a F i n e I n c a r i c o DATE NULL DEFAULT NULL,
D a t a I n i z i o I n c a r i c o DATE NOT NULL,

12

PRIMARY KEY( I d I n c a r i c o ) ,
INDEX I n c a r i c o _ F K I n d e x 1 ( M a r i n a i o _ M a t r i c o l a ) ,
INDEX I n c a r i c o _ F K I n d e x 2 ( M a n s i o n e _ i d I n c a r i c o ) ,
INDEX I n c a r i c o _ F K I n d e x 3 ( Grado_IdGrado ) ,
FOREIGN KEY( M a r i n a i o _ M a t r i c o l a )
ON DELETE CASCADE

REFERENCES M a r i n a i o ( M a t r i c o l a )

ON UPDATE CASCADE,

FOREIGN KEY( M a n s i o n e _ i d I n c a r i c o )
ON DELETE RESTRICT

REFERENCES M a n s i o n e ( i d I n c a r i c o )

ON UPDATE CASCADE,

FOREIGN KEY( Grado_IdGrado )


ON DELETE RESTRICT

REFERENCES Grado ( I d G r a d o )

ON UPDATE CASCADE,

FOREIGN KEY( Nave_Codice )


ON DELETE RESTRICT

REFERENCES Nave ( C o d i c e )

ON UPDATE CASCADE )

ENGINE=InnoDB ;

CREATE TABLE Armamento (


idArmamento INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
F a c i l i t y _ i d F a c i l i t y INTEGER UNSIGNED NULL,
ModArmamento_idMod_Armamento INTEGER UNSIGNED NOT NULL,
Nave_Codice INT UNSIGNED NOT NULL,
M u n i z i o n i R i m a s t e INTEGER UNSIGNED NULL,
D a t a U l t i m a M a n u t e n z i o n e DATE NULL,

PRIMARY KEY( idArmamento ) ,


INDEX Armamento_FKIndex1 ( Nave_Codice ) ,
INDEX Armamento_FKIndex2 ( ModArmamento_idMod_Armamento ) ,
INDEX Armamento_FKIndex3 ( F a c i l i t y _ i d F a c i l i t y ) ,
FOREIGN KEY( Nave_Codice )
ON DELETE CASCADE

REFERENCES Nave ( C o d i c e )

ON UPDATE CASCADE,

FOREIGN KEY( ModArmamento_idMod_Armamento )


ON DELETE RESTRICT

FOREIGN KEY( F a c i l i t y _ i d F a c i l i t y )
ON DELETE RESTRICT

REFERENCES ModArmamento ( idMod_Arma

ON UPDATE CASCADE,
REFERENCES

Facility ( idFacility )

ON UPDATE CASCADE )

ENGINE=InnoDB ;

Sicurezza

Su questo database sono previsti due tipi di utenti con diversi permessi a seconda
delel tabelle su cui hanno i permessi di lettura, inserimento e modica:

Amministratore: colui che gestisce l'intero DataBase e pertanto


l'unico a possedere i permessi di inserimento,modica e cancellazione su
tutte le tabelle. Possiede inoltre anche i permessi di Lettura

Lettore: un visitatore del DataBase. Ha solo permessi di lettura su


tutte le tabelle e le view

Il DB per garantire questi controlli d'accesso fornisce la possibilit di attribuire


permessi a diversi utenti a cui viene associata una password. Ecco il comando
in questione:

13

GRANT <elenco privilegi> ON <nome tabella> TO <nome utente> IDENTIFIED BY < password utente>

Elenco privilegi: I privilegi sono quelli sopra elencati (lettura, modica, inserimento, cancellazione) che al DB vengono indicati come Select,
Update, Insert, Delete.

Nome tabella: Il nome della tabella a cui ci si riferisce, una sola. Non
si pu fare elenco di tutte le tabelle a cui dare determinati permessi

Nome utente: Il nome dell'utente a cui si stanno dando i privilegi in


riferimento ad una data tabella (nel nostro caso Admin, Moderator)

Password utente: La password con cui l'utente si pu identicare al DB


per poter identicarsi come Admin o Moderator a seconda dei casi.

Triggers

7.1 Buisness rule 2


delimiter

Create t r i g g e r
before
for

Incarico_Data_consistency

i n s e r t on I n c a r i c o

each

row

begin
if

new . D a t a I n i z i o I n c a r i c o > new . D a t a F i n e I n c a r i c o

then
SET NEW. D a t a F i n e I n c a r i c o = new . D a t a I n i z i o I n c a r i c o ;
end

if ;

end ;
}
delimiter

7.2 Buisness rule 1


delimiter

Create t r i g g e r
before
for

Marinaio_Date_consistency

i n s e r t on M a r i n a i o

each

row

begin
if

new . D a t a D i N a s c i t a > new . DataDiMorte

then
SET NEW. DataDiMorte = NULL;
end

if ;

end ;
}
delimiter

14

7.3 Buisness rule 3


delimiter

Create t r i g g e r
before
for

Class_noPonti_Consistency

i n s e r t on C l a s s

each

row

begin
if

new . I s W a r S h i p = False and new . N o P o n t i > 5

then
SET new . I s W a r S h i p = True ;
end

if ;

end ;
}
delimiter

7.4 Consistenza logica Tra Flotta e Incarico


In questo Database si f l'assunzione che alle navi di una data fazione possano
essere assegnati solo marinai che hanno un Grado che appartiene alla scala
gerarchica della fazione stessa. Per determinare l'associazione di un Marinaio
ad una Fazione si fa fede a quanto inserito nella tabella Gerarchia, passando
per la tabella Incarico, in quanto eettivamente nel corso del suo storico un
Marinaio pu militare in pi fazioni.

Per assicurare che questa assunzione si

verichi sempre si scelto di correggere la tabella Gerarchia aggiungendo alla


fazione l'eventuale grado del marinaio a cui si sta assegnando un Incarico sulla
Nave nel qual caso non dovesse essere prensente il grado stesso nella gerarchia
della fazione cui la nave fa parte.

15

delimiter

Create t r i g g e r
for

each

Incarico_Grado_conistency

after

i n s e r t on I n c a r i c o

row

begin

select

f l o t t a . idFazione

flotta

j o i n Nave on ( f l o t t a . i d F l e e t = n a v e . f l o t t a _ i d F l e e t )

join

into

@faction

from

on ( I n c a r i c o . N a v e _ c o d i c e = Nave . C o d i c e )

Incarico

where new . i d I n c a r i c o = i d I n c a r i c o ;
s e l e c t count ( )

i n t o @count from G e r a r c h i a

where G e r a r c h i a . Grado_idGrado = new . Grado_idGrado and G e r a r c h i a . i d F a z i o n e = @ f a c


if

then

@count = 0

insert
end

into

Gerarchia

values

( new . g r a d o _ i d G r a d o ,

@faction ) ;

if ;

end ;
}
delimiter

Query

8.1 Calcolo dei pianeti dove non presente una fabbrica


select
Pianeta

d i s t i n c t Nome , S i s t e m a from
left

join

Facility

where F a c i l i t y . i d F a c i l i t y
set

(0.01

on ( Nome = F a c i l i t y . i d P i a n e t a )
i s NULL

sec )

16

order by ( Nome ) ;

8.2 Calcolo dei marinai in attivit sulla nave N


select

M a r i n a i o . Nome , M a r i n a i o . Cognome , M a r i n a i o . M a t r i c o l a

Marinaio

join

Incarico

from

on ( M a r i n a i o . M a t r i c o l a = I n c a r i c o . M a r i n a i o _ M a t r i c o l a )

j o i n Nave on ( I n c a r i c o . Nave_Codice = Nave . C o d i c e )


where I n c a r i c o . D a t a F i n e I n c a r i c o
set

(0.01

i s NULL and Nave . NomeVaro = " E n t e r p r i s e " ;

sec )

8.3 Calcolo delle astronavi capaci di volo a curvatura maggiore di 5


select

C l a s s . C l a s s , NomeVaro , C u r v a t u r a

( ( Nave

join

Class

from

on Nave . C l a s s = C l a s s . C l a s s )

j o i n MotoreCurv on i d M o t o r e C u r v = MotoreCurv_idMotoreCurv )
where C u r v a t u r a > 5
set

(0.01

order by ( C u r v a t u r a ) desc ;

sec )

8.4 Calcolo della classica di navi da battaglia dotate di


velivoli ordinata per il numero di velivoli avversari
abbattuti
s e l e c t NomeVaro , sum ( T a c c h e )
join

(( Velivolo

Incarico

as Tacche , count ( V e l i v o l o . i d V e l i v o l o )

as

Velivoli

from

on P i l o t a _ M a t r i c o l a = M a r i n a i o _ M a t r i c o l a )

j o i n Nave on Nave_Codice = C o d i c e )
where D a t a F i n e I n c a r i c o

i s NULL

group by ( Nave_Codice ) order by ( sum ( T a c c h e ) )


set

(0.82

desc ;

sec )

8.5 Calcolo del numero di navi e di otte di ogni fazione


select

A l l i a n c e N a m e , count ( d i s t i n c t

from F l o t t a
join

Fazione

idFleet )

as NumFlotte

, count ( d i s t i n c t

j o i n Nave on ( F l o t t a _ i d F l e e t = F l o t t a . i d F l e e t )
on ( F l o t t a . i d F a z i o n e = F a z i o n e . i d F a z i o n e )

group by A l l i a n c e N a m e ;
set

(0.02

sec )

8.6 Calcolo dell' uciale di grado maggiore a bordo della


Nave N
s e l e c t max ( HScalaComando ) from
Nave

join

Incarico

on ( C o d i c e = Nave_Codice )

j o i n Grado on ( i d G r a d o = Grado_idGrado )

17

NomeVar

where C o d i c e = 1 2 i n t o @max ;
s e l e c t NomeVaro , M a r i n a i o _ M a t r i c o l a , HScalaComando from
j o i n Grado on (

Incarico

i d G r a d o = Grado_idGrado )

j o i n Nave on ( C o d i c e = Nave_Codice )
where C o d i c e = 1 and HScalaComando = @max ;
set

(0.00

sec )

8.7 Calcolo di tutte le otte con navi incapaci di volo a


Curvatura di una Fazione F
select

distinct

Nave

join

join

Flotta

from

idFleet

on ( Nave . C l a s s = C l a s s . C l a s s )

Class

on ( I d F l e e t = F l o t t a _ I d F l e e t )

where i d F a z i o n e = 15 and MotoreCurv_idMotoreCurv


set

(0.00

is

null ;

sec )

8.8 Calcolo di tutte le classi con almeno una nave costruita


su un pianeta P
select
Nave on

join

distinct

Class . Class

Facility

join

on ( i d F a c i l i t y = F a c i l i t y _ i d F a c i l i t y )

where F a c i l i t y . i d P i a n e t a
set

from C l a s s

( C l a s s . C l a s s = Nave . C l a s s )

(0.03

= 15;

sec )

8.9 Calcolo di tutte le navi con armamenti non sottoposti


a manutenzione da una data D
s e l e c t Nave . NomeVaro , idArmamento from
Armamento

j o i n Nave on ( C o d i c e = Nave_Codice )

where D a t a U l t i m a M a n u t e n z i o n e < " 3 1 0 0 / 0 2 / 1 9 " ;


set

(0.06

sec )

8.10 Calcololo del numero di marinai di ogni razza per


ogni nave
s e l e c t Nave . C o d i c e , NomeVaro , NameRace , count ( NameRace )
from Nave j o i n
join

Marinaio

join

Specie

Incarico

on (

on (

on (

C o d i c e = Nave_Codice )

Matricola = Marinaio_Matricola

Marinaio . i d S p e c i e = Specie . i d S p e c i e )

where D a t a F i n e I n c a r i c o

is

null

group by Nave . C o d i c e , NameRace ;

18

set

(2.71

sec )

8.11 Calcolo del Marinaio che ha svolto la mansione M


col grado pi alto un una nave di classe C
select

M a r i n a i o . Nome , M a r i n a i o . Cognome from

join

Marinaio

join

Mansione

Incarico

on (

on (

Marinaio_Matricola = Matricola

M a n s i o n e _ i d I n c a r i c o = Mansione . i d I n c a r i c o

j o i n Grado on ( i d G r a d o = Grado_idGrado )
j o i n Nave on ( Nave_Codice = Nave . C o d i c e )
where M a n s i o n e . i d I n c a r i c o = 1 4 and Nave . C l a s s = 1 0 and Grado_idGrado
in

s e l e c t max ( Grado_idGrado ) from M a r i n a i o

join

Incarico

on (

Marinaio_Matricola = Matricola

join

Mansione

on (

M a n s i o n e _ i d I n c a r i c o = Mansione . i d I n c a r i c o

)
)

j o i n Grado on ( i d G r a d o = Grado_idGrado )
j o i n Nave on ( Nave_Codice = Nave . C o d i c e )
where M a n s i o n e . i d I n c a r i c o = 1 4 and Nave . C l a s s = 1 0
set

(0.06

);

sec )

8.12 Calcolo dei Velivoli pilotati da Piloti di Grado G


select

idVelivolo

Velivolo

join

from

Incarico

on ( P i l o t a _ M a t r i c o l a = M a r i n a i o _ M a t r i c o l a )

j o i n Grado on ( Grado_idGrado = i d G r a d o

where NomeGrado = " rpnzm " ;


set

(0.68

sec )

8.13 Calcolo del numero di marinai attivi su ogni nave


s e l e c t NomeVaro , C o d i c e , count ( d i s t i n c t
Incarico

Marinaio_Matricola )

where I n c a r i c o . D a t a F i n e I n c a r i c o

i s NULL

group by Nave . C o d i c e order by count ( d i s t i n c t


set

(0.76

as N_Marinai from

j o i n Nave on ( I n c a r i c o . Nave_Codice = Nave . C o d i c e )


Marinaio_Matricola )

desc ;

sec )

8.14 Calcolo dei Marinai che Sono di una specie originaria


di un pianeta nel sistema "S" o che hanno avuto un
incarico in una otta stanziata su un pianeta nel sistema "S"
select

distinct

Incarico

join

Marinaio . Matricola ,

Marinaio

M a r i n a i o . Nome ,

M a r i n a i o . Cognome from

on ( M a t r i c o l a = M a r i n a i o _ M a t r i c o l a )

19

join

specie

join

Pianeta

on ( M a r i n a i o . i d S p e c i e = S p e c i e . i d S p e c i e )
on ( S p e c i e . i d P i a n e t a = P i a n e t a . i d P i a n e t a )

j o i n Nave on ( Nave_Codice = Nave . C o d i c e )


join

Flotta

join

Pianeta

on ( f l o t t a _ i d F l e e t = F l o t t a . i d F l e e t )
a on

f l o t t a . idpianeta = a . idpianeta )

where p i a n e t a . s i s t e m a = "LUWYQNLWCEGOKQWK" or a . s i s t e m a = "LUWYQNLWCEGOKQWK" ;


set

(2.27

sec )

8.15 Calcolo degli incarichi eettuati o su navi varate nel


2000 o da marinai nati nel 2000
Select

Incarico . idIncarico

from I n c a r i c o

join

Marinaio

on ( M a r i n a i o . M a t r i c o l a =

I n c a r i c o . Marinaio_matricola

j o i n Nave on Nave . c o d i c e = I n c a r i c o . Nave_Codice


where year ( Nave . d a t a V a r o ) = 2 0 0 0 or year ( m a r i n a i o . d a t a d i n a s c i t a ) = 2 0 0 0
set

(1.21

sec )

8.16 Calcolo delle navi con parti prodotte in pianeti con


alte temperature
Select

d i s t i n c t Nave . NomeVaro

from Nave j o i n
join

Pianeta

Facility

on ( Nave . F a c i l i t y _ i d F a c i l i t y = i d F a c i l i t y )

on ( F a c i l i t y . i d P i a n e t a = P i a n e t a . i d P i a n e t a )

j o i n Armamento on ( Armamento . N a v e _ c o d i c e = n a v e . C o d i c e )
join

Facility

join

Pianeta

as
as

Facility2
pianeta2

on ( Armamento . F a c i l i t y _ i d F a c i l i t y = f a c i l i t y 2 . i d F a c i l

on ( F a c i l i t y 2 . i d P i a n e t a = P i a n e t a 2 . i d P i a n e t a )

where p i a n e t a . A v r g t e m p e r a t u r a > 5 0 or
set

(0.11

Query in Algebra Relazionale

pianeta2 . avrgtemperatura >

50;

sec )

9.1 Calcolo dei pianeti ove non presente una fabbrica


Q

nome,sistema (f acility.idf acility=N U LL (nome=f acility pianeta

= (P ianeta |X|lef t F acility)))

9.2 Calcolo dei velivoli pilotati da piloti di grado G


Q

idV elivolo (N omegrado=G (V

elivolo |X|P ilota matricola=M arinaio M atricola Incarico)

|X|Grado idGrado=idGrado Grado)

20

10

Ottimizzazione Query

10.1 Ottimizzazione di 8.10 (2.56sec 1.69sec)


s e l e c t Nave . C o d i c e , NomeVaro , NameRace , count ( NameRace )
from Nave j o i n
join

Marinaio

join

Specie

on (

Incarico

on (

on (

C o d i c e = Nave_Codice )

Matricola = Marinaio_Matricola

Marinaio . i d S p e c i e = Specie . i d S p e c i e )

where D a t a F i n e I n c a r i c o

is

null

group by Nave . C o d i c e , NameRace ;


Si nota subito che la query non ha sottoquery,quindi lanciamo il comando
Explain sulla stessa:
mysql> e x p l a i n

s e l e c t Nave . C o d i c e , NomeVaro , NameRace ,

count ( NameRace ) from

> Nave j o i n I n c a r i c o on ( C o d i c e = Nave_Codice )


> j o i n M a r i n a i o on ( M a t r i c o l a = M a r i n a i o _ M a t r i c o l a )
> j o i n S p e c i e on ( M a r i n a i o . i d S p e c i e = S p e c i e . i d S p e c i e )
> where D a t a F i n e I n c a r i c o i s n u l l
> group by Nave . C o d i c e , NameRace \G
1 . row
id :

select_type :

table :

SIMPLE

Specie

t y p e : ALL p o s s i b l e _ k e y s : PRIMARY

key : NULL

k e y _ l e n : NULL

r e f : NULL

rows :

Using temporary ;

Extra :

5063

Using

id :

filesort
row

select_type :

table :
type :

key :

SIMPLE

Marinaio
p o s s i b l e _ k e y s : PRIMARY, Marinaio_FKIndex2

ref

Marinaio_FKIndex2

key_len :
ref :

ship . Specie . idSpecie

rows :

19

Using index

Extra :

id :

2.

3.

row

select_type :

table :
type :

key :

ref

rows :

possible_keys :

I n c a r i c o _ F K I n d e x 1 , Nave_Codice

Incarico_FKIndex1

key_len :
ref :

SIMPLE

Incarico

ship . Marinaio . Matricola


1

21

Using where

Extra :

id :

select_type :

table :
type :

4.

row

SIMPLE

Nave
p o s s i b l e _ k e y s : PRIMARY

eq_ref

key : PRIMARY
key_len :
ref :

s h i p . I n c a r i c o . Nave_Codice

rows :

Extra :

rows i n

set

(0.00

sec )

Essendo Il DBMS scelto MySql, l'unico algoritmo disponibile per eettuare


i Join il Nested Loop Join.

Questo algoritmo molto sensibile alla scelta

dell'ordine di Join delle tabelle scelto, in quanto presta migliri performances


se la Driving Table quella pi restrittiva, ovvero quella con meno tuple.
Dal comando Explain quindi si vede che L'ordine di Join scelto

M arinaio Incarico N ave.

Specie

Nei dati di prova inseriti la tabella specie e la

tabella nave hanno un ordini di grandezza di

(104 )

quindi potrebbe sembrare

che l'ordine in cui vengano Joinate non faccia molta divverenza.

Se si va a

(105 ),
N ave Incarico

vedere l'ordine di grandezza della tabella Incarico per si scopre che di


quindi risulterebbe pi conveniente come ordine di Join

M arinaio Specie.
Si vede subito infatti che eseguendo
mysql> s e l e c t

straight_join

Nave . C o d i c e , NomeVaro , NameRace ,

count ( NameRace ) from

> Nave j o i n I n c a r i c o on ( C o d i c e = Nave_Codice )


> j o i n M a r i n a i o on ( M a t r i c o l a = M a r i n a i o _ M a t r i c o l a )
> j o i n S p e c i e on ( M a r i n a i o . i d S p e c i e = S p e c i e . i d S p e c i e )
> where D a t a F i n e I n c a r i c o i s n u l l
> group by Nave . C o d i c e , NameRace l i m i t 1 0 ;
+++++
|

Codice

NomeVaro

NameRace

count ( NameRace )

+++++
|

4001

4001

| AESXCW

4001

4001

| BYXPWZMCAD

4001

| CQUTXYD

4001

4001

| DWGDOB

4001

| EHNKVPKHVBS

4001

| ELYYEFXQCFXSLKNNW |

4001

DJBYI

+++++
10

rows i n

set

(1.66

sec )

22

il tempo di esecuzione scenda.


un Explain sulla nuova query

select

mysql> e x p l a i n

straight_join

Nave . C o d i c e , NomeVaro , NameRace ,

count ( NameRace ) from

> Nave j o i n I n c a r i c o on ( C o d i c e = Nave_Codice )


> j o i n M a r i n a i o on ( M a t r i c o l a = M a r i n a i o _ M a t r i c o l a )
> j o i n S p e c i e on ( M a r i n a i o . i d S p e c i e = S p e c i e . i d S p e c i e )
> where D a t a F i n e I n c a r i c o i s n u l l
> group by Nave . C o d i c e , NameRace l i m i t 1 \G
1 . row
id :

select_type :

table :

SIMPLE

Nave

t y p e : ALL p o s s i b l e _ k e y s : PRIMARY

key : NULL
k e y _ l e n : NULL
r e f : NULL

rows :

3754

Using temporary ;

Extra :

Using

id :

select_type :

type :

filesort

2.

row

table :

SIMPLE

Incarico

ref

possible_keys :
I n c a r i c o _ F K I n d e x 1 , Nave_Codice

key :

Nave_Codice

key_len :
ref :

s h i p . Nave . C o d i c e

rows :

31

Using where

Extra :

id :

select_type :

type :

eq_ref

3.

row

table :

SIMPLE

Marinaio

p o s s i b l e _ k e y s : PRIMARY, Marinaio_FKIndex2

key : PRIMARY
key_len :
ref :

ship . I n c a r i c o . Marinaio_Matricola

rows :

Extra :

id :

select_type :

table :
type :

4.

key_len :

p o s s i b l e _ k e y s : PRIMARY

ship . Marinaio . i d S p e c i e

rows :
Extra :

Specie
eq_ref

key : PRIMARY
ref :

row

SIMPLE

1
4 rows

in

set

(0.00

sec )

23

mostra che la query non pu essere ulteriormente ottimizzata.

10.2 Ottimizzazione di 8.11 (0.06sec 0.00sec)


select

M a r i n a i o . Nome , M a r i n a i o . Cognome from

join

Marinaio

join

Mansione

Incarico

on (

on (

Marinaio_Matricola = Matricola

M a n s i o n e _ i d I n c a r i c o = Mansione . i d I n c a r i c o

j o i n Grado on ( i d G r a d o = Grado_idGrado )
j o i n Nave on ( Nave_Codice = Nave . C o d i c e )
where M a n s i o n e . i d I n c a r i c o = 1 4 and Nave . C l a s s = 1 0 and Grado_idGrado
in

( s e l e c t max ( Grado_idGrado )

from M a r i n a i o

join

Incarico

on (

Marinaio_Matricola = Matricola

join

Mansione

on (

M a n s i o n e _ i d I n c a r i c o = Mansione . i d I n c a r i c o

)
)

j o i n Grado on ( i d G r a d o = Grado_idGrado )
j o i n Nave on ( Nave_Codice = Nave . C o d i c e )
where M a n s i o n e . i d I n c a r i c o = 1 4 and Nave . C l a s s = 1 0

);

Si pu notare che anche se il tempo di esecuzione modesto la query presenta


una query annidata.

Siccome consigliabile evitare le query annidate si pu

provare a riformulare una query equivalente che eviti l'annidamento.

s e l e c t max ( Grado_idGrado ) from


join

Marinaio

join

Mansione

Incarico

on (

on (

Marinaio_Matricola = Matricola

M a n s i o n e _ i d I n c a r i c o = Mansione . i d I n c a r i c o

j o i n Grado on ( i d G r a d o = Grado_idGrado )
j o i n Nave on ( Nave_Codice = Nave . C o d i c e )
where M a n s i o n e . i d I n c a r i c o = 1 4 and Nave . C l a s s = 1 0 i n t o @max ;
select

M a r i n a i o . Nome , M a r i n a i o . Cognome from

join

Marinaio

join

Mansione

Incarico

on (

on (

Marinaio_Matricola = Matricola

M a n s i o n e _ i d I n c a r i c o = Mansione . i d I n c a r i c o

j o i n Grado on ( i d G r a d o = Grado_idGrado )
j o i n Nave on ( Nave_Codice = Nave . C o d i c e )
where M a n s i o n e . i d I n c a r i c o = 1 4 and Nave . C l a s s = 1 0 and Grado_idGrado = @max ;
Usando la variabile @Max per memorizzare il risultato della subquery si
riesce a spezzare la query in due query con meno complessit temporale
mysql> s e l e c t max ( Grado_idGrado )

>
>
>
>

Marinaio

join

join

Mansione

Incarico

on (

from

Marinaio_Matricola = Matricola

M a n s i o n e _ i d I n c a r i c o = Mansione . i d I n c a r i c o

j o i n Grado on ( i d G r a d o = Grado_idGrado )

j o i n Nave on ( Nave_Codice = Nave . C o d i

where M a n s i o n e . i d I n c a r i c o = 1 4 and Nave . C l a s s = 1 0 i n t o @max ;

Query OK,

row

affected

mysql> mysql> s e l e c t

>
>
>

on (

Marinaio

join

join

Mansione

sec )

M a r i n a i o . Nome , M a r i n a i o . Cognome from

Incarico

on (

(0.00

on (

Marinaio_Matricola = Matricola

M a n s i o n e _ i d I n c a r i c o = Mansione . i d I n c a r i c o

j o i n Grado on ( i d G r a d o = Grado_idGrado )

24

j o i n Nave on ( Nave_Codice = Nave . C o d i

> where M a n s i o n e . i d I n c a r i c o = 1 4 and Nave . C l a s s


+++
|

Nome

Cognome

= 1 0 and Grado_idGrado = @max ;

+++
| YMVCFGDOLANSQKCXDZJ | BAHQKMOAEBGGFVFVGF |
+++
1

in

row

set

(0.00

sec )

come si pu vedere l tempo complessivo sceso ad un tempo arrotondato a


0.00 sec. Nel caso peggiore il tempo di esecuzione 0.005 sec, e quindi la query
sar scesa a un tempo di esecuzione all'incirca del 10% rispetto a prima

10.3 Ottimizzazione di 8.13 (0.76sec 0.48sec)


s e l e c t NomeVaro , C o d i c e , count ( d i s t i n c t

Marinaio_Matricola )

as N_Marinai from

j o i n Nave on ( I n c a r i c o . Nave_Codice = Nave . C o d i c e )

Incarico

where I n c a r i c o . D a t a F i n e I n c a r i c o

i s NULL

group by Nave . C o d i c e order by count ( d i s t i n c t

Marinaio_Matricola )

la Query non presenta delle subquery annidate, quindi si procede ad analizzare l'execution plan con il comando explain

id :

1.

row

select_type :

table :

index

type :

SIMPLE

Nave
p o s s i b l e _ k e y s : PRIMARY, C o d i c e , P i p p o I n d e x

key : PRIMARY
key_len :

r e f : NULL

rows :

4064

Extra :

Using temporary ;

Using

id :

filesort

2.

row

select_type :

table :
type :

key :

ref

possible_keys :

Nave_Codice

Nave_Codice

key_len :
ref :

SIMPLE

Incarico

s h i p . Nave . C o d i c e

rows :
Extra :

20

Using where 2 rows i n

set

(0.00

sec )

Come discusso precedentemente l'ordine di Join molto importante. L'ordine


di grandezza di Nave

(104 ) mentre quello di Incarico (105 ).

Quindi si Nota

facilmente che ancora una volta l'ordine di Join scelto il peggiore.

select

straight_join

count ( d i s t i n c t

NomeVaro , C o d i c e ,

Marinaio_Matricola )

25

as N_Marinai from

desc ;

Incarico

j o i n Nave on ( I n c a r i c o . Nave_Codice = Nave . C o d i c e )

where I n c a r i c o . D a t a F i n e I n c a r i c o
order by count ( d i s t i n c t

i s NULL group by Nave . C o d i c e

desc l i m i t

Marinaio_Matricola )

10;

mysql> s e l e c t / ! s t r a i g h t _ j o i n /
>NomeVaro , C o d i c e , count ( d i s t i n c t M a r i n a i o _ M a t r i c o l a ) as N_Marinai
> I n c a r i c o j o i n Nave on ( I n c a r i c o . Nave_Codice = Nave . C o d i c e )
> where I n c a r i c o . D a t a F i n e I n c a r i c o i s NULL group by Nave . C o d i c e
>order by count ( d i s t i n c t M a r i n a i o _ M a t r i c o l a ) desc l i m i t 1 0 ;
++++
|

NomeVaro

Codice

N_Marinai

from

++++
| FPXGAJXWCNWFVQYY

4850

45

4394

43

| PIDHPDMSHHDT

6480

43

| XSQXJVMC

7570

43

| AXILAOODRPQMXPIBOBWE |

4244

42

FB

6906

42

KNAVSSRZOTPGI

5516

42

6279

42

CJSGKBEDOJ

| BOLXXVWBBYCH
| MWGIHSQFEO

4824

42

5112

42

XHGITZPKCZZYHFHO

++++
10

rows i n

set

mysql> e x p l a i n

(0.48

sec )

select

straight_join

NomeVaro , C o d i c e , count ( d i s t i n c t
Incarico

by count ( d i s t i n c t

1.

0.48

i s NULL group by Nave . C o d i c e

Marinaio_Matricola )

id :

as N_Marinai from

j o i n Nave on ( I n c a r i c o . Nave_Codice = Nave . C o d i c e )

where I n c a r i c o . D a t a F i n e I n c a r i c o
order

Marinaio_Matricola )

row

desc l i m i t

10

\G

select_type :

table :

SIMPLE

Incarico

t y p e : ALL p o s s i b l e _ k e y s :

Nave_Codice

key : NULL
k e y _ l e n : NULL
r e f : NULL

rows :
Extra :

175429

Using where ;

Using temporary ;

id :

2.

row

Using

select_type :

table :
type :

SIMPLE

Nave
eq_ref

p o s s i b l e _ k e y s : PRIMARY, C o d i c e

key : PRIMARY

26

filesort

key_len :
ref :

s h i p . I n c a r i c o . Nave_Codice

rows :

Extra :
2 rows

in

set

(0.00

sec )

Si pu notare che il tempo di esecuzione diminuito e che la tabella che


viene scelta come driving-table Nave.

10.4 Ottimizzazione di 8.14 (2.45sec 0.05sec)


select

distinct
join

Incarico

join

specie

join

Pianeta

Marinaio . Matricola ,

Marinaio

M a r i n a i o . Nome ,

M a r i n a i o . Cognome from

on ( M a t r i c o l a = M a r i n a i o _ M a t r i c o l a )

on ( M a r i n a i o . i d S p e c i e = S p e c i e . i d S p e c i e )
on ( S p e c i e . i d P i a n e t a = P i a n e t a . i d P i a n e t a )

j o i n Nave on ( Nave_Codice = Nave . C o d i c e )


join

Flotta

join

Pianeta

on ( f l o t t a _ i d F l e e t = F l o t t a . i d F l e e t )
a on

f l o t t a . idpianeta = a . idpianeta )

where p i a n e t a . s i s t e m a = "LUWYQNLWCEGOKQWK" or a . s i s t e m a = "LUWYQNLWCEGOKQWK" ;


mysql> e x p l a i n

select

distinct

Marinaio . Matricola ,

M a r i n a i o . Nome ,

> I n c a r i c o j o i n M a r i n a i o on ( M a t r i c o l a = M a r i n a i o _ M a t r i c o l a )
> j o i n s p e c i e on ( M a r i n a i o . i d S p e c i e = S p e c i e . i d S p e c i e )
> j o i n P i a n e t a on ( S p e c i e . i d P i a n e t a = P i a n e t a . i d P i a n e t a )
> j o i n Nave on ( Nave_Codice = Nave . C o d i c e )
> j o i n F l o t t a on ( f l o t t a _ i d F l e e t = F l o t t a . i d F l e e t )
> j o i n P i a n e t a a on ( f l o t t a . i d p i a n e t a = a . i d p i a n e t a )
> where p i a n e t a . s i s t e m a = "LUWYQNLWCEGOKQWK"
> or a . s i s t e m a = "LUWYQNLWCEGOKQWK" \G
1 . row
id :

select_type :

table :

SIMPLE

Pianeta

t y p e : ALL p o s s i b l e _ k e y s : PRIMARY

key : NULL
k e y _ l e n : NULL
r e f : NULL

rows :

954

Using temporary

Extra :

id :

2.

row

select_type :

table :
type :

key :

rows :

p o s s i b l e _ k e y s : PRIMARY, S p e c i e _ F K I n d e x 1

ref

Specie_FKIndex1

key_len :
ref :

SIMPLE

specie

ship . Pianeta . IdPianeta


1

27

M a r i n a i o . Cognom

Using index

Extra :

id :

3.

row

select_type :

table :
type :

key :

SIMPLE

Marinaio
p o s s i b l e _ k e y s : PRIMARY, Marinaio_FKIndex2

ref

Marinaio_FKIndex2

key_len :
ref :

ship . specie . idSpecie

rows :

20

Extra :

id :

select_type :

table :
type :

key :

row

SIMPLE

Incarico
ref

possible_keys :

I n c a r i c o _ F K I n d e x 1 , Nave_Codice

Incarico_FKIndex1

key_len :
ref :

ship . Marinaio . Matricola

rows :

Distinct

Extra :

id :

4.

5.

row

select_type :

table :
type :

SIMPLE

Nave
eq_ref

possible_keys :

PRIMARY, Nave_FKIndex1 , C o d i c e , P i p p o I n d e x
key : PRIMARY
key_len :
ref :

s h i p . I n c a r i c o . Nave_Codice

rows :

Distinct

Extra :

id :

6.

row

select_type :

table :
type :

SIMPLE

Flotta
eq_ref

p o s s i b l e _ k e y s : PRIMARY, F l o t t a _ F K I n d e x 1

key : PRIMARY
key_len :
ref :

s h i p . Nave . F l o t t a _ I d F l e e t

rows :
Extra :

Distinct

id :

7.

select_type :

table :

SIMPLE

28

row

type :

p o s s i b l e _ k e y s : PRIMARY

eq_ref

key : PRIMARY
key_len :
ref :

ship . Flotta . IdPianeta

rows :

Extra :

Using where ;

Distinct
7 rows

in

set

(0.00

sec )

la Query ha un OR nella clausola where.

in Mysql possibile usare un

solo indice per query, e se non possibile futilizzare un indice per tutte le
condizioni del where allora eettua per una full-table scan, quindi nel caso di
OR nella clausola where spesso conveniente riscrivere la query usando invece
una UNION di due query diverse

select

distinct b . Matricola ,

Incarico

join

join

specie

join

Pianeta

Marinaio

b on

b . Cognome from

b . Nome ,

(b . Matricola = Marinaio_Matricola )

on ( b . i d S p e c i e = S p e c i e . i d S p e c i e )
on ( S p e c i e . i d P i a n e t a = P i a n e t a . i d P i a n e t a )

where p i a n e t a . s i s t e m a = "LUWYQNLWCEGOKQWK"
union
select

distinct

Incarico

join

Marinaio . Matricola ,

Marinaio

M a r i n a i o . Nome ,

M a r i n a i o . Cognome from

on ( M a t r i c o l a = M a r i n a i o _ M a t r i c o l a )

j o i n Nave on ( Nave_Codice = Nave . C o d i c e )


join

Flotta

join

Pianeta

on ( f l o t t a _ i d F l e e t = F l o t t a . i d F l e e t )
a on

f l o t t a . idpianeta = a . idpianeta )

where a . s i s t e m a = "LUWYQNLWCEGOKQWK" ;
mysql> s e l e c t

distinct b . Matricola ,

b . Nome ,

b . Cognome from

> I n c a r i c o j o i n M a r i n a i o b on ( b . M a t r i c o l a = M a r i n a i o _ M a t r i c o l a )
> j o i n s p e c i e on ( b . i d S p e c i e = S p e c i e . i d S p e c i e )
> j o i n P i a n e t a on ( S p e c i e . i d P i a n e t a = P i a n e t a . i d P i a n e t a )
> where p i a n e t a . s i s t e m a = "LUWYQNLWCEGOKQWK"
> union
>
s e l e c t d i s t i n c t M a r i n a i o . M a t r i c o l a , M a r i n a i o . Nome , M a r i n a i o . Cognome
>
I n c a r i c o j o i n M a r i n a i o on ( M a t r i c o l a = M a r i n a i o _ M a t r i c o l a )
>
j o i n Nave on ( Nave_Codice = Nave . C o d i c e )
>
j o i n F l o t t a on ( f l o t t a _ i d F l e e t = F l o t t a . i d F l e e t )
>
j o i n P i a n e t a a on ( f l o t t a . i d p i a n e t a = a . i d p i a n e t a )
>
where a . s i s t e m a = "LUWYQNLWCEGOKQWK" ;
++++
|

Matricola

Nome

Cognome

|
++++
|

28714

| WTIQTAXJX

| XANUVCZTOYHGJRJGDLVN |

30770

| VEXDTFTLWTLRHKYGP

29

NJCXC

33983

| IHIXPVQABHOEMHH

| MOVUXHYLSMSPYVAZ

222439

| IMEDUFDKEZCWXA

226273

| SDDCDPPV

| EKPLIWUNPUGPQDLUJ

227277

| NJDLNRDMXCEKNAV

|
[ . . . ]
|

ER

|
|
|
|

SLRFDOBN

|
++++
80

rows i n

set

mysql> e x p l a i n

(0.05

sec )

select

distinct b . Matricola ,

b . Nome ,

b . Cognome from

> I n c a r i c o j o i n M a r i n a i o b on ( b . M a t r i c o l a = M a r i n a i o _ M a t r i c o l a )
> j o i n s p e c i e on ( b . i d S p e c i e = S p e c i e . i d S p e c i e )
> j o i n P i a n e t a on ( S p e c i e . i d P i a n e t a = P i a n e t a . i d P i a n e t a )
> where p i a n e t a . s i s t e m a = "LUWYQNLWCEGOKQWK"
> union
>
s e l e c t d i s t i n c t M a r i n a i o . M a t r i c o l a , M a r i n a i o . Nome , M a r i n a i o . Cognome
>
I n c a r i c o j o i n M a r i n a i o on ( M a t r i c o l a = M a r i n a i o _ M a t r i c o l a )
>
j o i n Nave on ( Nave_Codice = Nave . C o d i c e )
>
j o i n F l o t t a on ( f l o t t a _ i d F l e e t = F l o t t a . i d F l e e t )
>
j o i n P i a n e t a a on ( f l o t t a . i d p i a n e t a = a . i d p i a n e t a )
>
where a . s i s t e m a = "LUWYQNLWCEGOKQWK" \G
1 . row
id :

s e l e c t _ t y p e : PRIMARY

table :

Pianeta

t y p e : ALL p o s s i b l e _ k e y s : PRIMARY

key : NULL
k e y _ l e n : NULL
r e f : NULL

rows :

954

Using where ;

Extra :

Using temporary

id :

2.

row

s e l e c t _ t y p e : PRIMARY

table :
type :

key :

specie
p o s s i b l e _ k e y s : PRIMARY, S p e c i e _ F K I n d e x 1

ref

Specie_FKIndex1

key_len :
ref :

ship . Pianeta . IdPianeta

rows :

Extra :

Using index

id :

3.

s e l e c t _ t y p e : PRIMARY

30

row

table :
type :

key :

Marinaio_FKIndex2

key_len :
ref :

ship . specie . idSpecie

rows :

20

Extra :
id :

p o s s i b l e _ k e y s : PRIMARY, Marinaio_FKIndex2

ref

4.

row

s e l e c t _ t y p e : PRIMARY

table :
type :

key :

Incarico
ref

possible_keys :

Incarico_FKIndex1

Incarico_FKIndex1

key_len :
ref :

ship . b . Matricola

rows :

Using index

Extra :

id :

5.

row

s e l e c t _ t y p e : UNION

table :
key :

Flotta

index

type :

p o s s i b l e _ k e y s : PRIMARY, F l o t t a _ F K I n d e x 1

Flotta_FKIndex1

key_len :

r e f : NULL

rows :

250

Using index ;

Extra :

Using temporary

id :

6.

row

s e l e c t _ t y p e : UNION

table :
type :

a
eq_ref

p o s s i b l e _ k e y s : PRIMARY

key : PRIMARY
key_len :
ref :

ship . Flotta . IdPianeta

rows :

Using where

Extra :

id :

7.

row

s e l e c t _ t y p e : UNION

table :
type :

key :

Nave

Nave_FKIndex1

key_len :
ref :

p o s s i b l e _ k e y s : PRIMARY, Nave_FKIndex1 , C o d i c e , P i p p o I n d e x

ref
4

ship . Flotta . IdFleet

rows :
Extra :

Using index

31


id :

8.

row

s e l e c t _ t y p e : UNION

table :
type :

key :

Incarico
ref

possible_keys :

I n c a r i c o _ F K I n d e x 1 , Nave_Codice

Nave_Codice

key_len :
ref :

s h i p . Nave . C o d i c e

rows :

20

Extra :

id :

9.

row

s e l e c t _ t y p e : UNION

table :
type :

Marinaio
eq_ref

p o s s i b l e _ k e y s : PRIMARY

key : PRIMARY
key_len :
ref :

ship . I n c a r i c o . Marinaio_Matricola

rows :

Extra :

10.

row

i d : NULL
s e l e c t _ t y p e : UNION RESULT

t a b l e : <u n i o n 1 ,2 >
t y p e : ALL p o s s i b l e _ k e y s : NULL

key : NULL
k e y _ l e n : NULL
r e f : NULL

rows : NULL
Extra :

rows i n

10

set

(0.00

sec )

10.5 Ottimizzazione di 8.15 (1.21sec 0.13sec)


come si pu vedere il tempo di esecuzione diminuisce fortemente con questa
soluzione.

Select

Incarico . idIncarico

from I n c a r i c o

join

Marinaio

on ( M a r i n a i o . M a t r i c o l a =

I n c a r i c o . Marinaio_matricola

j o i n Nave on Nave . c o d i c e = I n c a r i c o . Nave_Codice


where year ( Nave . d a t a V a r o ) = 2 0 0 0 or year ( m a r i n a i o . d a t a d i n a s c i t a ) = 2 0 0 0
set

(1.21

sec )

come discusso prima per l'ottimizzazione di 8.14 l'or nella clausola where
rallenta il tempo di esecuzione della query.
La tecnica di ottimizzazione sar la stessa.

32

mysql> S e l e c t

Incarico . idIncarico

> from I n c a r i c o j o i n M a r i n a i o on ( M a r i n a i o . M a t r i c o l a = I n c a r i c o
> where year ( m a r i n a i o . d a t a d i n a s c i t a ) = 2 0 0 0
> union
> S e l e c t I n c a r i c o . i d I n c a r i c o
> from I n c a r i c o j o i n Nave on Nave . c o d i c e = I n c a r i c o . Nave_Codice
> where year ( Nave . d a t a V a r o ) = 2 0 0 0 ;
++
|

idIncarico

. Marinaio_matri

++
|

300015

261263

316363

[ . . . ]
|

289180

412253

330724

++
2254

rows i n

set

(0.13

sec )

10.6 Ottimizzazione di 8.16 (1.21sec 0.13sec)


Select

d i s t i n c t Nave . NomeVaro

from Nave j o i n
join

Pianeta

Facility

on ( Nave . F a c i l i t y _ i d F a c i l i t y = i d F a c i l i t y )

on ( F a c i l i t y . i d P i a n e t a = P i a n e t a . i d P i a n e t a )

j o i n Armamento on ( Armamento . N a v e _ c o d i c e = n a v e . C o d i c e )
join

Facility

join

Pianeta

as
as

Facility2
pianeta2

on ( Armamento . F a c i l i t y _ i d F a c i l i t y = f a c i l i t y 2 . i d F a c i l

on ( F a c i l i t y 2 . i d P i a n e t a = P i a n e t a 2 . i d P i a n e t a )

where p i a n e t a . A v r g t e m p e r a t u r a > 5 0 or

pianeta2 . avrgtemperatura >

50;

come visto nelle ottimizzazioni di 8.15 e 8.14 il problema in questa query


l'or nella clausola where.
Come negli altri casi l'ottimizzazione

Select

d i s t i n c t Nave . NomeVaro

from Nave j o i n Armamento on ( Armamento . N a v e _ c o d i c e = n a v e . C o d i c e )


join

Facility

join

Pianeta

as
as

Facility2
pianeta2

on ( Armamento . F a c i l i t y _ i d F a c i l i t y = f a c i l i t y 2 . i d F a c i l

on ( F a c i l i t y 2 . i d P i a n e t a = P i a n e t a 2 . i d P i a n e t a )

where p i a n e t a 2 . a v r g t e m p e r a t u r a < 5 0
union d i s t i n c t
Select

d i s t i n c t Nave . NomeVaro

from Nave j o i n
join

Pianeta

Facility

on ( Nave . F a c i l i t y _ i d F a c i l i t y = i d F a c i l i t y )

on ( F a c i l i t y . i d P i a n e t a = P i a n e t a . i d P i a n e t a )

where p i a n e t a . A v r g t e m p e r a t u r a < 5 0 ;
mysql> e x p l a i n

Select

d i s t i n c t Nave . NomeVaro

33

> from Nave j o i n Armamento on ( Armamento . N a v e _ c o d i c e = n a v e . C o d i c e )


> j o i n F a c i l i t y as F a c i l i t y 2 on ( Armamento . F a c i l i t y _ i d F a c i l i t y = f a c i l i t y 2
> j o i n P i a n e t a as p i a n e t a 2 on ( F a c i l i t y 2 . i d P i a n e t a = P i a n e t a 2 . i d P i a n e t a )
> where p i a n e t a 2 . a v r g t e m p e r a t u r a < 5 0
> union d i s t i n c t
> S e l e c t d i s t i n c t Nave . NomeVaro
> from Nave j o i n F a c i l i t y on ( Nave . F a c i l i t y _ i d F a c i l i t y = i d F a c i l i t y )
> j o i n P i a n e t a on ( F a c i l i t y . i d P i a n e t a = P i a n e t a . i d P i a n e t a )
> where p i a n e t a . A v r g t e m p e r a t u r a < 5 0 \G
1 . row
id :

s e l e c t _ t y p e : PRIMARY

table :
key :

Facility2

index

type :

p o s s i b l e _ k e y s : PRIMARY, F a c i l i t y _ F K I n d e x 1

Facility_FKIndex1

key_len :

r e f : NULL

rows :

2104

Using index ;

Extra :

Using temporary

id :

2.

row

s e l e c t _ t y p e : PRIMARY

table :
type :

pianeta2
eq_ref

p o s s i b l e _ k e y s : PRIMARY

key : PRIMARY
key_len :
ref :

ship . F a c i l i t y 2 . IdPianeta

rows :

Using where

Extra :

id :

3.

row

s e l e c t _ t y p e : PRIMARY

table :
type :

key :

Armamento
ref

possible_keys :

Armamento_FKIndex1 , Armamento_FKIndex3

Armamento_FKIndex3

key_len :
ref :

ship . Facility2 . i d F a c i l i t y

rows :
Extra :

Using where

id :

4.

row

s e l e c t _ t y p e : PRIMARY

table :
type :

Nave
eq_ref

p o s s i b l e _ k e y s : PRIMARY

key : PRIMARY
key_len :

34

. idFa

ref :

s h i p . Armamento . Nave_Codice

rows :

Extra :

id :

5.

row

s e l e c t _ t y p e : UNION

table :
key :

Facility

index

type :

p o s s i b l e _ k e y s : PRIMARY, F a c i l i t y _ F K I n d e x 1

Facility_FKIndex1

key_len :

r e f : NULL

rows :

2104

Using index ;

Extra :

Using temporary

id :

6.

row

s e l e c t _ t y p e : UNION

table :
type :

Pianeta
p o s s i b l e _ k e y s : PRIMARY

eq_ref

key : PRIMARY
key_len :
ref :

ship . F a c i l i t y . IdPianeta

rows :

Using where

Extra :

id :

7.

row

s e l e c t _ t y p e : UNION

table :
type :

key :

Nave
ref

key_len :
ref :

possible_keys :

Nave_FKIndex3

Nave_FKIndex3
4

ship . F a c i l i t y . i d F a c i l i t y

rows :

Extra :

8.

row

i d : NULL
s e l e c t _ t y p e : UNION RESULT

t a b l e : <u n i o n 1 ,2 >
t y p e : ALL p o s s i b l e _ k e y s : NULL

key : NULL
k e y _ l e n : NULL
r e f : NULL

rows : NULL
Extra :

rows i n

set

(0.00

sec )

come si pu vedere dall'explain la query non ulteriormente ottimizzabile.

35

11

Stored Procedure
Questa Stored Procedure Prende come parametro di input la matricola di un
marinaio, e lo promuove automaticamente di un grado nella scala gerarchica cercando automaticamente se c' un grado superiore al grado attualmente ricoperto
dal marinaio. Se il grado non dovesse esistere lo crea e glielo assegna.
delimiter

Create p r o c e d u r e

( in

Promote

Mtr

int )

begin

s e l e c t max ( HScalaComando )
join

Incarico

i n t o @Max from

on ( i n c a r i c o . Grado_idGrado = g r a d o . i d G r a d o )

grado

where M a r i n a i o _ M a t r i c o l a = mtr and d a t a f i n e i n c a r i c o


select

join

Incarico

join

null ;

on ( i n c a r i c o . Grado_idGrado = g r a d o . i d G r a d o )

grado

gerarchia

is

i n t o @ F a z i o n e from

idFazione

on ( g e r a r c h i a . Grado_idGrado = g r a d o . i d g r a d o )

where M a r i n a i o _ M a t r i c o l a = mtr and HScalaComando = @Max ;


s e l e c t min ( HScalacomando )
gerarchia

join

grado

i n t o @Min from

on ( g e r a r c h i a . Grado_idGrado = g r a d o . i d g r a d o )

where HScalaComando > @Max and i d F a z i o n e = @ F a z i o n e ;


if

@min

not n u l l

is

then
select

Grado_idGrado

Gerarchia

join

grado

i n t o @Grado from
on ( g e r a r c h i a . Grado_idGrado = g r a d o . i d g r a d o )

where i d F a z i o n e = @ F a z i o n e and HSCALACOMANDO = @Min ;


update

incarico

s e t g r a d o _ i d G r a d o = @grado
where M a r i n a i o _ M a t r i c o l a = mtr and d a t a f i n e i n c a r i c o

is

null ;

else
s e l e c t NomeGrado into@Name from
gerarchia

join

grado

on ( g e r a r c h i a . Grado_idGrado = g r a d o . i d g r a d o )

where HScalaComando = @Max and i d F a z i o n e = @ F a z i o n e ;


insert

i n t o Grado ( HscalaComando

, Nomegrado )

values

(@max+1 ,

maggiore " ) ) ;

select

idGrado

insert

into

update

incarico

c o n c a t ( @nome ,

"

i n t o @grado from Grado where h s c a l a c o m a n d o = @max+1 a

Gerarchia

values

( @grado ,

@fazione ) ;

s e t g r a d o _ i d G r a d o = @grado

where M a r i n a i o _ M a t r i c o l a = mtr and d a t a f i n e i n c a r i c o


END IF ;
end ;
}
delimiter

36

is

null ;

Questa Stored Procedure prende come parametro di input l'id di un pianeta e


Modica il Database In occasione di un evento catastroco sul pianeta dato in
input, settando il pianeta come distrutto, le specie abitanti sul pianeta come
vicine all'estinzione e distruggendo le otte di stanza sul pianeta stesso.
delimiter

create

procedure

DoomDay ( In

iD

int )

begin

update P i a n e t a
set

isnotdestroyed = false

update S p e c i e
d e l e t e from

set

where P i a n e t a . i d P i a n e t a = iD ;
= true where

isnearextinction

flotta

S p e c i e . i d P i a n e t a = iD ;

where F l o t t a . i d P i a n e t a = iD ;

end ;
}
delimiter

Questa Stored Procedure semplicemente una re-implementazione della query


8.11 come Procedure in modo da poter essere pi facilmente usata in maniera
parametrica. Prende come parametri di input l'id di una mansione e l'id di un
incarico e stampa a video il risultato della query
delimiter

Create p r o c e d u r e

( in

Find

ClassiD

int ,

in

IncaricId

int )

begin

s e l e c t max ( Grado_idGrado ) from


Marinaio

join

join

Mansione

Incarico

on (

on (

Marinaio_Matricola = Matricola

M a n s i o n e _ i d I n c a r i c o = Mansione . i d I n c a r i c o

j o i n Grado on ( i d G r a d o = Grado_idGrado )

j o i n Nave on ( Nave_Codice = Nave . C o d

where M a n s i o n e . i d I n c a r i c o = I n c a r i c I d and Nave . C l a s s = C l a s s i D


select

Marinaio

join

i n t o @max ;

M a r i n a i o . Nome , M a r i n a i o . Cognome from

join

Mansione

Incarico

on (

on (

Marinaio_Matricola = Matricola

M a n s i o n e _ i d I n c a r i c o = Mansione . i d I n c a r i c o

j o i n Grado on ( i d G r a d o = Grado_idGrado )

j o i n Nave on ( Nave_Codice = Nave . C o d

where M a n s i o n e . i d I n c a r i c o = I n c a r i c I d and Nave . C l a s s = C l a s s i D and Grado_idG


end ;
}
delimiter

12

Views
Crea una view che restituisce tutte le navi varate nell'anno corrente

c r e a t e view N a v i _ a t t u a l i
from Nave j o i n

Class

as S e l e c t

Codice ,

NomeVaro ,

on ( Nave . C l a s s = C l a s s . C l a s s )

where year ( DataVaro ) = year ( now ( ) ) ;

37

DataVaro ,

Class . Class

Crea una view che restituisce tutti i marinai che hanno pi di 50 anni

CREATE VIEW a n z i a n i AS SELECT M a r i n a i o . Nome

M a r i n a i o . Cognome

FROM M a r i n a i o
WHERE DATEDIFF(CURDATE(

, DataDiNascita

/365 > 50

Crea una view che restituisce tutte le Classi a disposizione della otta F

Create VIEW C l a s s i _ d i AS S e l e c t
from C l a s s

C l a s s . NameClass

as C l a s s ,

count ( )

j o i n Nave on ( C l a s s . C l a s s = Nave . C l a s s )

join

Flotta

join

Fazione

on ( Nave . F l o t t a _ i d F l e e t = F l o t t a . i d F l e e t )
on ( F l o t t a . i d F a z i o n e = F a z i o n e . i d F a z i o n e )

where a l l i a n c e n a m e = "JEUNWXGHDECOUWOMY"

Crea una view che restituisce i pianeti che hanno dato vita ad una specie

Create view P i a n e t i _ v i v i AS
Select

P i a n e t a . Nome as

from S p e c i e

join

Planet

Pianeta

on ( S p e c i e . i d P i a n e t a = P i a n e t a . i d P i a n e t a )

group by P i a n e t a . i d P i a n e t a ;

Crea una view che restituisce tutte le navi varate questo anno di una classe a
disposizione della otta F

Create view N a v i _ c o m e _ c l a s s _ a t t u a l i AS
Select

from C l a s s i _ d i

13

join

Navi_attuali

on ( C l a s s e = C l a s s ) ;

Transazioni

Una transazione una serie di azioni che vengono compiute assieme contemporaneamente.
Il meccanismo delle transazioni permette di assicurare il rispetto delle propriet ACID (Atomiicity, Consistency, Isolation, Durability) quando si eettuano
dei commit nel Database.
Le propriet da rispettare sono appunto

Atomicit:

Una transazione una unit atomica.

Non pu essere ese-

quita in parte, quindi se per qualche motivo la transazione non v a buon


ne bisogna eettuare un rollback no all'inizio della transazione stessa
ripristinando i i dati nel database ad una situazione precedente all'avvio
della transazione

Consistenza: Una transazione rispetta i vincoli di integrit

Isolazione: Una transazione indipendente dalle altre, se pi transazioni


vengono eettuate in parallelo l'eetto risultante deve essere identico ad
una esecuzione sequenziale

38

as No

Durabilit: Gli eetti di una transazione portata a buon ne sono persistenti nel tempo

Questo un esempio di transazione che simula l'abbattimento di un velivolo B1


da un velivolo A1
Start

Transaction ;

update V e l i v o l o

Set T a c c h e = T a c c h e +1 where

idvelivolo

= @A1 ;

d e l e t e from V e l i v o l o where i d V e l i v o l o = @B1 ;


Commit ;
In Questo altro esempio si vede una transazione che accorpa la otta A1 nella
otta B1, e poi distrugge la otta A1 oramai vuota
Start

Transaction ;

update Nave s e t

F l o t t a _ i d F l e e t = @B1 where

d e l e t e from F l o t t a where i d F l e e t = @A1 ;


Commit ;

39

F l o t t a _ i d F l e e t = @A1 ;

You might also like