Conception d'une base de données

De l'analyse à la base de données

Un modèle de données est une description formelle et structurée des données et de leurs liens de dépendance dans un système d'information. Les classes de données, ou ensembles d'entités, et les ensembles de liaisons sont définis indépendamment des ordinateurs et des systèmes de getion de bases de données qui serviront plus tard à la saisie, au stockage et à la mise à jour des informations. Du point de vue utilisateur, cette indépendance assure la stabilité des données et de leurs liens de dépendance face au développement des systèmes informatiques et de l'évolution des logiciels.

La description de monde réel en vue de concevoir une base de données comporte trois phases majeures: 1. l'analyse de données 2. la construction d'un modèle entité-association 3. sa conversion en un schéma de base de données relationnelle

L'analyse des données vise à déterminer, en collaboration avec les utilisateurs, les données nécessaires à un système d'information, leurs liaisons et leurs structures. C'est ainsi qu'on parvient à délimiter dès le début les frontières d'un système. Elle doit aboutir à la mise au point d'une documentation complète qui contient au minimum une description narrative du mandat avec des objectifs clairement définis ainsi qu'une liste des informations factuelles pertinentes. Durant cette phase, il est important d'utiliser le langage des utilisateurs.

La deuxième phase d'abstraction consiste à concevoir un modèle entité-association où l'on définit les ensembles d'entités et les ensembles de liens entre ces entités.

La troisième phase a pour but de convertir le modèle entité-association en un schéma de base de données relationnelle. C'est-à-dire à fournir une description formelle des objets dans la base de données considérée. Les ensembles d'entités et de liens sont exprimés sous forme de tables.

Le modèle entité-association

Entités et associations

Une entité est un objet spécifique dans le monde réel ou imaginaire. Elle peut désigner une personne, un objet, un concept abstrait, etc. Les entités de même type forment un ensemble d'entités caractérisées par un certain nombre d'attributs.

Pour chaque entité, une clé d'identification doit être utilisé. Elle permet de distinguer sans ambiguïté les entités dans l'ensemble considéré. Cette clé doit être formée d'une combinaison minimale d'attributs.

Entre les ensembles d'entités s'établissent des liaisons qui forment également un ensemble. Les ensembles de liaisons se caractérisent aussi par leurs propres attributs.

Les types d'associations

Une association d'un ensemble d'entités E1 à un deuxième ensemble E2 d'entités définit un lien orienté dans cette direction E1->E2. Chaque association est caractérisée par un type. Un type d'association indique le nombre d'entités provenant du deuxième ensemble E2 qui sont reliés à une entité du premier ensemble E1.

On distingue quatre types d'associations: simple, conditionnelle, multiple et multiple conditionnelle.

Association simple

Dans une association simple, à chaque entité de E1 correspond une et une seule entité de E2.

Association conditionnelle

A chaque entité de E1 correspond *au plus une * entité de E2.

Association multiple

A chaque entité de E1 correspond plusieurs entités de E2.

Association multiple conditionnelle

A chaque entité de E1 correspond * aucune, une ou plusieurs* entités de E2.

Les types d'associations déterminent le degré d'une liaison. Chaque liaison comprend deux types d'associations et donc le degré d'une liaison est défini par une paire de types d'associations:

Degré = (Type d'association de E1 -> E2, Type d'association de E2 -> E1)

Généralisation et agrégation

La généralisation des ensemble d'entités est un processus d'abstraction qui consiste à généraliser les entités, et donc les ensembles d'entités en un seul ensemble ascendant. Réciproquement, les ensembles d'entités dépendants ou sous-ensembles d'entités dans une hiérarchie de généralisation résultent du processus de spécialisation.

Les sous-ensembles d'entités peuvent être disjoints ou non (i.e., posséder des intersections non nulles).

La généralisation est une structuration en type ''EST-UN''.

L'aggrégation consiste à réunir les entités en un tout de niveau supérieur. Ces entités regroupées sont alors considérées comme une seule entité dans un nouvel ensemble d'entités.

Le schéma d'une base de données relationnelle

Le passage du modèle entité-association au schéma de base de données relationnelle permet de représenter les ensembles d'entités et de liens par des tables.

Un schéma de base de données contient la description d'une base de données et plus précisément la spécification de la structure des données et de leur contraintes d'intégrité. Il contient la définition des tables, des attributs et des clés primaires. Les contraintes d'intégrité imposent des limites aux domaines des attributs et définissent les dépendances entre les tables.

