79 lines
3.9 KiB
TeX
79 lines
3.9 KiB
TeX
% !TEX root = ../main.tex
|
||
\\
|
||
\textbf{Schema logico relazionale in formato testuale}
|
||
|
||
\begin{lstlisting}[style=SQLu,escapechar=@]
|
||
Persone(@\underline{IdPersona}@, Nome, Cognome, Email, CodiceFiscale)
|
||
Clienti(@\underline{IdPersona*}@, IndirizzoSpedizione)
|
||
Birraie(@\underline{IdPersona*}@, Soprannome)
|
||
Birrifici(@\underline{IdBirrificio}@, Nome, AnnoFondazione, Motto, Stemma,
|
||
CapacitàProduttiva)
|
||
BirrificiBirraie(@\underline{IdBirrificio*, IdBirraia*}@)
|
||
Fornitori(@\underline{IdFornitore}@, RagioneSociale, PartitaIva, Indirizzo)
|
||
Fatture(@\underline{IdFattura}@, IdBirrificio*, IdFornitore*, Data,
|
||
NumeroFattura, Importo)
|
||
TipiIngredienti(@\underline{IdTipo}@, Tipo, UnitàDiMisura)
|
||
Ingredienti(@\underline{IdIngrediente}@, IdTipo*, Descrizione)
|
||
Acquisti(@\underline{IdFattura*, IdIngrediente*}@, Quantità)
|
||
Ricette(@\underline{IdRicetta}@, IdBirrificio*, IdCreatrice*, IdRicettaMadre*,
|
||
Nome, DataCreazione, Stato)
|
||
IngredientiRicette(@\underline{IdRicetta*, IdIngrediente*}@, Quantità)
|
||
Produzioni(@\underline{IdProduzione}@, IdRicetta*, DataProduzione, NumeroLotto,
|
||
Stato, NumeroBottiglie)
|
||
Prenotazioni(@\underline{IdCliente*, IdProduzione*}@, Stato, Quantità)
|
||
Note(@\underline{IdNota}@, IdProduzione*, Testo)
|
||
NoteDegustazione(@\underline{IdNota*}@, Giudizio)
|
||
\end{lstlisting}
|
||
|
||
\paragraph{Dipendenze funzionali}
|
||
\begin{itemize}
|
||
\itemsep0em
|
||
\item Per ogni tabella la chiave primaria (sottolineata) determina ciascuno
|
||
degli attributi della tabella.
|
||
\begin{lstlisting}[style=SQLu,escapechar=@]
|
||
IdPersona @$\to$@ Nome, IdPersona @$\to$@ Cognome, IdPersona @$\to$@ Email,
|
||
IdPersona @$\to$@ CodiceFiscale, @$\textellipsis$@
|
||
\end{lstlisting}
|
||
\item Nella tabella \texttt{Persone}, \texttt{CodiceFiscale} è chiave
|
||
naturale e determina tutti gli altri attributi.
|
||
Ho ritenuto prudente aggiungere una chiave artificiale perché, se è vero
|
||
che due persone diverse non avranno mai lo stesso codice fiscale, è vero
|
||
anche che ci possono essere errori umani nell'inserimento di un CF e voglio
|
||
riservarmi la possibilità di correggere un CF senza minare l'affidabiltà
|
||
della base di dati.
|
||
\item Stesso discorso per la \texttt{RagioneSociale} e la \texttt{PartitaIva} nella tabella
|
||
\texttt{Fornitori}: ciascuno è chiave separatamente.
|
||
\item Nella tabella \texttt{Fatture}, la coppia di attributi \texttt{\{IdFornitore, NumeroFattura\}}
|
||
è chiave.
|
||
\item Nella tabella \texttt{Produzioni}, il NumeroLotto \underline{non} è chiave, in
|
||
quanto birrifici diversi possono avere lotti uguali, è solo all'interno del
|
||
birrificio che il lotto identifica univocamente la produzione.
|
||
\end{itemize}
|
||
|
||
Uno schema R, avente insieme di attributi T e insieme di dipendenze funzionali F, \lstinline{R<T, F>}, è
|
||
in forma normale di Boyce-Codd (BCNF) se ogni dipendenza funzionale della chiusura di F o è
|
||
banale o ha come determinante una superchiave di T.
|
||
Esiste un teorema che semplifica il calcolo, asserendo che se la condizione di cui sopra vale per
|
||
una qualsiasi copertura di F allora vale per l’intera chiusura di F.
|
||
|
||
Nella copertura di F che ho descritto sopra (che peraltro è canonica: ogni dipendenza ha un
|
||
solo attributo come determinato, nessuna dipendenza è ridondante e non sono presenti
|
||
attributi estranei, in quanto ogni determinante è chiave), ogni dipendenza funzionale ha
|
||
come determinante o la chiave primaria o una chiave naturale che non è stata scelta come
|
||
primaria, in ogni caso una superchiave. \underline{La BCNF è pertanto rispettata}.
|
||
|
||
Alcuni vincoli intra-relazionali possono essere tradotti in trigger in modo da
|
||
mantenere la coerenza del database con l'inserimento di record.
|
||
Per esempio:
|
||
\begin{lstlisting}[style=SQLu,escapechar=@]
|
||
CREATE TRIGGER IntegritàReferenzialeNote
|
||
BEFORE INSERT ON Note
|
||
BEGIN
|
||
SELECT
|
||
CASE WHEN NEW.IdProduzione NOT IN (
|
||
SELECT IdProduzione FROM Produzioni)
|
||
THEN RAISE (ABORT,'Produzione non valida!')
|
||
END;
|
||
END;
|
||
\end{lstlisting}
|