import * as Bluelib from "@steffo/bluelib-react" import { BaseElement } from "@steffo/bluelib-react/dist/components/BaseElement" import { Section, Panel, r, ILatex, BLatex, PLatex, P, Anchor, I, B, Help, Example, LI } from "../../components/compat1" import 'katex/dist/katex.min.css'; import { WarningIncomplete, WarningPorted, WarningUnchecked } from "../../components/warnings"; export default function BasiDiDati() { return <> Basi di Dati Introduzione

Alle superiori, abbiamo trattato molto in dettaglio le Basi di Dati, quindi non ho preso appunti per tutta la prima parte del corso; pertanto, qui ci sono solo appunti sulla seconda parte, quella sul calcolo dei costi.

In compenso, abbiamo pubblicato il progetto di gruppo che abbiamo realizzato per l'esame: potete usarlo per prendere ispirazione se siete bloccati con il vostro!

Link

Simbolo Descrizione
{r`N_{tuple}`} Numero di tuple di una tabella
{r`N_{blocchi}`} Numero di blocchi di una tabella
{r`N_{foglie}`} Numero di foglie di un indice
{r`N_{indici}`} Numero di indici presenti in una tabella
{r`N_{unici}`} Numero di valori unici presenti in una colonna
{r`F`} Fattore di selettività di una condizione
{r`C`} Costo di accesso a una o più tuple
{r`N_{selezionati}`} Numero di tuple del risultato

Espressione formata da una o più condizioni moltiplicate tra loro.

Condizioni che soddisfano i seguenti requisiti:

È possibile costruire indici sulle colonne di una tabella per velocizzare le query che riguardano quelle colonne.

In particolare, ogni tabella può avere un indice clustered e infiniti indici unclustered.

Generalmente, l'indice clustered è costruito sulla colonna della primary key, ma non è sempre quello il caso.

Gli indici vanno tenuti aggiornati, e ciò ha un costo di manutenzione:

È possibile usare gli indici nelle query solo per gli argomenti di ricerca attraverso indice.

La percentuale di tuple di una tabella che soddisfano una condizione.

Condizione Fattore di selettività
col = $costante {r`F = \frac{1}{N_{unici}}`}
col != $costante {r`F = 1 - \frac{1}{N_{unici}}`}
col1 != col2 {r`F = \frac{1}{max(N_{unici_A}, N_{unici_B})}`}
IN {r`F = \frac{n_{IN}}{N_{unici}}`}
col > $costante {r`F = \frac{ max(col) - \$costante }{ max(col) - min(col) }`}
{r`col < $costante`} {r`F = \frac{ \$costante - min(col) }{ max(col) - min(col) }`}
col BETWEEN $lower AND $upper {r`F = \frac{ \$upper - \$lower }{ max(col) - min(col) }`}
cond1 OR cond2 {r`F = F_{cond1} + F_{cond2} - ( F_{cond1} \cdot F_{cond2} )`}

Quante unità di lavoro costa accedere a una specifica relazione:

{r` C = {\color{yellow} {C_{indice}}} + {\color{Orange} C_{relazione}} `}

Per accedere attraverso un indice a una specifica tupla della relazione, si spenderà:

{r` C = {\color{yellow} 1} + {\color{Orange} 1} `}

Se le tuple a cui si vuole accedere sono più di una, allora, il costo dipenderà da se l'indice è clustered o non-clustered.

Nel calcolo del costo di una query, si considerano tutti i cambi di pagina come page fault.

Per gli indici clustered, visto che basta caricare in memoria i blocchi in sequenza, il costo sarà:

{r` C = {\color{yellow} ( F \cdot N_{foglie} ) } + {\color{Orange} ( F \cdot N_{blocchi} ) } `}

Per gli indici unclustered, per i quali potremmo dover caricare e rimuovere lo stesso blocco dalla memoria più volte, il costo sarà:

{r` C = {\color{yellow} ( F \cdot N_{foglie} ) } + {\color{Orange} ( F \cdot N_{tuple} ) } `}

Se si stanno effettuando query su più indici unclustered, il costo sarà:

{r` C = {\color{yellow}\sum_k ( F_k \cdot N_{foglie_k} )} + {\color{Orange} \left( \prod_k F_k \cdot N_{tuple} \right)} `}

Quante unità di lavoro costa effettuare un join tra due relazioni.

Varia in base al metodo di join utilizzato.

Utilizzando il metodo del nested loop:

{r` C_{1 \times 2} = C_1 + ( N_{selezionati_1} \cdot C_2 ) `}

La scelta della colonna su cui iterare è quindi importante!

}