15.1. Lesson: Introduzione ai database

Prima di usare PostgreSQL, assicuriamoci di conoscere la teoria generale dei database. Non avrai bisogno di inserire codice; è solo a scopo illustrativo.

Obiettivo di questa lezione: Comprendere i concetti fondamentali dei database.

15.1.1. Cos’è un database?

Un database consiste in una raccolta organizzata di dati per uno o più usi. - Wikipedia

Un sistema di gestione del database (DBMS) è costituito da un software che gestisce i database, fornendo spazio di archiviazione, accesso, sicurezza, backup e altri servizi. - Wikipedia

15.1.2. Tabelle

Nei database relazionali e nei database di file flat, una tabella è un insieme di elementi di dati (valori) organizzati utilizzando un modello di colonne verticali (identificate dal loro nome) e righe orizzontali. Una tabella ha un numero specificato di colonne, ma può avere un numero qualsiasi di righe. Ogni riga è identificata dai valori che appaiono in un particolare sottoinsieme di colonne che è stato identificato come una chiave univoca. - Wikipedia

 id | name  | age
----+-------+-----
  1 | Tim   |  20
  2 | Horst |  88
(2 rows)

Nei database SQL una tabella è anche nota come relazione.

15.1.3. Colonne / Campi

Una colonna è un insieme di valori di dati di un particolare tipo, uno per ogni riga della tabella. Le colonne forniscono la struttura in base alla quale sono composte le righe. Il termine campo viene spesso utilizzato in modo intercambiabile con colonna, anche se molti ritengono più corretto utilizzare campo (o valore del campo) per fare riferimento in modo specifico al singolo elemento esistente all’intersezione tra una riga e una colonna. - Wikipedia

Una colonna:

| name  |
+-------+
| Tim   |
| Horst |

Un campo:

| Horst |

15.1.4. Record

Un record è l’informazione memorizzata in una riga della tabella. Ogni record avrà un campo per ciascuna delle colonne nella tabella.

2 | Horst |  88  <-- one record

15.1.5. Tipi di dati

Il tipo di dato limita il tipo di informazioni che possono essere archiviate in una colonna. - Tim e Horst

Ci sono diversi tipi di dato. Concentriamoci sui più comuni:

  • String - per memorizzare dati di testo

  • Integer - per memorizzare numeri interi

  • Real - per memorizzare i numeri decimali

  • Data - per memorizzare il compleanno di Horst, in modo che nessuno lo dimentichi.

  • Boolean - per memorizzare valori di vero/falso

Puoi dire al database di permetterti di non memorizzare nulla in un campo. Se non c’è nulla in un campo, allora il contenuto del campo viene definito come un valore null”:

insert into person (age) values (40);

select * from person;

Risultato:

id | name  | age
---+-------+-----
 1 | Tim   |  20
 2 | Horst |  88
 4 |       |  40  <-- null for name
(3 rows)

Ci sono molti altri tipi di dati che puoi usare - controlla il manuale di PostgreSQL `<https://www.postgresql.org/docs/current/datatype.html> `_

15.1.6. Creazione di un database di indirizzi

Usiamo un semplice caso di studio per vedere come viene costruito un database. Vogliamo creare un database di indirizzi.

Try Yourself basic

Scriviamo le proprietà che costituiscono un indirizzo semplice e che vorremo memorizzare nel nostro database.

Struttura indirizzi

Le proprietà di ogni indirizzo sono espresse nelle colonne. Il tipo di informazioni memorizzate in ogni colonna è il suo tipo di dati. Nella prossima sezione analizzerai la nostra tabella degli indirizzi concettuali per vedere come migliorarla!

15.1.7. Teoria dei database

Il processo di creazione di un database implica la creazione di un modello del mondo reale; prendendo i concetti del mondo reale e rappresentandoli nel database come entità.

15.1.8. Normalizzazione

Una delle idee principali in un database è quella di evitare la duplicazione/ridondanza dei dati. Il processo di rimozione della ridondanza da un database è chiamato Normalizzazione.

La normalizzazione è un modo sistematico per garantire che una struttura di database sia adatta per l’interrogazione e priva di determinati e indesiderabili caratteristiche - inserimento, aggiornamento e anomalia di cancellazione - che potrebbero portare a una perdita dell’integrità dei dati. - Wikipedia

Ci sono diversi tipi di «forme» di normalizzazione.

Guarda un semplice esempio:

Table "public.people"

Column    |          Type          |                Modifiers
----------+------------------------+------------------------------------
 id       | integer                | not null default
          |                        | nextval('people_id_seq'::regclass)
          |                        |
 name     | character varying(50)  |
 address  | character varying(200) | not null
 phone_no | character varying      |
Indexes:
 "people_pkey" PRIMARY KEY, btree (id)
select * from people;

id |     name      |           address           |  phone_no
---+---------------+-----------------------------+-------------
 1 | Tim Sutton    | 3 Buirski Plein, Swellendam | 071 123 123
 2 | Horst Duester | 4 Avenue du Roix, Geneva    | 072 121 122
(2 rows)

Immagina di avere molti amici con lo stesso nome di via o città. Ogni volta che questi dati vengono duplicati, viene consumato spazio. Peggio ancora, se il nome di una città cambia, devi fare un sacco di lavoro per aggiornare il tuo database.

15.1.9. Try Yourself basic

Riprogetta la tabella teorica people di cui sopra per ridurre la duplicazione e normalizzare la struttura dei dati.

Puoi leggere di più sulla normalizzazione del database qui <https://en.wikipedia.org/wiki/Database_normalization> _

