Les bases de données relationnelles
Pour ce support de formation, j'ai choisi de reprendre l'exemple développé dans le support pour QField. Vous pouvez y jeter un oeil si vous voulez mieux comprendre l'exemple utilisé sinon, on peut y aller. J'ai aussi choisi d'utiliser des technologies open-source et de créer la base avec SQLite, qui est un conteneur SQL léger (toute la base est contenue dans un seul fichier) et peut être consultée à travers différentes interfaces graphiques. C'est un peu technique et peut-être pas toujours fun, mais ça vous aidera à mettre en place une base de données fonctionnelle et surtout pérenne.
Bon, allons-y. Avant de créer quoi que ce soit, il faut comprendre ce qu'on veut faire et pourquoi. Parce que construire une base de données sans réfléchir à sa structure, c'est un peu comme partir en prospection sans préparer son matériel : ça peut marcher, mais c'est souvent douloureux et on finit avec des chaussettes mouillées et des données qui ressemblent à rien. :hiking_boot:
C'est quoi une base de données relationnelle ?
Une base de données, c'est une façon d'organiser des informations pour les stocker, les retrouver et les exploiter facilement. Il en existe plein de types, mais ici, on parle de bases de données relationnelles. L'idée centrale, c'est simple : on découpe l'information en tables (comme des tableurs), et on relie ces tables entre elles. C'est le modèle inventé par Edgar Codd dans les années 70 et c'est encore aujourd'hui le plus utilisé dans le monde.
Pourquoi "relationnel" ? Parce que les tables sont liées par des relations. Un objet archéologique appartient à une zone, une structure à une zone, etc. Plutôt que de répéter "Zone A1" à chaque ligne du tableau, on stocke l'information une seule fois et on y fait référence. C'est plus propre, plus cohérent, et bien plus puissant pour interroger les données. :unicorn:
Codd définit aussi une notion fondamentale (à mon sens en tout cas) pour les bases de données relationnelles, les contraintes
. Ce sont des règles qui vont bloquer certains comportements ou pratiques. Malheureusement, ça ne fait pas tomber le patriarcat, en revanche, ça évite d'enregistrer de la
!
Les contraintes peuvent prendre plusieurs formes, comme, par exemple, limiter la colonne d'un tableur à un seul type de données (comme du texte ou des nombres), interdire des enregistrement vides, forcer à avoir des noms uniques et éviter les doublons, etc. Leur domaine est assez large... 
Ne confondez pas "base de données" et "tableur". Excel ou Calc peuvent parfois dépanner pour quelques listes, mais dès que les données se compliquent (plusieurs types d'objets, des liens entre eux, plusieurs personnes qui saisissent en même temps...), c'est la croix
et la bannière
. La base de données relationnelle, c'est l'outil fait pour ça.
Les notions fondamentales
Modèle de données - SGBD - interfaces
Il faut bien distinguer trois notions que nous abordons dans ce support, car on les confond souvent, et cette confusion est source de beaucoup de douleur :face_with_head_bandage: :
Le modèle de données, c'est la conception abstraite de votre base : quelles tables, quels champs, quelles relations entre elles. C'est le plan de l'architecte. Il existe indépendamment de tout logiciel. On peut le dessiner sur une nappe en papier, dans Draw.io ou dans sa tête. Ce qu'on fait dans ce chapitre, c'est précisément ça : apprendre à concevoir un modèle de données cohérent.
Le SGBD (Système de Gestion de Base de Données, ou DBMS en anglais), c'est le moteur logiciel qui stocke, organise et interroge vos données. Il "fait tourner" le modèle. Il en existe plein : SQLite, PostgreSQL, MariaDB, MySQL, Oracle... Dans ce support, on utilise SQLite (et son extension spatiale SpatiaLite). C'est le SGBD qui parle SQL, qui gère les contraintes, les clés, les jointures — bref, qui fait le boulot ingrat dans l'ombre. :gear:
L'interface, c'est le logiciel avec lequel vous interagissez pour consulter, saisir ou visualiser les données. Ce peut être un logiciel dédié comme DB Browser for SQLite, un SIG comme QGIS, une application mobile comme QField, ou une interface web qu'on construit soi-même avec SQLPage ou Streamlit. L'interface parle à votre SGBD, qui lui parle au fichier ou au serveur où sont stockées les données.
Vous (l'humain.e) ──► Interface ──► SGBD ──► Données
(QField, (SQLite, (le fichier .gpkg
QGIS, PostgreSQL) ou .sqlite)
SQLPage...)
Pourquoi cette distinction est importante ? Parce que le modèle de données est (relativement) stable, le SGBD peut changer selon les besoins du projet (SQLite pour du terrain léger, PostgreSQL pour un serveur mutualisé), et les interfaces peuvent être multiples — on peut très bien consulter la même base via QGIS et via une appli web en même temps. Ne pas mélanger ces trois niveaux vous évitera bien des confusions quand vous lirez de la documentation ou que vous chercherez de l'aide. 
Les tables
Une table, c'est la structure fondamentale. Elle ressemble à un tableau : des colonnes (les champs ou fields) et des lignes (les enregistrements ou records). Chaque table représente un type d'entité bien défini : les structures, les mobiliers, les auteurices, etc.
La règle d'or : une table = un type de truc (ou de machin, je ne fais pas de hiérarchie). On ne mélange pas les structures et les mobiliers dans la même table.
C'est comme quand à l'école, on vous disait qu'on ne multiplie par les choux par les tomates (même si au final, on peut donner le total en fruits et légumes et que c'est comme ça qu'on a sa dose de 5 par jour (et la pizza ça compte (avec un point par ingrédient !))).
Les champs
Un champ, c'est une colonne de la table. Il a un nom et un type. Le type, c'est ce qu'il peut contenir :
| Type | Ce que ça contient | Exemple |
|---|---|---|
TEXT |
Du texte libre | "Céramique moche" |
INTEGER |
Un nombre entier | 42 |
REAL |
Un nombre décimal | 3.14 |
BLOB |
Des données binaires | Une géométrie spatiale |
NULL |
Rien du tout | L'absence de valeur |
En SQLite (qu'on verra dans le prochain chapitre), le système de types est assez souple, mais dans d'autres SGBD comme PostgreSQL, c'est plus strict. Prenez l'habitude de bien choisir vos types dès le départ, ça vous évitera des surprises.
Un champ peut aussi avoir des contraintes :
- NOT NULL : le champ doit obligatoirement être rempli
- UNIQUE : deux enregistrements ne peuvent pas avoir la même valeur dans ce champ
- DEFAULT : une valeur par défaut si on ne renseigne rien
Les enregistrements
Un enregistrement, c'est une ligne de la table. C'est l'instance concrète d'une entité : tel mobilier précis, telle structure précise. Chaque enregistrement est unique, distingué par sa clé primaire (on en parle juste après). 
Les clés : primaires et étrangères
C'est là que ça devient intéressant. Les clés, c'est le mécanisme qui permet de relier les tables entre elles.
La clé primaire (PK — Primary Key)
Chaque enregistrement dans une table doit être identifiable de manière unique. C'est le rôle de la clé primaire. En pratique, on utilise souvent un entier qui s'incrémente automatiquement (1, 2, 3, 4...) : c'est simple, efficace, et ça ne demande aucune imagination (oui, la vie est parfois un peu triste, je sais). :brain:
Par exemple, dans notre table de zones de prospection, chaque zone a un id qui est sa clé primaire. On ne mettra jamais deux zones avec le même id. Le SGBD s'en assure tout seul.
T_zones
| id | nom | priorité | fait |
|---|---|---|---|
| 1 | A1 | 1 | 0 |
| 2 | A2 | 2 | 1 |
| 3 | B1 | 1 | 0 |
La clé étrangère (FK — Foreign Key)
Si la clé primaire identifie un enregistrement dans sa table, la clé étrangère est une référence vers la clé primaire d'une autre table. C'est le lien concret entre deux tables.
Par exemple, dans T_mobilier, le champ zone ne contient pas le nom de la zone, mais son id dans T_zones. Si un mobilier est dans la zone "A1" (qui a l'id = 1), on stockera 1 dans le champ zone de ce mobilier.
T_mobilier
| id | identifiant | zone | nature |
|---|---|---|---|
| 1 | MOB-001 | 1 | 3 |
| 2 | MOB-002 | 1 | 1 |
| 3 | MOB-003 | 3 | 2 |
-> zone = 1 -> T_zones.id = 1 -> "A1"
Quand on voudra afficher les données de façon lisible, on fera une jointure (un JOIN en SQL) pour aller chercher le nom de la zone depuis T_zones. On verra ça plus en détail dans le chapitre SQLite. 
Pourquoi le lien est sur la clé primaire et pas sur le mot que l'on choisit directement ? Évidemment, plusieurs raisons, mais l'une des plus logique c'est déjà qu'un lien associe une entité dans son ensemble (la ligne entière du tableur) et pas une seule variable (une seule case de la ligne). Ensuite, la clé primaire est automatique et ne correspond pas à quelque chose d'interprété, c'est donc potentiellement le seul élément stable d'une entité (tout le reste peut être modifié un jour). En revanche, comme je viens de l'écrire (enfin plutôt comme vous venez de le lire, parce que je suis peut-être déjà mort depuis des semaines dans mon bureau quand vous lisez ce support et alors ça fait peut-être super longtemps que j'ai écrit tout ça
), on peut afficher n'importe quelle champ (case) correspondant à la clé primaire sélectionnée, c'est l'utilité de la jointure.
Les relations entre tables
On distingue trois types de relations dans un modèle relationnel :
1 à n (un à plusieurs)
C'est la plus courante. Un enregistrement dans la table A est lié à plusieurs enregistrements dans la table B. Mais chaque enregistrement de B n'est lié qu'à un seul enregistrement de A.
Exemple : une zone peut contenir plusieurs mobiliers, mais un mobilier n'appartient qu'à une seule zone. C'est une relation de 1 à n entre T_zones et T_mobilier.
En pratique, c'est la clé étrangère dans la table "n" (ici T_mobilier) qui pointe vers la clé primaire de la table "1" (ici T_zones).
1 à 1 (un à un)
Un enregistrement dans A est lié à exactement un enregistrement dans B, et vice-versa. C'est assez rare en pratique, souvent signe qu'on peut fusionner les deux tables. Mais ça peut servir pour séparer des données techniques des données "métier", par exemple.
n à n (plusieurs à plusieurs)
Plusieurs enregistrements dans A sont liés à plusieurs enregistrements dans B. Par exemple, un mobilier peut avoir été photographié par plusieurs personnes, et une personne peut avoir photographié plusieurs mobiliers. 
En pratique, on ne peut pas représenter une relation n à n directement avec des clés étrangères. On crée une table de jonction (ou table d'association) qui contient les clés étrangères des deux tables concernées. C'est un peu plus compliqué, mais pour notre base de prospection, on n'en aura pas besoin — inutile de s'y attarder pour l'instant. 
Les listes de valeurs
Maintenant qu'on sait ce que c'est qu'une clé étrangère, on peut parler des listes de valeurs (ou tables de référence). C'est simplement des petites tables qui contiennent les options possibles pour un champ donné. Plutôt que de taper "Céramique" à la main à chaque fois (avec toutes les fautes de frappe que ça implique), on stocke toutes les natures de mobilier dans une table L_natures_mob et on y fait référence par un identifiant.
C'est le principe des menus déroulants dans les formulaires de saisie. Et ça permet aussi de gérer des vocabulaires contrôlés, des thésaurus normalisés comme PACTOLS en archéologie. Vous pouvez même ajouter un champ definition pour documenter ce que chaque terme signifie — ça peut sauver la mise quand on reprend une base après quelques années de thèse chaotique (ou une soirée au bar "non, juste une bière je rentre finir mon bastract"...). 
L_natures_mob
| id | nature_mob | definition |
|---|---|---|
| 1 | Céramique | Fragments de poterie |
| 2 | Métal | Objets ou scories métalliques |
| 3 | Verre | Fragments de verre |
Dans nos supports, les tables de listes de valeurs sont préfixées L_ et les tables de données de terrain sont préfixées T_. C'est une convention de nommage, rien d'obligatoire techniquement, mais ça aide vraiment à s'y retrouver quand la base grossit. 
Donc ici, plus concrètement que précédemment (bien écrit tout ça...), on va revenir sur le fait que ce qui va être lié, c'est la clé primaire et pas le terme lui-même. L'avantage est très parlant dans le cas d'une liste de valeurs : le terme lui-même peut évoluer (on se rend compte que le terme qu'on a choisi au début n'est pas le plus pertinent) et si on le change, on conserve notre lien puisqu'il a été fait sur la clé primaire qui, elle, ne bouge pas. De plus, si on a une base multilingue (avec une colonne
nature_mob_fret une autrenature_mob_en), on peut choisir d'afficher le champ en français ou en anglais dans l'interface. Comme c'est la clé primaire qui est référencée, bah qu'on affiche une langue ou l'autre, ça n'impacte pas les données ;-) !
La normalisation : ne pas se répéter
La normalisation, c'est un ensemble de règles (des "formes normales") qui permettent d'éviter la redondance dans une base de données. L'idée de base : chaque information doit être stockée une seule fois. Si on stocke le nom d'une zone dans chaque enregistrement de mobilier, on crée de la redondance — et si on renomme la zone un jour, il faudra corriger des dizaines de lignes au lieu d'une seule.
Ces règles ont été formalisées sous forme de formes normales (NF — Normal Forms), dont voici les trois premières. On les présente ici d'abord sous forme de principes concrets, puis on donne leur définition formelle :
- Un champ = une information : pas de "Céramique, Métal, Verre" dans le même champ. Si un mobilier peut avoir plusieurs natures, c'est une relation n à n qu'il faut modéliser proprement.
- Pas de colonnes calculées : si on peut calculer une valeur depuis d'autres colonnes, on ne la stocke pas (l'âge calculé depuis la date de naissance, la superficie calculée depuis la géométrie, etc.). Dans les faits, c'est inutile de conserver ce type d'information et ça occupe de la place pour rien.
- Pas de redondance (taper manuellement plusieurs fois le même mot) : les liens et les listes de valeurs sont là pour ça.
Ces trois principes correspondent aux formes normales définies par Codd :
1NF — Première forme normale : chaque champ ne contient qu'une seule valeur atomique, indivisible. Pas de liste, pas de valeurs multiples dans la même case. C'est le principe n°1 : "Céramique, Métal, Verre" dans un seul champ, c'est une violation de la 1NF. 
2NF — Deuxième forme normale : tous les champs d'une table dépendent entièrement de la clé primaire. Autrement dit, chaque information enregistrée dans une ligne concerne bien l'entité représentée par cette ligne — et rien d'autre. Si on stocke le nom de la zone directement dans la table des mobiliers, c'est une violation de la 2NF : le nom de la zone dépend de la zone, pas du mobilier. C'est pour ça qu'on utilise une clé étrangère plutôt que de répéter l'information.
3NF — Troisième forme normale : aucun champ ne dépend d'un autre champ non-clé (pas de dépendance transitive). Si une valeur peut être déduite ou calculée à partir d'une autre valeur déjà stockée, on ne la stocke pas. C'est le principe n°2 (pas de colonnes calculées) : stocker à la fois la date de naissance et l'âge calculé, c'est une violation de la 3NF — l'âge dépend de la date, pas directement de la clé primaire.
La normalisation, c'est bien, mais l'excès nuit :moon:. Une base trop normalisée devient difficile à interroger et à maintenir. Comme souvent, il faut trouver l'équilibre. Pour une base de prospection ou de fouille, les trois principes ci-dessus suffisent largement.
Le modèle entités-relations (ERD)
Il existe plusieurs façons de représenter les modèles de données, globalement regroupées dans ce qu'on appelle l'UML (pour Unified Modeling Language (langage de modélisation unifié dans la langue de mon voisin de bureau)). C'est un langage graphique utilisé pour les représentations d'organisation ou de gestion des données et il en existe évidemment beaucoup de variations. Vous pouvez aller voir sur internet l'ensemble des types de diagrammes. Ici, on va se concentrer sur un type souvent utilisé pour la mise en place technique des bases de données.
Avant de créer quoi que ce soit dans un logiciel, on dessine un ERD (Entity Relationship Diagram, ou MCD — Modèle Conceptuel de Données — en français, mais bon, tout le monde dit ERD
). C'est un schéma qui représente :
- Les tables (des boîtes avec leurs champs)
- Les relations entre elles (des traits avec des cardinalités)
Ça peut se dessiner sur un bout de papier, dans un logiciel de schéma (genre libreOffice Draw), dans Draw.io, avec Mermaid, peu importe. L'important, c'est de poser la structure sur le papier avant de commencer à cliquer partout. Vous vous éviterez bien des migraines. :face_with_head_bandage:
Les cardinalités (ces petits symboles aux extrémités des traits) indiquent la nature de la relation : 1 d'un côté, n de l'autre pour une relation 1 à n. Certains outils utilisent la notation "pied de corbeau" (crow's foot), avec des petites pattes d'oiseau pour le "plusieurs". Si vous ne connaissez pas, c'est le moment de googler une image, c'est très parlant visuellement. 
Réfléchir à sa base avant de la créer
C'est souvent là que les gens se précipitent et parfois le regrettent
. Avant d'ouvrir un logiciel, posez-vous ces questions :
Qu'est-ce qu'on veut enregistrer ? Listez toutes les entités (les "choses") dont vous avez besoin : mobilier, structures, zones, personnes, photos...
Quelles informations on veut sur chaque entité ? Listez les champs pour chaque table, en pensant aux types de données.
Quels champs peuvent être standardisés ? Ce sont vos futures listes de valeurs.
Comment ces entités sont-elles liées ? Dessinez les relations, avec les cardinalités.
Quelles contraintes faut-il respecter ? Un identifiant unique ? Un champ obligatoire ?
Pour continuer un peu sur ces grandes questions, dans son introduction à la publication des journées d'étude sur les banques de données en archéologie en 1974, Jean-Claude Gardin indique trois grands problèmes à affronter durant la mise en place d'une base (banque) de données. Je vais vous les indiquer en y insérant mon interprétation :
Problèmes théoriques : Quelles données choisir et comment les décrire ? → Ici, il s'agit surtout de bien considérer les données utiles à votre problématique de recherche.
Problèmes techniques : D'un point de vue technique, comment associer les données ? → Bon, dans nos cas, ça concerne surtout la partie logicielle et les choix à faire sur les formats et l'accès à la base de données (en local sur un ordinateur perso, public, sur serveur,...).
Problèmes institutionnels : Qui crée et qui maintient la base de données, pour qui la crée-t-on ? → ce lot de problèmes conditionne beaucoup les choix techniques et les enjeux liés au développement de la base. S'agit-il d'une base personnelle que personne d'autre que vous consultera ou fait-elle partie d'un projet prévu sur plusieurs années avec une équipe internationale ?
À ces trois problèmes, j'en rajoute un quatrième (c'est une initiative personnelle qui repose sur mon expérience, ça n'engage que moi donc ne vous offusquez pas
)
- Les utilisateurices (et j'ai pas envie de parler de problème) : Qui utilise et alimente la base ? Et par quels moyens ? Les interfaces et leur ergonomie sont autant de biais guidant les utilisateurices de la base et il me semble fondamental de les adapter à l'ensemble de la communauté des participant.e.s (institutionnel.le.s et non-institutionnel.le.s et grand public plus généralement). Dans l'idéal , il faut réaliser plusieurs interfaces qui correspondent aux différentes utilisations de votre base de données, qu'il s'agisse de pratiques, de langue et d'habitude culturelle,...
Une base de données n'est jamais parfaite dès le départ. Elle évolue avec le projet, avec les besoins, avec les erreurs qu'on fait et qu'on corrige. L'objectif n'est pas de tout prévoir, mais de construire une base solide et cohérente qu'on pourra faire évoluer sans tout casser. Donc pas de panique si vous vous rendez compte en cours de route que vous avez oublié un champ ou mal pensé une relation.
Et même, j'ajouterai si je peux (mais oui tu peux, bien sûr. Ok merci, alors je reprends la parole), on fait une première base de données avant de commencer à enregistrer les données et donc avant d'être confronté aux données. On a donc des vues idéalisées de nos matériels d'étude et, une fois confronté au matos, nos perspectives et cadre interprétatifs évoluent. Ça implique que la base subira régulièrement des modifications et sera développée de façon itérative avec des tables et des champs qui seront ajoutés, d'autres supprimés, etc.
Autre point très important, une base de données correspond à une vue ou une volonté d'enregistrement, d'analyse et d'exploitation des données. Il n'y a donc pas de modèle unique. Chaque projet, chaque recherche aura besoin de sa propre base de données faite sur mesure. D'une façon générale, je suis totalement contre l'univocité et l'universalité des modèles de bases de données, c'est un truc de fasciste où tout le monde est obligé de penser pareil...
Nommage et implications techniques
Avant de se lancer dans la production de notre base, une petite règle qui a son importance, on évite les accents, espaces et caractères spéciaux dans tout ce qui intervient dans la programmation. En clair, les noms de champs, de table et même de la base ne doivent pas en comporter (et avec une base encodée en UTF-8 c'est encore mieux). Les données elles-même, c'est différent et n'oubliez pas que l'affichage durant l'utilisation de la base, c'est autre chose. C'est-à-dire que côté interface graphique, vous pourrez mettre autant d'accents ou caractères chelous que votre coeur vous dicte ! (genre avec des alias
ou des trucs comme ça)
Aussi, c'est bien de mettre des noms explicites que vous comprenez, pour faire vos liens ou requêtes, ce sera plus facile. Il s'agit de poser des questions à votre base, donc si vous savez facilement comment poser des questions avec les bons mots, c'est quand même pas mal !
Et vous avez vu, les noms de tables que j'ai indiqué sont en mode T pour table, bon là, c'est plutôt moi qui fonctionne comme ça, et ensuite que des caractères en minuscules avec les mots séparés par des _, c'est ce qu'on appelle le snake_case. Ça permet d'avoir des termes lisibles et pas se planter dans la casse en mettant des majuscules au mauvais endroit.
Notre exemple : la base de prospection forestière
Pour illustrer tout ça dans les chapitres suivants, on va travailler sur une base de données conçue pour enregistrer des données de prospection archéologique en forêt. Elle a été pensée dans le cadre de formations en master et en apprentissage à l'Université Paris 1, donc si vous pensez qu'on aurait pu faire autrement, vous avez probablement raison, mais c'est trop tard maintenant. 
Notre base comprend :
- T_zones : les zones de prospection définies avant le terrain (polygones)
- T_mobilier : les objets archéologiques découverts (points)
- T_structures : les structures archéologiques (polygones)
- T_anomalies : les trucs pas encore caractérisés (polygones)
- T_tracking : les traces GPS des balades (lignes)
- L_natures_mob : les types de mobilier
- L_natures_str : les types de structures
- L_contextes : les contextes de découverte particuliers (chablis, taupinière...)
- L_etats : les états de conservation
- L_auteurices : les personnes qui participent aux prospections
- L_priorites : les niveaux de priorité des zones
Les relations sont simples : les zones sont liées au mobilier, aux structures et aux anomalies en 1 à n. Les tables L_ sont des listes de valeurs liées aux tables T_ correspondantes. Pas d'architecture folle, mais une base propre et fonctionnelle. 
L'ERD résultant est le suivant (déjà montré dans le support de formation pour QField mais flemme de ouf de refaire un autre truc en plus) :
Et comme j'écris ce support en markdown, voici le schéma en Mermaid :
Sur le site statique, ça s'affiche pas, mais comme je me suis bien embêté à produire un schéma, je vous invite à aller l'admirer sur la version gitlab-Markdown de cette page.
---
title: ERD de notre base de données en Mermaid
config:
layout: elk
elk:
mergeEdges: true
nodePlacementStrategy: LINEAR_SEGMENTS
---
erDiagram
T_zones {
int id PK
text nom
int priorite FK
boolean fait
text commentaires
}
T_mobilier {
int id PK
geometry geom
text identifiant
int zone FK
int contexte FK
int nature FK
int etat FK
date date_modification
boolean photographie
int auteurice FK
text commentaires
}
T_structures {
int id PK
geometry geom
text identifiant
int zone FK
int nature FK
date date_creation
date date_modification
int auteurice FK
text commentaires
}
T_anomalies {
int id PK
geometry geom
text identifiant
int zone FK
date date_creation
date date_modification
int auteurice FK
text commentaires
}
T_tracking {
int id PK
geometry geom
date date
int auteurice FK
}
T_zones ||--o{ T_mobilier : "zone"
T_zones ||--o{ T_structures : "zone"
T_zones ||--o{ T_anomalies : "zone"
L_priorites
L_natures_mob
L_contextes
L_etats
L_auteurices
L_natures_str
L_auteurices
Pour l'écrire vous-même, la syntaxe c'est (après avoir indiqué mermaid au début de votre bloc de code):
erDiagram
nom de_la_table {
type_de_champ nom_du_champ contraintes
}
nom_de_la_table ||--o{ nom_de_la_table : "champ_lié"
Pour les liens , il sont indiqués par -- au centre, et les extrémités indiquent le type et la cardinalité de la relation :
| left | right | Meaning |
|---|---|---|
| |o | o| | Zero or one |
| || | || | Exactly one |
| }o | o{ | Zero or more |
| }| | |{ | One or more |
Le tableau est repris de la documentation de Mermaid sur les diagrammes ERD. Et pour voir tout le code, vous pouvez faire copier-coller dans bloc et ça devrait recopier le code lui-même. Bon après, j'avoue que pour avoir un truc propre et joli, il faut se battre un peu...
Vous l'aurez compris (enfin j'espère parce que sinon, j'ai vraiment tout raté
), le nerf de la guerre, c'est le MCD. Le plus gros travail de développement d'une base de données, ce n'est pas du tout la partie logicielle, c'est son organisation sur un bout de papier. Dans mon bureau, l'équipement le plus important, c'est le tableau blanc (et la pile de brouillon aussi (et non, je ne t'oublie chère machine à café (fais pas ta victime comme ça non plus
))).
Voilà les fondations théoriques posées. Dans le chapitre suivant, on passe à la pratique et on construit cette base dans SQLite avec SpatiaLite pour les géométries. C'est parti !
Ne confondez pas "base de données" et "tableur". Excel ou Calc peuvent parfois dépanner pour quelques listes, mais dès que les données se compliquent (plusieurs types d'objets, des liens entre eux, plusieurs personnes qui saisissent en même temps...), c'est la croix
et la bannière
. La base de données relationnelle, c'est l'outil fait pour ça.
La normalisation, c'est bien, mais l'excès nuit :moon:. Une base trop normalisée devient difficile à interroger et à maintenir. Comme souvent, il faut trouver l'équilibre. Pour une base de prospection ou de fouille, les trois principes ci-dessus suffisent largement.
))).