Table des matières

Introduction

Cette série d'articles n'a pas pour ambition de remplacer un manuel de référence SQL, ni un bon bouquin détaillant toute la démarche menant d'un problème à résoudre à sa représentation sous la forme d'une base de données et des requêtes permettant d'obtenir les résultats recherchés. Pour cela, les lecteurs intéressés pourront consulter les différents ouvrages que nous citons à la fin de cet article.

Notre but est de faciliter la compréhension de l'utilisation des bases de données relationnelles : nous gommerons donc volontairement tous les aspects trop théoriques tout en étant conscient que ceux-ci sont nécessaires à une connaissance en profondeur des mécanismes sous-jacents des bases de données relationnelles.

Notamment, toute la partie de l'analyse conceptuelle des données et des traitements, l'étude des dépendances fonctionnelles, sera passée sous silence (ce qui est un scandale, j'en conviens...). Nous ne pourrons, par contre, pas échapper, à quelques rudiments d'algèbre relationnelle : j'essaierai de les faire passer le plus simplement possible...

Historique rapide

Oracle et Informix dominent le marché actuel, SQL-Server (de Microsoft) tente de s'imposer dans le monde des PC sous NT. À côté des ces produits, très chers, existent heureusement des systèmes libres et gratuits : MSQL, MYSQL et POSTGRESQL sont les plus connus. Ils existent évidemment sous forme de paquetages rpm ou deb pour Linux et leurs sources peuvent se compiler sur quasiment tous les Unix.

Bien que ces SGBDR n'aient pas la puissance des produits commerciaux, certains s'en approchent de plus en plus : c'est le cas de POSTGRESQL, notamment, que nous avions présenté dans des numéros précédents de Linux Magazine. Les différences notables concernent principalement les environnements de développement qui sont de véritables ateliers logiciels sous Oracle et qui sont réduits à des interfaces de programmation C, Python, Perl sous POSTGRESQL. Il en va de même pour les interfaces utilisateurs : il en existe pour POSTGRESQL, mais ils n'ont certainement pas la puissance de leurs équivalents commerciaux.

Ces limites ne nous gèneront pas car, pour apprendre SQL, pas besoin de clickodrome ! D'autre part, si la dernière version de POSTGRESQL utilise encore un sous-ensemble de SQL-4, celui-ci dispose de toutes les fonctionnalités essentielles. Le jour où vous ressentirez les limites de ce sous-ensemble, vous vous rappelerez avec émotion de ce petit article ;-)

Algèbre relationnelle

Vouloir traiter de SQL sans présenter l'algèbre relationnelle serait comme enseigner un langage de programmation sans présenter l'algorithmique. Nous consacrerons donc un peu de temps à étudier le modèle défini par Codd, et dont SQL n'est que la traduction informatique.

Termes employés

Exemple de relation

Soit la relation ETUDIANTS, représentant un ensemble d'étudiants. Celle-ci sera représentée par le tableau suivant :

Num_Etudiant Nom Prenom Date_Naissance Code_Diplome Adresse Code Postal Ville Tel
... ... ... ... ... ... ... ... ...
9901 Martin Olivier 10/10/1979 A 10, Route de Toulouse 31130 Balma 05.61.12.13.14
... ... ... ... ... ... ... ... ...
9945 Dupont Catherine 09/09/1980 B 2, Av. de Paris 31000 Toulouse  
... ... ... ... ... ... ... ... ...

Cette relation sera notée :

ETUDIANTS(Num_Etudiant, Nom, Prenom, Date_Naissance, Code_Diplome, Adresse, Code Postal, Ville, Tel)

Sa clé est l'attribut Num_Etudiant, car chaque étudiant peut être désigné de manière unique par ce seul attribut. Le problème de la détermination de la clé primaire d'une relation est un sujet qui nous amènerait trop loin pour être abordé ici. Le lecteur intéressé se reportera aux ouvrages cités en fin d'article.

Normalisation d'une relation

Pour être exploitable, une relation doit être normalisée. Plusieurs formes normales ont été définies et nous nous bornerons à utiliser des relations en troisième forme normale (3FN). Vous trouverez dans les différents ouvrages des références à une 3FNBCK (troisième forme normale de Boyce-Codd-Kent), et à une 4FN (multivaluée) : elles ne seront pas utilisées ici.

Première forme normale

Une relation est en 1FN si elle possède une clé, que tous ses attributs dépendent fonctionnellement de cette clé et sont atomiques (non décomposables) : c'est pour cette raison que nous découpons l'adresse en ses différentes parties (adresse, code postal et ville), au lieu de la considérer comme un seul attribut.

Deuxième forme normale

Une relation est en 2FN si elle est en 1FN et que tous les attributs non clé dépendent pleinement de la clé (on ne peut trouver un sous-ensemble d'attributs de la clé qui suffirait à identifier de façon unique un autre attribut). Si la clé est réduite à un attribut (comme dans notre relation ETUDIANT, le problème est trivial).

Soit, par exemple, la relation COMMANDE suivante :

COMMANDE(Numero_Cde, Code_Article, Date_Cde, Nom_Fournisseur, Adr_Fournisseur, Cp_Fournisseur, Ville_Fournisseur)

Cette relation est en 1FN car tous ses attributs sont simples. Elle n'est pas en 2FN car l'attribut Nom_Four ne dépend que d'une partie de la clé (la connaissance de Numero_Cde suffit à déterminer le fournisseur).

Lorsqu'une relation n'est pas en 2FN, il y a donc un problème de redondance des données dans la base : ici, par exemple, il faudrait répéter les champs Date_Cde, Nom_Fournisseur, Adr_Fournisseur, Cp_Fournisseur, Ville_Fournisseur pour chaque article de la commande (alors que c'est le même...).

Afin de mettre cette relation en 2FN, il suffit de la décomposer selon les attributs qui introduisent la redondance (ici, Code_Article) :

COMMANDE(Numero_Cde, Date_Cde, Nom_Fournisseur, Adr_Fournisseur, Cp_Fournisseur, Ville_Fournisseur)
ART_CDE(Numero_Cde, Code_Article)

Cette décomposition est sans perte d'information, et l'on constate que les problèmes de redondance précédents ont disparu.

Les deux relations obtenues ici sont nécessairement en 2FN : COMMANDE a une clé réduite à un attribut (il ne peut donc exister de sous-ensemble...) et les deux uniques attributs de ART_CDE forment la clé.

Troisième forme normale

Une relation est en 3FN si elle est en 2FN et si tout attribut n'appartenant pas à la clé ne dépend pas aussi d'un attribut non clé. Il n'y a donc pas de transitivité dans les dépendances entre les attributs.

Reprenons la relation COMMANDE obtenue à l'étape précédente : elle est bien en 2FN, mais pas en 3FN : les attributs Adr_Fournisseur, Cp_Fournisseur et Ville_Fournisseur dépendent aussi (et surtout) de l'attribut Nom_Fournisseur.

On a donc une transitivité dans les dépendances :

Cette transitivité induit, elle aussi, des problèmes de redondances, ainsi que des problèmes de mises à jour de la base de données : les caractéristiques d'un même fournisseur sont répétées à chaque fois qu'une commande le concerne et, si un fournisseur change d'adresse, il faudra modifier tous les tuples de la relation où celui-ci apparaît.

Là encore, la solution consiste à décomposer la relation selon l'attribut qui introduit la transitivité. COMMANDE devient donc :

COMMANDE(Numero_Cde, Date_Cde, Nom_Fournisseur)
FOURNISS(Nom_Four, Adr_Four, Cp_Four, Ville_Four)

Nous n'avons pas perdu d'informations et les problèmes de redondance et de mise à jour sont maintenant réglés.

Les deux relations obtenues, ainsi que la relation ART_CDE, sont en 3FN : nous avons donc désormais un schéma en troisième forme normale et nous nous en contenterons.

Opérateurs relationnels

Maintenant que nous avons défini notre univers : l'ensemble des relations, voyons les opérations qu'il est possible d'effectuer.

L'algèbre de Codd repose sur la théorie des ensembles et, sur les neuf opérateurs principaux, quatre sont les opérateurs ensemblistes bien connus : union, intersection, différence et produit cartésien. Les cinq autres sont propres aux tableaux : projection, sélection, différence, jointure et division. Nous verrons que le langage SQL n'est rien d'autre que la représentation, dans un langage informatique, de ces opérations.

Opérateurs ensemblistes

Trois de ces opérateurs agissent sur deux relations de même schéma, ce sont l'union, l'intersection et la différence.

L'opérateur de produit cartésien agit sur des relations ayant des schémas différents :

Opérations sur les tables

Les opérateurs suivants agissent sur une relation :

Les deux autres opérateurs agissent sur deux relations n'ayant pas nécessairement le même schéma :

Exemples récapitulatifs

Soit les schémas de relation suivants :

COMMANDE(Num_Cde, Date_Cde, Num_Four, Montant_Cde)
FOURNISSEUR(Num_Four, Nom_Four, Adr_Four, ...)

Soient les questions suivantes :

C'est tout pour cette fois...

Quoi ? L'article est fini et l'on n'a pas vu une seule instruction SQL ? Non, c'est vrai, mais nous avons posé (d'une façon très rudimentaire) les bases des prochains articles qui, eux, présenteront le langage et créeront des bases de données permettant de tester réellement les requêtes.

En attendant, vous pouvez ronger votre frein en consultant les ouvrages suivants :

Cette liste est loin d'être exhaustive, mais ce sont les ouvrages que j'utilise... Vous trouverez dans ceux-ci d'autres références, françaises et internationales.

Une recherche utilisant le mot clé « SQL » sur yahoo! devrait également vous proposer un certain nombre de documents, voire de cours complets, disponibles en téléchargement.

À propos de ce document...

Introduction à SQL

This document was generated using the LaTeX2HTML translator Version 98.1p1 release (March 2nd, 1998)

Copyright © 1993, 1994, 1995, 1996, 1997, Nikos Drakos, Computer Based Learning Unit, University of Leeds.

The command line arguments were:
latex2html -split 0 sql1.

The translation was initiated by Eric Jacoboni on 1999-09-27


Eric Jacoboni
1999-09-27

© Copyright 2000 Diamond Editions/Linux magazine France
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; A copy of the license is included in the section entitled "GNU Free Documentation License".