15.1.10. Indici

Un indice di database è una struttura di dati che migliora la velocità delle operazioni di recupero dei dati su una tabella di database. - Wikipedia

Immagina di leggere un libro e di cercare la spiegazione di un concetto - e il libro non ha un indice! Dovrai iniziare a leggere dalla prima pagina e poi proseguire per tutto il libro fino a trovare l’informazione di cui hai bisogno. L’indice sul retro di un libro ti aiuta a saltare rapidamente alla pagina con le informazioni pertinenti:

create index person_name_idx on people (name);

Ora le ricerche sul nome saranno più veloci:

Table "public.people"

Column   |          Type          |               Modifiers
----------+------------------------+-------------------------------------
 id       | integer                | not null default
          |                        | nextval('people_id_seq'::regclass)
          |                        |
 name     | character varying(50)  |
 address  | character varying(200) | not null
 phone_no | character varying      |
Indexes:
 "people_pkey" PRIMARY KEY, btree (id)
 "person_name_idx" btree (name)

15.1.11. Sequenze

Una sequenza è un generatore di numeri univoco. Viene normalmente utilizzato per creare un identificativo univoco per una colonna in una tabella.

In questo esempio, id è una sequenza: il numero viene incrementato ogni volta che un record viene aggiunto alla tabella:

id |     name     |           address           |  phone_no
---+--------------+-----------------------------+-------------
 1 | Tim Sutton   | 3 Buirski Plein, Swellendam | 071 123 123
 2 | Horst Duster | 4 Avenue du Roix, Geneva    | 072 121 122

15.1.12. Diagramma Entità Relazione

In un database normalizzato, si hanno tipicamente molte relazioni (tabelle). Il diagramma entità-relazione (ER Diagram) è usato per disegnare le dipendenze logiche tra le relazioni. Considera la nostra tabella non normalizzata people nella lezione precedente:

select * from people;

 id |     name     |           address           |  phone_no
----+--------------+-----------------------------+-------------
 1  | Tim Sutton   | 3 Buirski Plein, Swellendam | 071 123 123
 2  | Horst Duster | 4 Avenue du Roix, Geneva    | 072 121 122
(2 rows)

Con poco lavoro possiamo dividerlo in due tabelle, eliminando la necessità di ripetere il nome della via per le persone che vivono nella stessa strada:

select * from streets;

 id |     name
----+--------------
 1  | Plein Street
(1 row)

e:

select * from people;

 id |     name     | house_no | street_id |  phone_no
----+--------------+----------+-----------+-------------
  1 | Horst Duster |        4 |         1 | 072 121 122
(1 row)

Possiamo quindi collegare le due tabelle usando le “chiavi” streets.id e people.streets_id.

Se disegnassimo un diagramma ER per questi due tabelle, sarebbe simile a questo:

../../../_images/er-people-streets.png

Il diagramma ER ci aiuta ad esprimere relazioni “da uno a molti”. In questo caso il simbolo della freccia indica che una strada può avere molte persone che vivono su di essa.

Try Yourself moderate

Il nostro modello “people” ha ancora alcuni problemi di normalizzazione: prova a vedere se puoi normalizzarlo ulteriormente e mostrarlo per mezzo di un diagramma ER.

15.1.13. Vincoli, chiavi primarie e chiavi esterne

Un vincolo di database è utile per assicurare che i dati in una relazione corrispondano a come tali dati devono essere memorizzati. Ad esempio un vincolo sul tuo codice postale potrebbe garantire che il numero sia tra 1000 e 9999.

Una chiave Primaria è uno o più valori di campo che rendono un record univoco. Di solito la chiave primaria è chiamata id ed è una sequenza.

Una chiave Esterna viene utilizzata per fare riferimento a un record univoco su un’altra tabella (utilizzando la chiave primaria di quell’altra tabella).

Nel diagramma ER, il collegamento tra tabelle è normalmente basato su chiavi Esterne che si collegano a chiavi Primarie.

Se guardiamo all’esempio people, la definizione della tabella mostra che la colonna street è una chiave esterna che fa riferimento alla chiave primaria nella tabella streets:

Table "public.people"

 Column    |         Type          |  Modifiers
-----------+-----------------------+--------------------------------------
 id        | integer               | not null default
           |                       | nextval('people_id_seq'::regclass)
 name      | character varying(50) |
 house_no  | integer               | not null
 street_id | integer               | not null
 phone_no  | character varying     |
Indexes:
"people_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
"people_street_id_fkey" FOREIGN KEY (street_id) REFERENCES streets(id)

15.1.14. Transazioni

Quando aggiungi, modifichi o elimini dati in un database, è sempre importante che il database sia lasciato in buono stato. La maggior parte dei database fornisce una funzionalità chiamata supporto per le transazioni. Le transazioni consentono di creare una posizione di rollback a cui è possibile tornare se le modifiche al database non sono state eseguite come pianificato.

Considera uno scenario in cui hai un sistema di contabilità. Devi trasferire fondi da un account e aggiungerli a un altro. La sequenza di passaggi sarebbe come questa:

  • remove R20 from Joe

  • add R20 to Anne

Se qualcosa andasse storto durante il processo (ad esempio un’interruzione dell’alimentazione), la transazione verrà ripristinata.

15.1.15. In Conclusion

I database ti consentono di gestire i dati in modo strutturato utilizzando semplici strutture di codice.

15.1.16. What’s Next?

Ora che abbiamo visto come i database funzionano in teoria, creiamo un nuovo database per implementare la teoria trattata.