Queer European MD passionate about IT
Browse Source

Working on first assignment

Davte 4 năm trước cách đây
mục cha
commit
1356990467

+ 16 - 0
compitino/main.tex

@@ -1,9 +1,21 @@
 \documentclass [11pt, a4paper]{article}
 
 \usepackage[main= italian, english]{babel}
+\usepackage{enumitem}
 \usepackage{graphicx}
 \usepackage[utf8]{inputenc}
+\usepackage{listings}
+\usepackage{pxfonts}
+\usepackage{textcomp}
 
+\lstset{upquote=true,showstringspaces=false}
+\lstdefinestyle{SQLu}{
+    language=SQL,
+    basicstyle=\small\ttfamily,
+    keywordstyle=\bfseries,
+    moredelim=[is][\underbar]{_}{_},
+    keepspaces=true
+}
 \selectlanguage{italian}
 
 \setcounter{section}{-1}
@@ -38,4 +50,8 @@
           \label{fig:schema-logico}
         \end{figure}
         \input{\folder/schema_logico.tex}
+    \section{Interrogazioni}\label{sec:queries}
+        \input{\folder/queries.tex}
+    \section{Piani di accesso}\label{sec:piani}
+        \input{\folder/piani_di_accesso.tex}
 \end{document}

+ 0 - 0
compitino/primo_compitino/piani_di_accesso.tex


+ 120 - 0
compitino/primo_compitino/queries.tex

