1
Fork 0
mirror of https://github.com/Steffo99/alexandria.git synced 2024-11-21 21:34:19 +00:00

Descrivi più tabelle

This commit is contained in:
Steffo 2020-06-04 01:50:40 +02:00
parent edb25f9e79
commit 4c17a4ada4
Signed by: steffo
GPG key ID: 896A80F55F7C97F0
3 changed files with 228 additions and 50 deletions

View file

@ -30,7 +30,7 @@ Gli utenti potranno aggiungere _elementi_ alla loro raccolta multimediale.
Un elemento rappresenta una copia di un libro, di un film o di un videogioco posseduta da un utente. Un elemento rappresenta una copia di un libro, di un film o di un videogioco posseduta da un utente.
Ogni elemento avrà associato uno **stato** da una lista di opzioni diversa per ogni tipologia: Ogni elemento avrà associato uno **stato** da una lista di opzioni diverse per ogni tipologia:
- Libro - Libro
- Da iniziare - Da iniziare

View file

@ -41,10 +41,170 @@ CREATE TABLE public.audiolibro_edizione (
immagine bytea, immagine bytea,
relativa_a integer NOT NULL relativa_a integer NOT NULL
); );
ALTER TABLE ONLY public.audiolibro_edizione
ADD CONSTRAINT audiolibro_edizione_pkey PRIMARY KEY (isbn);
``` ```
L'immagine relativa all'audiolibro è archiviata nella base di dati come un blob binario di dati. L'immagine relativa all'audiolibro è archiviata nella base di dati come un blob binario di dati.
### `audiolibro_recensione`
```sql
CREATE TABLE public.audiolibro_recensione (
id bigint NOT NULL,
commento text NOT NULL,
valutazione smallint NOT NULL,
data timestamp without time zone NOT NULL,
CONSTRAINT audiolibro_recensione_valutazione_check CHECK (((valutazione >= 0) AND (valutazione <= 100)))
);
ALTER TABLE ONLY public.audiolibro_recensione
ADD CONSTRAINT audiolibro_recensione_pkey PRIMARY KEY (id);
```
La valutazione delle recensioni deve essere obbligatoriamente tra 0 e 100: a tale scopo, è stato introdotto un _CHECK_ sulla tabella.
La data di pubblicazione è rappresentata da un _timestamp_.
### `film`
```sql
CREATE TABLE public.film (
eidr character(34) NOT NULL,
titolo character varying NOT NULL,
sinossi text,
locandina bytea,
durata integer,
CONSTRAINT film_durata_check CHECK ((durata >= 0))
);
ALTER TABLE ONLY public.film
ADD CONSTRAINT film_pkey PRIMARY KEY (eidr);
```
I film hanno un _CHECK_ che impedisce alla loro durata di essere minore di 0 minuti, nel caso essa sia definita.
Il loro `eidr` è una stringa di lunghezza costante _char_, in quanto gli EIDR sono sempre lunghi 34 caratteri.
Inoltre, come per gli audiolibri, la loro locandina è immagazzinata nel database come _bytea_.
### `film_correlazioni`
```sql
CREATE TABLE public.film_correlazioni (
eidr_1 character(34) NOT NULL,
eidr_2 character(34) NOT NULL
);
ALTER TABLE ONLY public.film_correlazioni
ADD CONSTRAINT film_correlazioni_pkey PRIMARY KEY (eidr_1, eidr_2);
ALTER TABLE ONLY public.film_correlazioni
ADD CONSTRAINT eidr_1 FOREIGN KEY (eidr_1) REFERENCES public.film(eidr);
ALTER TABLE ONLY public.film_correlazioni
ADD CONSTRAINT eidr_2 FOREIGN KEY (eidr_2) REFERENCES public.film(eidr);
```
L'autoassociazione delle correlazioni è stata implementata attraverso una **tabella ponte** che collega due film attraverso i loro `eidr`.
`eidr_1` ed `eidr_2` sono due chiavi esterne separate, e insieme formano la **chiave primaria composta** della tabella.
### `film_vi_ha_preso_parte`
```sql
CREATE TABLE public.film_vi_ha_preso_parte (
eidr character(34) NOT NULL,
id_cast integer NOT NULL,
id_ruolo integer NOT NULL
);
ALTER TABLE ONLY public.film_vi_ha_preso_parte
ADD CONSTRAINT film_vi_ha_preso_parte_pkey PRIMARY KEY (eidr, id_cast, id_ruolo);
ALTER TABLE ONLY public.film_vi_ha_preso_parte
ADD CONSTRAINT eidr FOREIGN KEY (eidr) REFERENCES public.film(eidr);
ALTER TABLE ONLY public.film_vi_ha_preso_parte
ADD CONSTRAINT id_cast FOREIGN KEY (id_cast) REFERENCES public.film_cast(id);
ALTER TABLE ONLY public.film_vi_ha_preso_parte
ADD CONSTRAINT id_ruolo FOREIGN KEY (id_ruolo) REFERENCES public.film_ruolo(id);
```
L'associazione ternaria è stata realizzata con una **tabella ponte**, con una **chiave primaria composta** e tre chiavi esterne separate.
### `elemento_id_seq`
```sql
CREATE SEQUENCE public.elemento_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
```
Si è deciso di rendere **univoci** gli `id` di **tutti gli elementi**, qualsiasi fosse il loro tipo.
Per realizzare l'unicità si è creata una unica _SEQUENCE_, che viene usata da tutte le tabelle `*_elemento`.
### `gioco_stato` e `gioco_provenienza`
```sql
CREATE TYPE public.gioco_provenienza AS ENUM (
'GRATUITO',
'ACQUISTATO',
'IN_ABBONAMENTO',
'PRESO_IN_PRESTITO',
'NON_PIU_POSSEDUTO',
'ALTRO'
);
CREATE TYPE public.gioco_stato AS ENUM (
'DA_INIZIARE',
'INIZIATO',
'FINITO',
'COMPLETATO',
'NON_APPLICABILE'
);
```
Gli stati e le provenienze degli elementi sono state realizzate tramite _ENUM_ contenenti tutte le possibili opzioni selezionabili dall'utente.
### `gioco_elemento`
```sql
CREATE TABLE public.gioco_elemento (
id bigint DEFAULT nextval('public.elemento_id_seq'::regclass) NOT NULL,
stato public.gioco_stato,
provenienza public.gioco_provenienza,
istanza_di integer NOT NULL,
appartiene_a character varying NOT NULL
);
ALTER TABLE ONLY public.gioco_elemento
ADD CONSTRAINT gioco_elemento_pkey PRIMARY KEY (id);
ALTER TABLE ONLY public.gioco_elemento
ADD CONSTRAINT appartiene_a FOREIGN KEY (appartiene_a) REFERENCES public.utente(username);
ALTER TABLE ONLY public.gioco_elemento
ADD CONSTRAINT istanza_di FOREIGN KEY (istanza_di) REFERENCES public.gioco_edizione(id);
```
Le tabelle degli elementi hanno due colonne `stato` e `provenienza` di tipo `*_stato` e `*_provenienza` rispettivamente: sono gli _ENUM_ creati in precedenza, che impediscono che vengano inseriti valori non consentiti nella tabella.
La colonna `id` invece ha un valore di _DEFAULT_ particolare: `nextval('public.elemento_id_seq'::regclass)`.
Significa che, se non viene specificato un `id` durante un _INSERT_, alla riga verrà assegnato automaticamente il valore corrente della _SEQUENCE_, e il valore della sequenza sarà aumentato, garantendo l'**unicità** degli `id` anche attraverso tabelle diverse.
<!--TODO: qui dovremmo scrivere qualcosa sui trigger... quando sono finiti.-->
### `libro_edizione`
<!--TODO: è pronto il check dell'ISBN?-->
### `utente` ### `utente`
```sql ```sql
@ -59,6 +219,9 @@ CREATE TABLE public.utente (
film_elementi_posseduti integer DEFAULT 0 NOT NULL, film_elementi_posseduti integer DEFAULT 0 NOT NULL,
gioco_elementi_posseduti integer DEFAULT 0 NOT NULL gioco_elementi_posseduti integer DEFAULT 0 NOT NULL
); );
ALTER TABLE ONLY public.utente
ADD CONSTRAINT username PRIMARY KEY (username);
``` ```
La password, essendo un [hash](https://it.wikipedia.org/wiki/Funzione_di_hash), è rappresentata come un dato binario (_bytea_). La password, essendo un [hash](https://it.wikipedia.org/wiki/Funzione_di_hash), è rappresentata come un dato binario (_bytea_).

View file

@ -122,24 +122,6 @@ CREATE TYPE public.libro_stato AS ENUM (
ALTER TYPE public.libro_stato OWNER TO cookie; ALTER TYPE public.libro_stato OWNER TO cookie;
--
-- Name: adegua_isbn(); Type: FUNCTION; Schema: public; Owner: cookie
--
CREATE FUNCTION public.adegua_isbn() RETURNS trigger
LANGUAGE plpgsql
AS $$DECLARE
isbn VARCHAR;
BEGIN
if NEW.isbn LIKE '%x' then
new.isbn:= CONCAT(substring(new.isbn, 1, 12),'X');
end if;
return new;
END$$;
ALTER FUNCTION public.adegua_isbn() OWNER TO cookie;
-- --
-- Name: is_numeric(character varying); Type: FUNCTION; Schema: public; Owner: cookie -- Name: is_numeric(character varying); Type: FUNCTION; Schema: public; Owner: cookie
-- --
@ -164,9 +146,16 @@ ALTER FUNCTION public.is_numeric(text character varying) OWNER TO cookie;
CREATE FUNCTION public.update_n_audiolibri() RETURNS trigger CREATE FUNCTION public.update_n_audiolibri() RETURNS trigger
LANGUAGE plpgsql LANGUAGE plpgsql
AS $$BEGIN AS $$BEGIN
IF (TG_OP = 'DELETE') THEN
UPDATE utente
SET new.audiolibro_elementi_posseduti = old.audiolibro_elementi_posseduti - 1
WHERE utente.id = new.audiolibro_elemento.appartiene_a;
ELSIF (TG_OP = 'INSERT') THEN
UPDATE utente UPDATE utente
SET new.audiolibro_elementi_posseduti = old.audiolibro_elementi_posseduti + 1 SET new.audiolibro_elementi_posseduti = old.audiolibro_elementi_posseduti + 1
WHERE utente.id = new.audiolibro_elemento.appartiene_a; WHERE utente.id = new.audiolibro_elemento.appartiene_a;
END IF;
RETURN NEW;
END;$$; END;$$;
@ -179,9 +168,16 @@ ALTER FUNCTION public.update_n_audiolibri() OWNER TO cookie;
CREATE FUNCTION public.update_n_film() RETURNS trigger CREATE FUNCTION public.update_n_film() RETURNS trigger
LANGUAGE plpgsql LANGUAGE plpgsql
AS $$BEGIN AS $$BEGIN
IF (TG_OP = 'DELETE') THEN
UPDATE utente
SET new.film_elementi_posseduti = old.film_elementi_posseduti - 1
WHERE utente.id = new.film_elemento.appartiene_a;
ELSIF (TG_OP = 'INSERT') THEN
UPDATE utente UPDATE utente
SET new.film_elementi_posseduti = old.film_elementi_posseduti + 1 SET new.film_elementi_posseduti = old.film_elementi_posseduti + 1
WHERE utente.id = new.film_elemento.appartiene_a; WHERE utente.id = new.film_elemento.appartiene_a;
END IF;
RETURN NEW;
END;$$; END;$$;
@ -194,9 +190,16 @@ ALTER FUNCTION public.update_n_film() OWNER TO cookie;
CREATE FUNCTION public.update_n_giochi() RETURNS trigger CREATE FUNCTION public.update_n_giochi() RETURNS trigger
LANGUAGE plpgsql LANGUAGE plpgsql
AS $$BEGIN AS $$BEGIN
IF (TG_OP = 'DELETE') THEN
UPDATE utente
SET new.gioco_elementi_posseduti = old.gioco_elementi_posseduti - 1
WHERE utente.id = new.gioco_elemento.appartiene_a;
ELSIF (TG_OP = 'INSERT') THEN
UPDATE utente UPDATE utente
SET new.gioco_elementi_posseduti = old.gioco_elementi_posseduti + 1 SET new.gioco_elementi_posseduti = old.gioco_elementi_posseduti + 1
WHERE utente.id = new.gioco_elemento.appartiene_a; WHERE utente.id = new.gioco_elemento.appartiene_a;
END IF;
RETURN NEW;
END;$$; END;$$;
@ -209,9 +212,16 @@ ALTER FUNCTION public.update_n_giochi() OWNER TO cookie;
CREATE FUNCTION public.update_n_libri() RETURNS trigger CREATE FUNCTION public.update_n_libri() RETURNS trigger
LANGUAGE plpgsql LANGUAGE plpgsql
AS $$BEGIN AS $$BEGIN
IF (TG_OP = 'DELETE') THEN
UPDATE utente
SET new.libro_elementi_posseduti = old.libro_elementi_posseduti - 1
WHERE utente.id = new.libro_elemento.appartiene_a;
ELSIF (TG_OP = 'INSERT') THEN
UPDATE utente UPDATE utente
SET new.libro_elementi_posseduti = old.libro_elementi_posseduti + 1 SET new.libro_elementi_posseduti = old.libro_elementi_posseduti + 1
WHERE utente.id = new.libro_elemento.appartiene_a; WHERE utente.username = new.libro_elemento.appartiene_a;
END IF;
RETURN NEW;
END;$$; END;$$;
@ -817,6 +827,7 @@ CREATE TABLE public.libro_edizione (
pagine integer, pagine integer,
copertina bytea, copertina bytea,
relativa_a integer, relativa_a integer,
CONSTRAINT libro_edizione_isbn_check CHECK ((public.is_numeric(("substring"((isbn)::text, 1, 12))::character varying) AND (public.is_numeric(("right"((isbn)::text, 1))::character varying) OR ("right"((isbn)::text, 1) ~~ '%X'::text)))),
CONSTRAINT libro_edizione_pagine_check CHECK ((pagine >= 0)) CONSTRAINT libro_edizione_pagine_check CHECK ((pagine >= 0))
); );
@ -1188,6 +1199,9 @@ COPY public.libro_editore (parte_isbn, nome) FROM stdin;
-- --
COPY public.libro_edizione (isbn, titolo_edizione, pagine, copertina, relativa_a) FROM stdin; COPY public.libro_edizione (isbn, titolo_edizione, pagine, copertina, relativa_a) FROM stdin;
1234567890123 abcd \N \N \N
1111122222333 efgh 111 \N \N
3210987654321 bababa \N \N \N
\. \.
@ -1228,6 +1242,8 @@ COPY public.libro_scritto_da (id_libro, id_autore) FROM stdin;
-- --
COPY public.utente (username, password, email, is_admin, is_banned, libro_elementi_posseduti, audiolibro_elementi_posseduti, film_elementi_posseduti, gioco_elementi_posseduti) FROM stdin; COPY public.utente (username, password, email, is_admin, is_banned, libro_elementi_posseduti, audiolibro_elementi_posseduti, film_elementi_posseduti, gioco_elementi_posseduti) FROM stdin;
sas \\x737573 ciao@steffo.eu t f 0 0 0 0
sis \\x737573 banana@steffo.eu f f 0 0 0 0
\. \.
@ -1564,14 +1580,6 @@ ALTER TABLE ONLY public.libro_editore
ADD CONSTRAINT libro_editore_pkey PRIMARY KEY (parte_isbn); ADD CONSTRAINT libro_editore_pkey PRIMARY KEY (parte_isbn);
--
-- Name: libro_edizione libro_edizione_isbn_check; Type: CHECK CONSTRAINT; Schema: public; Owner: cookie
--
ALTER TABLE public.libro_edizione
ADD CONSTRAINT libro_edizione_isbn_check CHECK ((public.is_numeric(("substring"((isbn)::text, 1, 12))::character varying) AND (public.is_numeric(("right"((isbn)::text, 1))::character varying) OR ("right"((isbn)::text, 1) ~~ '%X'::text)))) NOT VALID;
-- --
-- Name: libro_elemento libro_elemento_pkey; Type: CONSTRAINT; Schema: public; Owner: cookie -- Name: libro_elemento libro_elemento_pkey; Type: CONSTRAINT; Schema: public; Owner: cookie
-- --
@ -1629,19 +1637,10 @@ ALTER TABLE ONLY public.utente
-- --
-- Name: film_correlazioni EIDR_1; Type: FK CONSTRAINT; Schema: public; Owner: cookie -- Name: libro_elemento numero_libri_trigger; Type: TRIGGER; Schema: public; Owner: cookie
-- --
ALTER TABLE ONLY public.film_correlazioni CREATE TRIGGER numero_libri_trigger AFTER INSERT ON public.libro_elemento FOR EACH ROW EXECUTE PROCEDURE public.update_n_libri();
ADD CONSTRAINT "EIDR_1" FOREIGN KEY (eidr_1) REFERENCES public.film(eidr);
--
-- Name: film_correlazioni EIDR_2; Type: FK CONSTRAINT; Schema: public; Owner: cookie
--
ALTER TABLE ONLY public.film_correlazioni
ADD CONSTRAINT "EIDR_2" FOREIGN KEY (eidr_2) REFERENCES public.film(eidr);
-- --
@ -1708,6 +1707,22 @@ ALTER TABLE ONLY public.film_vi_ha_preso_parte
ADD CONSTRAINT eidr FOREIGN KEY (eidr) REFERENCES public.film(eidr); ADD CONSTRAINT eidr FOREIGN KEY (eidr) REFERENCES public.film(eidr);
--
-- Name: film_correlazioni eidr_1; Type: FK CONSTRAINT; Schema: public; Owner: cookie
--
ALTER TABLE ONLY public.film_correlazioni
ADD CONSTRAINT eidr_1 FOREIGN KEY (eidr_1) REFERENCES public.film(eidr);
--
-- Name: film_correlazioni eidr_2; Type: FK CONSTRAINT; Schema: public; Owner: cookie
--
ALTER TABLE ONLY public.film_correlazioni
ADD CONSTRAINT eidr_2 FOREIGN KEY (eidr_2) REFERENCES public.film(eidr);
-- --
-- Name: film_recensione id; Type: FK CONSTRAINT; Schema: public; Owner: cookie -- Name: film_recensione id; Type: FK CONSTRAINT; Schema: public; Owner: cookie
-- --