Prima di usare PostgreSQL, assicuriati di conoscere la teoria generale dei database. Non avrai bisogno di inserire codice; è solo a scopo illustrativo.
L’obiettivo di questa lezione: Comprendere i concetti fondamentali dei 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
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.
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 |
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
Il tipo di dato limita il tipo di informazioni che possono essere archiviate in una colonna.
Ci sono diversi tipi di dato. Concentrati sui più comuni:
Stringa - per memorizzare dati di testo
Intero - per memorizzare numeri interi
Reale - per memorizzare i numeri decimali
Date - per memorizzare i compleanni
Booleano - per memorizzare i 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 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)
There are many more datatypes you can use - check the PostgreSQL manual!
Usa un semplice caso di studio per vedere come viene costruito un database. Vuoi creare un database di indirizzi.
Annota le proprietà che costituiscono un indirizzo semplice e che memorizzerai nel database.
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
Il processo di creazione di un database comporta la creazione di un modello del mondo reale; prendi concetti del mondo reale e rappresentali nel database come entità.
Una delle idee principali in un database è 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
Esistono diversi tipi di ‘moduli’ 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.
Ridisegnare la tabella sopra per ridurre la duplicazione e normalizzare la struttura dei dati.
You can read more about database normalisation here
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 di testo e di cercare la spiegazione di un concetto - e il libro di testo non ha indice! Dovrai iniziare a leggere dall’inizio e farti strada attraverso l’intero libro fino a trovare le informazioni 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)
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
In un database normalizzato, in genere si hanno molte relazioni (tabelle). Il diagramma entità-relazione (diagramma ER) viene utilizzato per progettare le dipendenze logiche tra le relazioni. Considera la tabella delle persone non normalizzate di prima nella lezione:
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 un piccolo lavoro puoi 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)
Puoi quindi collegare le due tabelle usando le ‘chiavi’ streets.id e people.streets_id.
Se disegnassi un diagramma ER per questi due tabelle, sarebbe simile a questo:
Il diagramma ER ti 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.
Il nostro modello di ‘people’ ha ancora alcuni problemi di normalizzazione: prova a vedere se puoi normalizzarlo ulteriormente e mostrarlo per mezzo di un diagramma ER.
Puoi usare un vincolo di database per garantire 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 stradale è 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)
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.
Fai 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:
Se qualcosa andasse storto durante il processo (ad esempio un’interruzione dell’alimentazione), la transazione verrà ripristinata.
I database ti consentono di gestire i dati in modo strutturato utilizzando semplici strutture di codice.
Ora che hai visto come i database funzionano in teoria, crea un nuovo database per implementare la teoria trattata.