Règle 1 (ensembles d'entités)

Chaque ensemble d'entités doit être traduit en une table distincte, avec une clé primaire unique.

Règle 2 (ensembles de liens)

Chaque ensemble de liens peut être traduit en une table distincte. Elle doit contenir les clés d'identification des ensembles d'entités participantes comme clés étrangères.

L'application des règles de passage 1 et 2 ne conduit pas toujours à un schéma de base de données relationelle optimal.

Règle 3 (liaisons de type multiple-multiple)

Chaque ensemble de liens de degré multiple-multiple doit être transformé en une table distincte. Les clés étrangères de la table sont formées au moins des clés d'identification des ensembles d'entités qui participent à la liaison. La clé primaire de la table est soit la clé d'identification formée par la concaténation des clés étrangères, soit une autre clé candidate.

Règle 4 (liaisons de type simple-multiple)

Un ensemble de liens simple-multiple peut s'exprimer dans les deux tables des ensembles d'entités participantes sans avoir besoin de créer une table distincte. Pour cela, dans la table qui participe à l'association simple, on définit une clé étrangère qui la relie à la table référencée en y ajoutant éventuellement d'autres attributs de l'ensemble de liens considéré.

Pour mettre en évidence une liaison, il convient d'ajouter un nom de rôle au nom de la clé d'identification correspondante. Un nom de rôle rend explicite la signification des valeurs d'une clé spécifique dans une table étrangère.

Règle 5 (liaisons simple-simple)

Un ensemble de liens simple-simple peut s'exprimer dans les deux tables des ensembles d'entités participantes sans avoir besoin de créer une table distincte. Une des clés d'identification de la table référencée est choisie comme clé étrangère dans la seconde table.

Règle 6 (généralisation)

Chaque ensemble d'entités dans une hiérarchie de généralisation donne lieu à une table distincte. La clé primaire de la table ascendante est aussi celle des tables au niveau inférieur.

Règle 7 (agrégation)

Dans une structure d'agrégation, si le type de liens est multiple-multiple, une table distincte doit être créée pour l'ensemble d'entités ainsi que pour l'ensemble de liens. La table qui traduit l'ensemble de liens contient deux fois la clé provenant de la table créée pour l'ensemble d'entités, à laquelle s'ajoute un nom de rôle. La concaténation de ces deux clés aux rôles différents définit la clé d'identification de la table créée pour l'ensemble de liens. Si la liaison est de type simple-multiple, il est possible de combiner en une seule table l'ensemble d'entités et l'ensemble de liens.

Les formes normales

La recherche dans le domaine relationnel a permis d'élaborer une théorie des bases de données qui traite des aspects formels du modèle relationnel. Elle accorde une place importante l'étude des formes normales. L'objectif consiste à détecter et à étudier les dépendances à l'intérieur des tables pour en éliminer les informations redondantes et les anomalies qui en resultent.

Un attribut dans une table est redondant lorsque ses valeurs peuvent être éliminées de cette table sans perte d'informations. Une table contenant des informations redondantes peut entraîner des anomalies de mutation (insertion, suppression, modification).

Les formes normales permettent d'éliminer les anomalies, et par la même les redondances qui en sont la cause.

Il existe 5 formes normales, mais on se limite généralement aux trois premières.

Première forme normale

Une table satisfait à la première forme normale si les domaines de ses attributs sont constitués de valeurs atomiques. C'est à dire que les attributs ne doivent pas contenir d'ensembles, de types énumérés ou de groupes répétitifs.

Deuxième forme normale

Une table satisfait à la deuxième forme normale si elle est en première forme normale et s'il existe une dépendance fonctionnelle totale reliant la clé à chaque attribut non clé.

Un attribut B est fonctionnellement dépendant de l'attribut A si à chaque valeur de A correspond une et une seule valeur de B (noté conventionnellement A->B). Par conséquent, la dépendance fonctionnelle de A vers B exprime le fait que chaque valeur de A détermine de manière unique une valeur de B.

Troisième forme normale

Une table est en troisième forme normale si elle est en deuxième forme normale et qu'aucun attribut non clé ne dépend d'une clé quelconque par transitivité.

La dépendance transitive est une dépendance fonctionnelle indirecte: si A->B et B->C alors A->C.

Contraintes d'intégrités structurelles

Le concept d'intégrité signifie l'absence d'incohérence dans une base de données. Le terme cohérence est aussi utilisé pour se référer à ce concept. Si les données étaient introduites sans erreur dans une base et qu'elles délivrent les informations désirées de manière correcte, on dit que la base de données en question est intègre ou cohérente.

Les contraintes d'intégrité structurelles établissent des règles qui doivent s'appliquer à un schéma de base de données pour assurer sa cohérence. Ces contraintes d'intégrité structurelles sont classées en trois catégories:

  • contrainte d'unicité: chaque table possède une clé d'identification (la clé primaire) qui sert à différencier les enregistrements dans la table de manière unique.

  • contrainte de domaine: un attribut dans une table ne peut prendre que des valeurs appartenant à un domaine de valeurs prédéfinies.

  • contrainte d'intégrité référentielle: chaque valeur d'une clé étrangère doit exister comme valeur de la clé d'identification correspondante dans la table référencée.

Les contraintes de domaine et d'intégrité référentielle sont généralement peu, pas ou mal gérées par un SGBDR. Il est donc nécessaire de construire en amont un certain nombre de mécanismes permettant non seulement de gérer la manipulation de la base de données, mais aussi sa cohérence.

Interfaces de programmation (API)

Les langages relationnels d'interrogation et de manipulation de données telles que SQL ne sont pas réservés uniquement à l'usage en tant que langages autonomes en mode conversationnel. Ils sont aussi intégrés dans des langages de programmation (langages hôtes). On parle alors d'interfaces de programmation ou API.

Par exemple, MySQL possède des API pour les langages C, C++, Java, Python, Perl, PHP, Tcl, Eiffel, etc.

import java.sql.*;

public class Connect {
    public static void main(String argv[]) {
        Connection con = null;

        try {
            // here is the JDBC URL for this database
            String url = "jdbc:mysql://athens.imaginary.com/
                        Web?user=someuser&password=somepass";
            // more on what the Statement and ResultSet classes do later
            Statement stmt;
            ResultSet rs; 

            // either pass this as a property, i.e.
            // -Djdbc.drivers=org.gjt.mm.mysql.Driver
            // or load it here as we are doing in this example
            Class.forName("org.gjt.mm.mysql.Driver");
            // here is where the connection is made   
            con = DriverManager.getConnection(url); 
        }
        catch( SQLException e ) {
            e.printStackTrace(  );
        }
        finally {
            if( con != null ) {
                try { con.close(  ); }
                catch( Exception e ) { }
            }
        }
    }
}