|
Site |
Cours VB.net |
|
|
|
Les bases de données. |
|
|
Comment lire et écrire des informations complexes et structurées?
Généralités:
Pour travailler avec du texte, des octets, des données très simple (sans nécessité d'index, de classement..), on utilise les fichiers séquentiels, aléatoires, binaires (chapitre 4-6).
Mais dès que les informations sont plus structurées, il faut utiliser les bases de données (Data Base en anglais).
Une base de données peut être:
locale: utilisable sur un ordinateur par un utilisateur.
répartie, c'est-à-dire que la base est stockée sur des machines distantes et accessibles par réseau.
Plusieurs utilisateurs peuvent accédés à la base simultanément.
Exemple de type de base de données:
Dbase Format très utilisé, qui date maintenant un peu, les fichiers contenant ses bases ont l'extension .dbf
Paradox
FileMaker
FoxPro
Interbase
Access Format très répandu, les fichiers contenant ses bases ont l'extension .mdb
SQLServeur les fichiers contenant ses bases ont l'extension .dbo
SyBase
MySql
Oracle..
Pour pouvoir contrôler les données, l'accès à ces données et les utilisateurs utilisant une base de données, un système de gestion est nécessaire. La gestion de la base de données se fait grâce à un système appelé SGBD (système de gestion de bases de données), si la base de données est relationnelle (Existence de relation entre les tables) on parle de SGBDR (système de gestion de bases de données relationnelles)
Un SGBD est un
logiciel qui joue le rôle d'interface entre les utilisateurs et la base de
données.
Un SGBD permet de décrire, manipuler et interroger les données d'une 'Base de Données'.
Tables:
Dans une base de données, il y a des tables:
Une table sert à stocker physiquement des données sous forme d'un tableau comportant des lignes (rows) et des colonnes (columns).
Exemple:
Une base de données Access nommée Cabinet.mdb contient les patients d'un cabinet, leurs consultations, les ordonnances, les médicaments..
Dans cette base il y a plusieurs tables: une table patient, une table consultation...
Examinons la table patient:
Sur chaque ligne (row), il y a un patient,.
Chaque colonne (column) représente un type de données (première colonne= civilité, seconde=nom, troisième=prénom, quatrième= numéro interne propre à chaque patient. )
L'ancienne terminologie parlait d'enregistrements (lignes) et de champs (colonnes)
| Champs Civilité | Champ Nom | Champ Prénom | Champ Numéro Interne |
| M. | Durand | Luc | 1 |
| Mme | Dupont | Josette | 2 |
| M. | Thomas | Guy | 3 |
Ici la seconde ligne (le 2eme enregistrement, le second row) contient la civilité, le nom, le prénom, le numéro du patient Dupont Josette.
Chaque colonne à un type bien définie: dans notre cas la première colonne contient du texte, ainsi que la seconde, la troisième; la quatrième colonne contient un numérique long par exemple.
Examinons la table consultation:
Sur chaque ligne, il y a une consultation,.
Chaque colonne représente un type de données (première colonne= numéro correspondant au patient, seconde=date, troisième=texte de la consultation, quatrième= Courrier. )
| Champs Numéro Interne | Champ Date | Champ Texte | Champ Courrier |
| 1 | 02/12/2003 | Angine | |
| 2 | 02/02/2004 | Hta | |
| 1 | 05/04/2004 | Bronchite |
Il n'est pas question pour chaque consultation d'enregistrer de nouveau le nom et le prénom du patient, cela enregistrerait 2 fois la même information puisque le nom et le prénom du patient sont déjà dans la table 'patient'. On va donc, pour éviter les redondances, utiliser un numéro interne: chaque patient a un numéro unique (4éme champ de la table 'nom'); il suffit de noter dans chaque consultation le numéro du patient.
Ensuite, si je consulte le patient Durand Luc, sachant que son numéro interne est '1', il suffit de rechercher dans la table consultation les consultations dont le premier champ est 1: Durand Luc à 2 consultations.
Le nom de la colonne est souvent nommé en utilisant le terme Id (pas ici) , 'IdPatient' par exemple, synonyme de 'numéro patient', cela permet de repérer les champs 'numéro interne'.
Type de colonne:
Il existe des types de colonne (de champs) alphanumériques
de longueur fixe (pour le champ 'nom' je prévois 30 caractères par exemple).
de longueur variable (champ mémo dans la base Dbase par exemple)
Il existe aussi
des champs numériques,
des champs dates
et dans certains base de données des champs booléens, image...
Clé primaire
Quand il est nécessaire de différencier chaque enregistrement de manière unique, il faut définir un champ comme clé primaire.
Ce champ doit être unique pour chaque enregistrement (il ne doit pas y avoir de doublons: 2 enregistrements ne peuvent pas avoir la même clé primaire), et la valeur de la clé primaire ne peut pas être égale à null.
Dans notre exemple de la table patient, on ne peut pas utiliser le champ 'nom' comme clé primaire car plusieurs patients peuvent avoir le même nom, il est judicieux de choisir le champ 'numéro interne' comme clé primaire car chaque patient (donc chaque enregistrement) à un numéro interne unique.
Quand on enregistre une nouvelle fiche patient, il faut donc donner un nouveau 'numéro interne' qui n'a jamais été utilisé, en pratique:
On gère soi même les numéros: on prend le dernier numéro interne (on cherche la dernière fiche dont on récupère le numéro ou bien on lit ce numéro qui a été enregistré quelque part), on ajoute 1 pour avoir le nouveau numéro.
On utilise un champ qui s'incrément automatiquement a chaque fois que l'on crée une enregistrement (NumeroAuto dans Access)
Index
Un index permet d'optimiser les recherches dans une table, de les rendre beaucoup plus rapide.
Expliquons:
Si j'ai une table contenant les noms des médecins utilisateurs et que je veux chercher un nom, comme il y a au maximum 5 à 6 médecins dans un cabinet, pour rechercher un nom, il suffit de lire successivement chaque enregistrement et de voir si c'est celui recherché. C'est suffisamment rapide.
Par contre si je recherche dans la table patient un patient, comme il y a 4000 à 8000 enregistrements, je ne peux pas les lire un à un , c'est trop long, aussi je crée un index: c'est comme l'index d'un livre, le nom me donne directement l'endroit ou se trouve l'enregistrement correspondant.
On peut combiner plusieurs champs pour en faire la base d'un index.
Pour ma table 'patient', je peux créer un index nommé IndexPatient qui sera indexé sur Nom +Prenom.
Il peut y a voir plusieurs index sur une même table.
Les index accélèrent les recherches mais s'il y en a trop, cela alourdit le
fonctionnement; on ne peut pas tout indexer!!
Relations entre les tables: différents types de relations.
On a déjà vu que 2 tables peuvent être liées et avoir un champ commun présent dans les 2 tables.
Sur ce champ commun, il peut exister plusieurs types de relation:
Relation 1 à N
Relation 1 à 1
Relation N à M
Voyons cela en détail:
1 à N (relation un à plusieurs)
Dans notre exemple la table 'patient' et la table 'consultation' ont chacune un champ numéro interne. Ce qui permet de lier à l'enregistrement du patient de numéro interne X toutes les consultations pour ce patient (elles ont dans leurs champs 'numéro interne' la valeur X.
Comme pour UN patient il peut y avoir N consultations, on parle de relation 1 à N.
Un enregistrement unique est lié à plusieurs enregistrements de l'autre table par un champ présent dans les 2 tables.
On remarque que le champ 'numéro interne' du coté patient est une clé primaire, pas du coté consultation.
Table 'patients'
| Champ Numéro Interne |
| M. | Durand | Luc | 1 |
| Mme | Dupont | Josette | 2 |
| M. | Thomas | Guy | 3 |
Table 'consultations'
| Champ Numéro Interne |
| 1 | 02/12/2003 | Angine | |
| 2 | 02/02/2004 | Hta | |
| 1 | 05/04/2004 | Bronchite |
Le patient Durand Luc a 2 consultations : le 02/12/2003 et le 05/04/2004 (Le numéro interne de ce patient est 1, mais l'utilisateur final n'a pas à le savoir ni à le gérer: la relation utilisant le numéro interne est transparente pour l'utilisateur final)
Il existe aussi les relations:
1 à 1
Un enregistrement unique est lié à un autre enregistrement unique par un champ présent dans les 2 tables.
On peut imaginer dans notre exemple, créer une table Antécédents contenant aussi un champ numéro interne; pour chaque enregistrement de la table patient, il y a un enregistrement unique dans la table Antécédents, de même numéro interne contenant les antécédents du patient.
Table 'patient'
| M. | Durand | Luc | 1 |
| Mme | Dupont | Josette | 2 |
| M. | Thomas | Guy | 3 |
Table 'antécédents'
Champ Numéro interne.
| 1 | 02/01/2003 | appendicite |
| 2 | 02/02/2004 | Hta |
| 3 | 05/05/2004 | Cancer du colon |
Enfin existe les relations:
N à M
Relation plusieurs à plusieurs. Plusieurs enregistrements de la première table peuvent être liés à plusieurs de la seconde table et vice versa.
Exemple:
J'ai une table 'ordonnances' qui peut contenir plusieurs médicaments, et une table 'médicaments' dont les médicaments peuvent être utilisé dans plusieurs ordonnances différentes.
Il faut dans ce cas avoir la table 'ordonnances' avec une clé primaire sur un numéro d'ordonnance (numéro d'ordonnance unique s'incrémentant à chaque nouvelle ordonnance), une table 'médicaments' avec une clé primaire sur le numéro unique du médicament, et créer une troisième table gérant la relation ordonnance-médicament.
Table 'Ordonnances'
| 'Numéro ordonnance' | 'Numéro Interne patient' | Champ' date' |
| 1 | 2 | 02/05/2002 | |
| 2 | 3 | 02/04/2003 | |
| 3 | 2 | 06/05/2004 |
Table 'Médicaments'
| 'Numéro médicament' | 'Libelle médicament' | Code CIP' |
| 1 | Amoxicilline | 65897 | |
| 2 | Omeprazone | 66589 | |
| 3 | Allopurinol | 78456 |
Table supplémentaire 'Contenu ordonnance'
| 'Numéro ordonnance' | 'Numéro médicament' |
| 1 | 1 |
| 1 | 2 |
| 2 | 2 |
Ici le patient de numéro interne 2 (Dupont Josette) a une ordonnance visible dans la table 'Ordonnances'(numéro interne: 2; numéro de l'ordonnance: 1); si on cherche dans la table 'Contenu ordonnance' (Index crée sur le numéro d'ordonnance) on retrouve 2 enregistrements (ayant un numéro d'ordonnance 1), on constate que l'ordonnance contient les médicaments 1 et 2 qui correspondent (table 'médicaments') à de l'amoxicilline et de l'oméprazone.
On remarque qu'une ordonnance peut avoir autant de médicaments que l'on veut.
Relation N à M avec N fixe et petit
Dernier cas non décrit dans les livres:
J'explique: si chaque ordonnance à au maximum 3 médicaments ( que la sécu serait contente si c'était vrai!!), il est possible de créer une table 'ordonnances' contenant 3 champs médicaments. Dans ce cas on se passe de la 3eme table.
Table 'Ordonnances'
| 'Numéro ordonnance' | 'Numéro Interne patient' | Champ' date' | 3 champs médicaments |
| 1 | 2 | 02/05/2002 | 1 | 2 | |
| 2 | 3 | 02/04/2003 | |||
| 3 | 2 | 06/05/2004 |
Table 'Médicaments'
| 'Numéro médicament' | 'Libelle médicament' | Code CIP' |
| 1 | Amoxicilline | 65897 | |
| 2 | Omeprazone | 66589 | |
| 3 | Allopurinol | 78456 |
Contraintes
Un champ peut avoir certaines contraintes:
On peut interdire la valeur Null: Cela empêche d'enregistrer un champ vide. On peut aussi donner une valeur par défaut.
On peut empêcher les doublons.
On peut exiger l'intégrité référentielle: La valeur d'un champ doit exister dans le champ d'une autre table.(On ne peut pas enregistrer une consultation pour le patient de numéro interne 2000 s'il n'existe pas de fiche patient ayant le numéro 2000)
On peut exiger des règles de validation pour un champ: interdire les valeurs négatives par exemple.
Serveur de fichier, Client serveur.
Si plusieurs utilisateurs sont connectés à une base Access à travers un réseau, chaque utilisateur a sur son poste un 'moteur' Access, qui récupère l'ensemble des données à utiliser et qui les traite en local. On parle de serveur de fichier.
Le moteur d'accès est présent sur chaque poste.
Si plusieurs utilisateurs sont connectés à une base SQLServer: la base est sur le serveur avec le logiciel SQLServeur.
Un logiciel utilisateur situé sur un autre ordinateur(le client) envoie au serveur une requête.
Le logiciel SQLServer traite la requête sur le serveur et retourne au logiciel client uniquement le résultat de la requête.
On parle d'architecture Client-serveur.
Le moteur d'accès est présent uniquement sur le serveur.
Si on cherche un enregistrement parmi 60 000 enregistrements, en serveur de fichiers, les 60 000 enregistrements sont envoyées par le réseau vers le moteur Access de l'utilisateur ; le moteur les traite pour en sortir un.
En client serveur, le logiciel utilisateur envoie une requête au serveur, le logiciel serveur cherche sur le serveur dans la base l'enregistrement, il le trouve et envoie à travers le réseau vers le logiciel client uniquement un enregistrement.
Opérations sur les enregistrements
De manière générale, on peut:
Ouvrir une base de données (Open)
Ajouter un enregistrement (Add)
Effacer un enregistrement (Delete)
Modifier un enregistrement (Update)
Chercher un ou des enregistrements.
Fermer la base. (Close)
Avant:
Il y a bien longtemps, on choisissait un index, on cherchait un enregistrement (avec Seek), on le lisait, le modifiait, on avançait (MoveNext) ou on reculait (MovePrevious) d'un enregistrement dans la base, mais c'est de l'histoire ancienne!!
Chaque type de base de données avait ses propres commandes.
Ensuite , il y a eu les RecordSet, sorte de tableau avec un curseur pointant un élément.
Avec
ADO.NET:
Maintenant quelle que soit la base de données, on utilise un langage unique: le 'SQL' pour faire une requête sur une base de donnée (extraction de certains enregistrements ou de certains champs en fonction de critères), le résultat (un ensemble d'enregistrements ou de champs) se retrouve dans un DataSet.
|
|
|
|
|