@@ -0,0 +1,120 @@
+% !TEX root = ../main.tex
+
+\begin{enumerate}[label=\alph*.]
+    \item Uso di proiezione, join e restrizione
+
+    Riportare il titolo e l’URL dei siti web il cui titolo inizia con la lettera G (compreso il caso
+    in cui il titolo sia esattamente 'G’).
+\begin{lstlisting}[style=SQLu]
+SELECT e.Titolo, sw.Url
+FROM Edizioni e
+JOIN SitiWeb sw ON e.IdEdizione = sw.IdEdizione
+WHERE e.Titolo >= 'G' AND e.Titolo < 'H'
+\end{lstlisting}
+    \item Uso di group by con having, where e sort
+
+    Riportare IdUtente e tempo totale di lettura, purché superiore a 10 minuti, escludendo
+    le sessioni di lettura lunghe un’ora o più (probabilmente l’utente avrà lasciato aperta la
+    pagina, non stava davvero leggendo: sui nostri siti peraltro dopo 55 minuti di inattività
+    si attiva una animazione che copre l’articolo e chiede di premere un pulsante per
+    continuare a leggere, altrimenti esegue il logout dell’utente dopo 5 minuti) e ordinando
+    dall’utente che ha passato più minuti a leggere a quello che ne ha passati meno.
+\begin{lstlisting}[style=SQLu]
+SELECT v.IdUtente, SUM(v.TempoLettura) TempoTotaleLettura
+FROM Visite v
+WHERE v.TempoLettura < 60
+GROUP BY v.IdUtente
+HAVING SUM(v.TempoLettura) > 10
+ORDER BY SUM(v.TempoLettura) DESC
+\end{lstlisting}
+    \item Uso di join, group by con having e where
+
+    Riportare il codice articolo, il titolo, il numero di visite e il tempo totale di lettura degli
+    articoli ad accesso libero (ovvero non premium) visti almeno 3 volte.
+\begin{lstlisting}[style=SQLu]
+SELECT a.IdArticolo, a.Titolo, COUNT(*) NumeroVisite,
+       SUM(v.TempoLettura) TempoTotaleLettura
+FROM Visite v
+JOIN Articoli a ON a.IdArticolo = v.IdArticolo
+WHERE a.Premium = 'N'
+GROUP BY a.IdArticolo, a.Titolo
+HAVING COUNT(*) >= 3
+\end{lstlisting}
+
+    Posso fare COUNT(*) perché la giunzione con chiave esterna IdArticolo (che è chiave
+    primaria della tabella Articoli) avrà tante righe quante ce ne sono nella tabella Visite:
+    per ogni riga di Visite c’è una sola riga di Articoli.
+    Raggruppo anche per titolo oltre che per IdArticolo (anche se IdArticolo → Titolo)
+    perché proietto poi anche il Titolo.
+    \item Uso di select annidata con quantificazione esistenziale
+
+    Riportare Cognome e Nome dei giornalisti che hanno scritto almeno un articolo sul
+    giornale “Il Titanio".
+\begin{lstlisting}[style=SQLu]
+SELECT g.Cognome, g.Nome
+FROM Giornalisti g
+WHERE EXISTS (SELECT *
+              FROM ArticoliGiornalisti ag
+              JOIN Articoli a ON a.IdArticolo = ag.IdArticolo
+              JOIN Edizioni e ON e.IdEdizione = a.IdEdizione
+              WHERE ag.IdGiornalista = g.IdGiornalista
+                    AND e.Titolo = 'Il Titanio')
+\end{lstlisting}
+
+    NOTA: avrei potuto fare una giunzione su IdGiornalista anziché una quantificazione
+    esistenziale.
+    \item Uso di select annidata con quantificazione universale
+
+    Riportare Cognome e Nome dei giornalisti che hanno scritto solo articoli per giornali
+    diretti da Peppone.
+    Esprimo in notazione insiemistica:
+\begin{lstlisting}[style=SQLu,escapechar=@]
+{g.Cognome, g.Nome | g @$\in$@ Giornalisti .
+    @$\forall$@ (ag @$\in$@ ArticoliGiornalisti, a @$\in$@ Articoli, e @$\in$@ Edizioni,
+        a.IdArticolo = ag.IdArticolo,
+        e.IdEdizione = a.IdEdizione,
+        ag.IdGiornalista = g.IdGiornalista) .
+    (e.Direttore = 'Peppone')}
+\end{lstlisting}
+    Trasformando il $\forall x.P$ in $\neg\exists x.\neg P$:
+\begin{lstlisting}[style=SQLu,escapechar=@]
+{g.Cognome, g.Nome | g @$\in$@ Giornalisti .
+    @$\neg\exists$@ (ag @$\in$@ ArticoliGiornalisti, a @$\in$@ Articoli, e @$\in$@ Edizioni,
+        a.IdArticolo = ag.IdArticolo,
+        e.IdEdizione = a.IdEdizione,
+        ag.IdGiornalista = g.IdGiornalista) .
+    (e.Direttore = 'Peppone')}
+\end{lstlisting}
+    Scrivo quindi la query:
+\begin{lstlisting}[style=SQLu,escapechar=@]
+SELECT g.Cognome, g.Nome
+FROM Giornalisti g
+WHERE NOT EXISTS (SELECT *
+                  FROM ArticoliGiornalisti ag
+                  JOIN Articoli a
+                    ON a.IdArticolo = ag.IdArticolo
+                  JOIN Edizioni e
+                    ON e.IdEdizione = a.IdEdizione
+                  WHERE ag.IdGiornalista = g.IdGiornalista
+                        AND e.Direttore != 'Peppone')
+\end{lstlisting}
+
+    NOTA: i giornalisti che non hanno scritto articoli compariranno nel risultato.
+    \item Uso di subquery di confronto quantificato usando una subquery di tipo scalare
+
+    Voglio premiare il dipendente che esercita la professione da più tempo: per fare questo,
+    ho bisogno di sapere il codice INPS del giornalista con numero di iscrizione all’albo più
+    basso.
+\begin{lstlisting}[style=SQLu,escapechar=@]
+SELECT gd.CodiceInps
+FROM GiornalistiDipendenti gd
+JOIN Giornalisti g ON g.IdGiornalista = gd.IdGiornalista
+WHERE g.NumeroAlbo = ANY(SELECT MIN(g2.NumeroALbo)
+                         FROM Giornalisti g2
+                         JOIN GiornalistiDipendenti gd2
+                           ON g2.IdGiornalista = gd2.IdGiornalista)
+\end{lstlisting}
+    La subquery scalare restituisce un singolo valore, mentre il confronto quantificato è utile
+    quando la subquery restituisce un insieme di più valori. \lstinline[language=SQL]{= ANY} equivale a \lstinline[language=SQL]{IN}.
+\end{enumerate}
+%\end{enumerate}

+ 33 - 18
compitino/primo_compitino/schema_logico.tex

@@ -1,23 +1,38 @@
 % !TEX root = ../main.tex
 
 \textbf{Schema logico relazionale in formato testuale}
-\begin{verbatim}
-Giornali(\underline{IdEdizione*}, ComuneStampa)
-SitiWeb(\underline{IdEdizione*}, Url)
-Edizioni(\underline{IdEdizione}, Titolo, Direttore, AnnoFondazione)
-Articoli(\underline{IdArticolo}, IdEdizione*, Titolo, Sottotitolo,
+\begin{lstlisting}[style=SQLu,escapechar=@]
+Giornali(@\underline{IdEdizione*}@, ComuneStampa)
+SitiWeb(@\underline{IdEdizione*}@, Url)
+Edizioni(@\underline{IdEdizione}@, Titolo, Direttore, AnnoFondazione)
+Articoli(@\underline{IdArticolo}@, IdEdizione*, Titolo, Sottotitolo,
     DataPubblicazione, Premium)
-Visite(\underline{IdVisita}, IdArticolo*, TempoLettura, IdUtente*)
-Utenti(\underline{IdUtente}, Nome, Cognome, Indirizzo)
-Abbonamenti(\underline{IdUtente*, IdEdizione*, DataSottoscrizione}, DataScadenza)
-ArticoliGiornalisti(\underline{IdArticolo*, IdGiornalista*})
-Giornalisti(\underline{IdGiornalista}, NumeroAlbo, Cognome, Nome)
-GiornalistiDipendenti(\underline{IdGiornalista*}, CodiceInps)
-GiornalistiFreeLance(\underline{IdGiornalista*}, PartitaIva)
-\end{verbatim}
+Visite(@\underline{IdVisita}@, IdArticolo*, TempoLettura, IdUtente*)
+Utenti(@\underline{IdUtente}@, Nome, Cognome, Indirizzo)
+Abbonamenti(@\underline{IdUtente*, IdEdizione*, DataSottoscrizione}@, DataScadenza)
+ArticoliGiornalisti(@\underline{IdArticolo*, IdGiornalista*}@)
+Giornalisti(@\underline{IdGiornalista}@, NumeroAlbo, Cognome, Nome)
+GiornalistiDipendenti(@\underline{IdGiornalista*}@, CodiceInps)
+GiornalistiFreeLance(@\underline{IdGiornalista*}@, PartitaIva)
+\end{lstlisting}
 
-%\textbf{Dipendenze funzionali}
-%\begin{itemize}
-%\item Per ogni tabella la chiave primaria (sottolineata) determina ciascuno degli attributi della tabella ($\{IdEdizione \to Titolo, IdEdizione \to Direttore, \textellipsis\}$)
-%\item Nella tabella Giornalisti, vale inoltre che $\{NumeroAlbo \to Nome;$ $NumeroAlbo \to Cognome;$ $NumeroAlbo \to IdGiornalista\}$: NumeroAlbo è una chiave naturale (l’Ordine dei Giornalisti si cura di non attribuire lo stesso numero di iscrizione all’albo a due giornalisti diversi), ho scelto di aggiungere la chiave artificiale IdGiornalista prevedendo possibili errori di inserimento da parte della segreteria della catena editoriale: in queto modo, il NumeroAlbo può essere modificato senza problemi in caso di errori. Discorso analogo per CodiceInps e PartitaIva.
-%\end{itemize}
+\paragraph{Dipendenze funzionali}
+\begin{itemize}
+\item Per ogni tabella la chiave primaria (sottolineata) determina ciascuno degli attributi della tabella ($\{IdEdizione \to Titolo, IdEdizione \to Direttore, \textellipsis\}$)
+\item Nella tabella Giornalisti, vale inoltre che $\{NumeroAlbo \to Nome;$ $NumeroAlbo \to Cognome;$ $NumeroAlbo \to IdGiornalista\}$: NumeroAlbo è una chiave naturale (l’Ordine dei Giornalisti si cura di non attribuire lo stesso numero di iscrizione all’albo a due giornalisti diversi), ho scelto di aggiungere la chiave artificiale IdGiornalista prevedendo possibili errori di inserimento da parte della segreteria della catena editoriale: in queto modo, il NumeroAlbo può essere modificato senza problemi in caso di errori. Discorso analogo per CodiceInps e PartitaIva.
+\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 i determinanti sono tutti 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}.
+
+NOTA: assumo che la stringa “Indirizzo” e simili siano attributi atomici, anche se forse nella
+realtà sarebbero meglio rappresentati in altro modo.