Avant d’utiliser PostgreSQL, assurons-nous de consolider nos fondations en abordant la théorie générale de bases de données. Vous n’aurez besoin d’entrer aucun des codes en exemple; ils ne servent qu’à des fins d’illustration.
Objectif de cette leçon: Comprendre les concepts fondamentaux des Bases de Données
Une base de données consiste en un ensemble organisé de données destinées à une ou plusieurs utilisations, généralement sous format numérique. - Wikipedia
Un Système de Gestion de Base de Données (SGBD) se compose d’un logiciel qui exploite des bases de données, gère le stockage, l’accès, la sécurité, la sauvegarde/restauration et autres fonctionnalités. - Wikipedia
Dans les bases de données relationnelles et à plat, une table est un jeu de données (valeurs) qui est organisé en utilisant un modèle de colonnes verticales (qui sont identifiées par leur nom) et de lignes horizontales. Une table contient un nombre spécifique de colonnes mais elle peut avoir autant de lignes qu’il faut. Chaque ligne est identifiée par des valeurs qui apparaissent dans un colonne particulière qui est identifiée comme une clef. - Wikipedia
id | name | age
----+-------+-----
1 | Tim | 20
2 | Horst | 88
(2 rows)
Dans une base de données SQL, une table est aussi appelée relation.
Une colonne est un jeu de valeur d’un type particulier, pour une valeur par ligne. Les colonnes fournissent la structure qui permet de composer les lignes. Le terme champ est souvent utilisé pour nommer la colonne même si certains considère qu’il est plus correct d’employer le mot champ (ou valeur de champ) pour se référer à un élément spécifique qui est présent à l’intersection entre une ligne et une colonne. - Wikipedia
Une colonne:
| name |
+-------+
| Tim |
| Horst |
Un champ:
| Horst |
Un enregistrement est une information stockée dans une ligne d’une table. Chaque enregistrement aura un champ pour chacune des colonnes de la table.
2 | Horst | 88 <-- one record
Les Types de données restreignent le genre d’informations pouvant être stockées dans une colonne. - Tim and Horst
Il existe différents type de données. Voyons les plus fréquents:
Texte ou String - pour stocker des données de texte libre
Entier ou Integer - pour stocker des nombres entiers
Réel ou Real - pour stocker les nombres décimaux
Date - pour stocker l’anniversaire de Horst afin que personne n’oublie
Booléen ou Boolean - pour stocker des valeurs vrai/faux
Dans une base de données, vous pouvez autoriser de ne rien stocker dans un champ. S’il n’y a rien dans un champ, alors le contenu de ce champ est référencé comme une valeur ‘null’:
insert into person (age) values (40);
select * from person;
Résultat:
id | name | age
----+-------+-----
1 | Tim | 20
2 | Horst | 88
4 | | 40 <-- null for name
(3 rows)
Il existe beaucoup plus de types de données utilisables - Lisez le manuel de PostgreSQL!
Etudions un cas simple pour voir comment est construite une base de données. Nous allons créer une base de données adresse.
Ecrivez les propriétés qui composent une adresse et que vous voulez stocker dans la base.
Les propriétés qui décrivent une adresse sont les colonnes. Le type d’information stockée dans chaque colonne est un type de données. Dans la section qui suit, nous analyserons notre table d’adresse pour voir comment l’améliorer !
Le processus de création d’une base de données implique la création d’un modèle basé sur le monde réel: prendre les concepts du monde réel et les représenter dans une base de données en tant qu’entités.
Une des idées principales dans une base de données consiste à éviter la duplication/redondance de données. Le processus de suppression de la redondance dans une base de données s’appelle Normalisation.
La normalisation est une méthode systémique qui permet de s’assurer que la structure de base de données est adaptée aux requêtes génériques et qu’elle est débarassée de certaines caractéristiques non désirées liées aux anomalies lors d’insertion, de mise à jour ou de suppression qui peuvent engendrer une perte d’intégrité des données. - Wikipedia
Il existe différents types de normalisation.
Examinons cet exemple tout simple:
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)
Imaginez que vous avez beaucoup d’amis avec le même nom de rue ou de ville. Chaque fois que ces données sont dupliquées, elles consomment de l’espace. Pire encore, si un nom de ville change, vous devrez effectuer beaucoup de travail pour mettre à jour votre base de données.
Reconstruisez la structure théorique de la table people ci-dessus pour réduire la duplication d’information et normaliser la structure de données.
Vous pouvez en lire plus sur la normalisation des bases de données ici
Un index de base de données est un lot de données destiné à accélérer les opérations de recherche de données. - Wikipedia
Imaginez que vous lisez un bouquin et cherchez la définition d’un concept - et que le bouquin n’a pas d’index! Vous devrez lire le livre depuis le début et page après page jusqu’à ce que vous trouviez l’information recherchée. L’index à la fin du livre vous permet d’aller directement à la page contenant l’information pertinente.
create index person_name_idx on people (name);
Maintenant, les recherches sur le nom seront plus rapides:
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)
Une séquence est un générateur de nombre unique. Il est normalement utilisé pour créer un identifiant unique pour une colonne d’une table.
Dans cet exemple, id est une séquence - le nombre est incrémenté chaque fois qu’un nouvel enregistrement est ajouté à la table:
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
Dans une base de données normalisée, vous disposez de plusieurs relations (tables). Le diagramme entités-association (ERD) est utilisé pour définir les dépendances logiques entre les relations. Voici notre modèle non normalisé de la table people de notre leçon précédente:
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)
Avec un peu d’effort, nous pouvons la séparer en deux tables en supprimant le besoin de répéter le nom de la rue pour les individus qui vivent dans la même rue.
select * from streets;
id | name
----+--------------
1 | Plein Street
(1 row)
et:
select * from people;
id | name | house_no | street_id | phone_no
----+--------------+----------+-----------+-------------
1 | Horst Duster | 4 | 1 | 072 121 122
(1 row)
Nous pouvons ensuite lier les deux tables en utilisant les clefs ‘keys’ streets.id et people.streets_id.
Si nous dessinons un Diagramme entité-association pour ces tables, il devrait ressembler à ce qui suit:
Le diagramme entité-association nous aide à exprimer les relations ‘un à plusieurs’. Dans ce cas, le symbole de flèche nous montre qu’une rue peut avoir plusieurs personnes qui vivent dedans.
Notre modèle de table people a encore des problèmes de normalisation. Essayez de les identifier et de les corriger à l’aide d’un diagramme entité-association.
Une contrainte de base de données est utilisée pour s’assurer que les données d’une relation correspondent à la vision du modélisateur sur le stockage de l’information. Par exemple, un contrainte sur le code postal permet de s’assurer que le nombre sera bien compris entre 1000 et 9999.
Une clef primaire est une ou plusieurs valeurs de champ qui identifie un enregistrement unique. En générale, la clef primaire est appelé identifiant et elle correspond à une séquence.
Une clef étrangère est utilisée pour se référer à un enregistrement unique d’une autre table (en utilisant la clef primaire de l’autre table).
Dans le diagramme entité-association, le lien entre les tables est basé sur la liaison entre les clefs étrangères et les clefs primaires.
Si vous regardez notre exemple sur les personnes, la définition de la table montre que la colonne street est une clef étrangère qui référence la clef primaire de la table des rues:
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)
Lorsque vous ajoutez, modifiez ou supprimez une donnée dans une base de données, il est toujours important de laisser la base de données dans un état consistant si quelquechose tourne mal. La plupart des bases de données fournissent un mécanisme de transaction. Les transactions vous permettent de créer une position de retour sur laquelle on peut revenir si les modifications ne se sont pas déroulées comme prévu.
Prenons un scénario ou vous avez mis en place un système de comptabilité. Vous devez transférer des fonds d’un compte à l’autre. Les étapes se dérouleront de la manière suivante:
Supprimer R20 du compte Joe.
Ajouter R20 au compte Anne.
Si quelquechose se passe mal lors du processus (ex: une panne de courant), la transaction sera annulée.
Les bases de données vous permettent de gérer vos données de manière structurée en utilisant des structures de code simple.
Maintenant que nous avons jeté un coup d’oeil sur le fonctionnement des bases de données, créons une nouvelle base pour mettre en pratique ce que nous avons appris.