| 1 |
<!-- $Header: /var/lib/cvs/pgsql-fr/sgml/ddl.sgml,v 1.6.2.3 2005/07/15 06:33:36 guillaume Exp $ --> |
|---|
| 2 |
|
|---|
| 3 |
<chapter id="ddl"> |
|---|
| 4 |
<title>Définition des données</title> |
|---|
| 5 |
|
|---|
| 6 |
<para> |
|---|
| 7 |
Ce chapitre couvre la création de structures de données qui contiendront |
|---|
| 8 |
les données de quelqu'un. Dans une base relationnelle, les données brutes |
|---|
| 9 |
sont stockées dans des tables. Du coup, la plus grande partie de ce chapitre |
|---|
| 10 |
sera consacrée à l'explication de la création et de la modification des tables |
|---|
| 11 |
et des fonctions disponibles pour contrôler les données stockées dans les tables. |
|---|
| 12 |
Ensuite, nous discuterons de l'organisation de tables en schémas, et comment |
|---|
| 13 |
des droits peuvent être attribués aux tables. Enfin, |
|---|
| 14 |
nous verrons brièvement d'autres fonctionnalités, tel que les vues, les fonctions |
|---|
| 15 |
et les déclencheurs. |
|---|
| 16 |
</para> |
|---|
| 17 |
|
|---|
| 18 |
<sect1 id="ddl-basics"> |
|---|
| 19 |
<title>Bases sur les tables</title> |
|---|
| 20 |
|
|---|
| 21 |
<indexterm zone="ddl-basics"> |
|---|
| 22 |
<primary>table</primary> |
|---|
| 23 |
</indexterm> |
|---|
| 24 |
|
|---|
| 25 |
<indexterm> |
|---|
| 26 |
<primary>rangée</primary> |
|---|
| 27 |
</indexterm> |
|---|
| 28 |
|
|---|
| 29 |
<indexterm> |
|---|
| 30 |
<primary>colonne</primary> |
|---|
| 31 |
</indexterm> |
|---|
| 32 |
|
|---|
| 33 |
<para> |
|---|
| 34 |
Une table dans une base relationnelle ressemble beaucoup à un tableau |
|---|
| 35 |
sur papier : elle est constituée de rangées et de colonnes. Le nombre |
|---|
| 36 |
et l'ordre des colonnes sont fixés et chaque colonne a un nom. Le |
|---|
| 37 |
nombre de rangées est variable -- il représente la quantité de données |
|---|
| 38 |
stockées à un moment donné. SQL n'apporte aucune garantie sur l'ordre des |
|---|
| 39 |
rangées dans une table. Quand une table est lue, les rangées |
|---|
| 40 |
apparaîtront dans un ordre aléatoire sauf si un tri est demandé |
|---|
| 41 |
explicitement. Ceci est couvert dans <xref linkend="queries">. De plus, |
|---|
| 42 |
SQL n'attribue pas d'identifiant unique aux rangées. Du coup, il est possible |
|---|
| 43 |
d'avoir plusieurs rangées complètement identiques dans une table. Ceci |
|---|
| 44 |
est une conséquence du modèle mathématique sur lequel repose SQL mais |
|---|
| 45 |
n'est habituellement pas désiré. |
|---|
| 46 |
Plus tard dans ce chapitre, nous verrons comment traiter ce problème. |
|---|
| 47 |
</para> |
|---|
| 48 |
|
|---|
| 49 |
<para> |
|---|
| 50 |
Chaque colonne a un type de donnée. Ce type de donnée restreint la série |
|---|
| 51 |
de valeurs possibles qui peuvent être attribuées à une colonne et attribue |
|---|
| 52 |
des sémantiques à la donnée stockée dans la colonne pour qu'elles puissent |
|---|
| 53 |
être utilisées pour des calculs. Par exemple, une colonne déclarée comme |
|---|
| 54 |
étant d'un type numérique n'acceptera pas une chaîne arbitraire de texte, |
|---|
| 55 |
et les données stockées dans une telle table peuvent être utilisées dans |
|---|
| 56 |
des calculs mathématiques. |
|---|
| 57 |
Par opposition, une colonne déclarée comme étant de type chaîne de |
|---|
| 58 |
caractères acceptera pratiquement n'importe quel type de donnée mais ne |
|---|
| 59 |
se prêtera pas à des calculs mathématiques bien que d'autres opérations |
|---|
| 60 |
tel que la concaténation des chaînes sont disponibles. |
|---|
| 61 |
</para> |
|---|
| 62 |
|
|---|
| 63 |
<para> |
|---|
| 64 |
<productname>PostgreSQL</productname> inclut une série conséquente de types |
|---|
| 65 |
de données intégrés qui correspondent à plusieurs applications. Les |
|---|
| 66 |
utilisateurs peuvent aussi définir leurs propres types de données. La |
|---|
| 67 |
plupart des types de données intégrés ont des noms et des sémantiques |
|---|
| 68 |
évidents alors nous reportons une explication détaillée à <xref |
|---|
| 69 |
linkend="datatype">. Quelques-uns des types les plus utilisés sont |
|---|
| 70 |
<type>integer</type> pour les entiers, <type>numeric</type> pour |
|---|
| 71 |
les nombres pouvant être fractionnels, <type>text</type> pour les chaînes de |
|---|
| 72 |
caractères, <type>date</type> pour les dates, <type>time</type> pour |
|---|
| 73 |
les valeurs de type heure et <type>timestamp</type> pour les valeurs |
|---|
| 74 |
contenant et une date et une heure. |
|---|
| 75 |
</para> |
|---|
| 76 |
|
|---|
| 77 |
<indexterm> |
|---|
| 78 |
<primary>table</primary> |
|---|
| 79 |
<secondary>création</secondary> |
|---|
| 80 |
</indexterm> |
|---|
| 81 |
|
|---|
| 82 |
<para> |
|---|
| 83 |
Pour créer une table, il faut utiliser la commande bien nommée <literal>CREATE |
|---|
| 84 |
TABLE</literal>. Dans cette commande, vous devez spécifier au moins le nom de la |
|---|
| 85 |
nouvelle table, les noms des colonnes et le type de données pour chacune des |
|---|
| 86 |
colonnes. Par exemple : |
|---|
| 87 |
<programlisting> |
|---|
| 88 |
CREATE TABLE ma_premiere_table ( |
|---|
| 89 |
premiere_colonne text, |
|---|
| 90 |
deuxieme_colonne integer |
|---|
| 91 |
); |
|---|
| 92 |
</programlisting> |
|---|
| 93 |
Ceci crée une table nommée <literal>ma_premiere_table</literal> avec |
|---|
| 94 |
deux colonnes. La première colonne est nommée |
|---|
| 95 |
<literal>premiere_colonne</literal> et a un type de données |
|---|
| 96 |
<type>text</type> ; la seconde colonne porte le nom |
|---|
| 97 |
<literal>deuxieme_colonne</literal> et le type <type>integer</type>. |
|---|
| 98 |
Les noms de table et colonnes suivent la syntaxe d'identification expliquée |
|---|
| 99 |
dans <xref linkend="sql-syntax-identifiers">. Les noms des types sont souvent |
|---|
| 100 |
aussi des identifiants mais il y a des exceptions. Notez que la liste des |
|---|
| 101 |
colonnes est séparée par des virgules et entourée par des parenthèses. |
|---|
| 102 |
</para> |
|---|
| 103 |
|
|---|
| 104 |
<para> |
|---|
| 105 |
Bien sur, l'exemple précédant est un peu tiré par les cheveux. Normalement, |
|---|
| 106 |
on donne aux tables et aux colonnes des noms indiquant quels types de données |
|---|
| 107 |
ils stockent. Alors voyons un exemple plus réaliste : |
|---|
| 108 |
<programlisting> |
|---|
| 109 |
CREATE TABLE produits ( |
|---|
| 110 |
no_produit integer, |
|---|
| 111 |
nom text, |
|---|
| 112 |
prix numeric |
|---|
| 113 |
); |
|---|
| 114 |
</programlisting> |
|---|
| 115 |
(Le type <type>numeric</type> peut stocker des composants fractionnels |
|---|
| 116 |
comme on pourrait s'y attendre de montants monétaires.) |
|---|
| 117 |
</para> |
|---|
| 118 |
|
|---|
| 119 |
<tip> |
|---|
| 120 |
<para> |
|---|
| 121 |
Quand vous créez des tables liées entre elles, il est prudent de choisir |
|---|
| 122 |
des règles de nommage pour les tables et les colonnes. Par exemple, il |
|---|
| 123 |
peut y avoir le choix d'utiliser des noms au pluriel ou au singulier |
|---|
| 124 |
pour les noms de table, chaque choix ayant les faveurs d'un théoricien |
|---|
| 125 |
ou d'un autre. |
|---|
| 126 |
</para> |
|---|
| 127 |
</tip> |
|---|
| 128 |
|
|---|
| 129 |
<para> |
|---|
| 130 |
Il y a une limite sur le nombre de colonnes qu'une table peut contenir. |
|---|
| 131 |
Suivant le type de colonne, elle peut être entre 250 et 1600. |
|---|
| 132 |
Par contre, définir une table avec un nombre de colonnes proche de ceux-ci |
|---|
| 133 |
est très inhabituel et est souvent la preuve d'une conception douteuse. |
|---|
| 134 |
</para> |
|---|
| 135 |
|
|---|
| 136 |
<indexterm> |
|---|
| 137 |
<primary>table</primary> |
|---|
| 138 |
<secondary>suppression</secondary> |
|---|
| 139 |
</indexterm> |
|---|
| 140 |
|
|---|
| 141 |
<para> |
|---|
| 142 |
Si vous n'avez plus besoin d'une table, vous pouvez la retirer en utilisant |
|---|
| 143 |
la commande <command>DROP TABLE</command>. Par exemple : |
|---|
| 144 |
<programlisting> |
|---|
| 145 |
DROP TABLE ma_premiere_table; |
|---|
| 146 |
DROP TABLE produits; |
|---|
| 147 |
</programlisting> |
|---|
| 148 |
Tenter de supprimer une table qui n'existe pas est une erreur. |
|---|
| 149 |
Malgré cela, il est habituel dans des fichiers de scripts SQL d'essayer |
|---|
| 150 |
de supprimer chaque table avant de la créer, tout en ignorant les messages |
|---|
| 151 |
d'erreur. |
|---|
| 152 |
</para> |
|---|
| 153 |
|
|---|
| 154 |
<para> |
|---|
| 155 |
Si vous avez besoin de modifier une table qui existe déjà, regardez <xref |
|---|
| 156 |
linkend="ddl-alter"> plus loin dans ce chapitre. |
|---|
| 157 |
</para> |
|---|
| 158 |
|
|---|
| 159 |
<para> |
|---|
| 160 |
Avec les outils dont nous avons déjà discuté, vous pouvez créer des tables |
|---|
| 161 |
fonctionnelles. Le reste de ce chapitre est consacré à l'ajout de fonctionnalités, |
|---|
| 162 |
à la définition de tables pour garantir l'intégrité des données, la sécurité |
|---|
| 163 |
ou la facilité. Si vous êtes impatients de remplir vos tables avec des données |
|---|
| 164 |
tout de suite, vous pouvez sauter au <xref linkend="dml"> et lire le reste de |
|---|
| 165 |
ce chapitre plus tard. |
|---|
| 166 |
</para> |
|---|
| 167 |
</sect1> |
|---|
| 168 |
|
|---|
| 169 |
<sect1 id="ddl-system-columns"> |
|---|
| 170 |
<title>Colonnes Systèmes</title> |
|---|
| 171 |
|
|---|
| 172 |
<para> |
|---|
| 173 |
Chaque table a plusieurs <firstterm>colonnes systèmes</firstterm> qui sont |
|---|
| 174 |
implicitement définis par le système. De ce fait, ces noms ne peuvent être |
|---|
| 175 |
utilisés comme noms de colonnes définis par l'utilisateur. (Notez que ces |
|---|
| 176 |
restrictions sont différentes, si le nom est un mot-clé ou pas; citez un |
|---|
| 177 |
nom ne vous permettra pas d'échapper à ces restrictions.) Vous n'avez pas |
|---|
| 178 |
vraiment besoin de vous préoccuper de ces colonnes, simplement savoir qu'elles |
|---|
| 179 |
existent. |
|---|
| 180 |
</para> |
|---|
| 181 |
|
|---|
| 182 |
<indexterm> |
|---|
| 183 |
<primary>colonne</primary> |
|---|
| 184 |
<secondary>colonne système</secondary> |
|---|
| 185 |
</indexterm> |
|---|
| 186 |
|
|---|
| 187 |
<variablelist> |
|---|
| 188 |
<varlistentry> |
|---|
| 189 |
<term><structfield>oid</structfield></term> |
|---|
| 190 |
<listitem> |
|---|
| 191 |
<para> |
|---|
| 192 |
<indexterm> |
|---|
| 193 |
<primary>OID</primary> |
|---|
| 194 |
<secondary>colonne</secondary> |
|---|
| 195 |
</indexterm> |
|---|
| 196 |
L'identifiant objet (object ID) d'une rangée. Ceci est un numéro de série |
|---|
| 197 |
qui est automatiquement rajouté par |
|---|
| 198 |
<productname>PostgreSQL</productname> à toutes les rangées de tables (sauf |
|---|
| 199 |
si la table a été créée avec <literal>WITHOUT OIDS</literal>, auquel cas |
|---|
| 200 |
cette colonne n'est pas présente). Cette colonne est de type |
|---|
| 201 |
<type>oid</type> (même nom que la colonne); voir <xref |
|---|
| 202 |
linkend="datatype-oid"> pour plus d'informations sur ce type. |
|---|
| 203 |
</para> |
|---|
| 204 |
</listitem> |
|---|
| 205 |
</varlistentry> |
|---|
| 206 |
|
|---|
| 207 |
<varlistentry> |
|---|
| 208 |
<term><structfield>tableoid</structfield></term> |
|---|
| 209 |
<listitem> |
|---|
| 210 |
<indexterm> |
|---|
| 211 |
<primary>tableoid</primary> |
|---|
| 212 |
</indexterm> |
|---|
| 213 |
|
|---|
| 214 |
<para> |
|---|
| 215 |
L' OID de la table contenant cette rangée. Cette colonne est |
|---|
| 216 |
particulièrement utile pour les requêtes qui sélectionnent de |
|---|
| 217 |
hiérarchies héritées, puisque sans elle, il est difficile de |
|---|
| 218 |
dire de quelle table vient une rangée. Le |
|---|
| 219 |
<structfield>tableoid</structfield> peut être joint à la |
|---|
| 220 |
colonne <structfield>oid</structfield> de |
|---|
| 221 |
<structname>pg_class</structname> pour obtenir le nom de la table. |
|---|
| 222 |
</para> |
|---|
| 223 |
</listitem> |
|---|
| 224 |
</varlistentry> |
|---|
| 225 |
|
|---|
| 226 |
<varlistentry> |
|---|
| 227 |
<term><structfield>xmin</structfield></term> |
|---|
| 228 |
<listitem> |
|---|
| 229 |
<indexterm> |
|---|
| 230 |
<primary>xmin</primary> |
|---|
| 231 |
</indexterm> |
|---|
| 232 |
|
|---|
| 233 |
<para> |
|---|
| 234 |
L'identité (transaction ID) de la transaction d'insertion de cette |
|---|
| 235 |
version de la rangée. (Une version de rangée est un état individuel |
|---|
| 236 |
d'une rangée; chaque mise à jour d'une rangée crée une nouvelle version |
|---|
| 237 |
de rangée pour la même rangée logique.) |
|---|
| 238 |
</para> |
|---|
| 239 |
</listitem> |
|---|
| 240 |
</varlistentry> |
|---|
| 241 |
|
|---|
| 242 |
<varlistentry> |
|---|
| 243 |
<term><structfield>cmin</structfield></term> |
|---|
| 244 |
<listitem> |
|---|
| 245 |
<indexterm> |
|---|
| 246 |
<primary>cmin</primary> |
|---|
| 247 |
</indexterm> |
|---|
| 248 |
|
|---|
| 249 |
<para> |
|---|
| 250 |
L'identifiant de commande (à partir de zéro) au sein de la transaction |
|---|
| 251 |
d'insertion. |
|---|
| 252 |
</para> |
|---|
| 253 |
</listitem> |
|---|
| 254 |
</varlistentry> |
|---|
| 255 |
|
|---|
| 256 |
<varlistentry> |
|---|
| 257 |
<term><structfield>xmax</structfield></term> |
|---|
| 258 |
<listitem> |
|---|
| 259 |
<indexterm> |
|---|
| 260 |
<primary>xmax</primary> |
|---|
| 261 |
</indexterm> |
|---|
| 262 |
|
|---|
| 263 |
<para> |
|---|
| 264 |
L'identité (transaction ID) de la transaction de suppression, ou |
|---|
| 265 |
zéro pour une version de rangée non effacée. Il est possible pour |
|---|
| 266 |
cette colonne d'être non nulle dans une version de rangée visible: Ceci |
|---|
| 267 |
indique normalement que la transaction de suppression n'a pas été |
|---|
| 268 |
effectuée, ou qu'une tentative de suppression a été annulée. |
|---|
| 269 |
</para> |
|---|
| 270 |
</listitem> |
|---|
| 271 |
</varlistentry> |
|---|
| 272 |
|
|---|
| 273 |
<varlistentry> |
|---|
| 274 |
<term><structfield>cmax</structfield></term> |
|---|
| 275 |
<listitem> |
|---|
| 276 |
<indexterm> |
|---|
| 277 |
<primary>cmax</primary> |
|---|
| 278 |
</indexterm> |
|---|
| 279 |
|
|---|
| 280 |
<para> |
|---|
| 281 |
L'identifiant de commande au sein d'une transaction de suppression, ou zéro. |
|---|
| 282 |
</para> |
|---|
| 283 |
</listitem> |
|---|
| 284 |
</varlistentry> |
|---|
| 285 |
|
|---|
| 286 |
<varlistentry> |
|---|
| 287 |
<term><structfield>ctid</structfield></term> |
|---|
| 288 |
<listitem> |
|---|
| 289 |
<indexterm> |
|---|
| 290 |
<primary>ctid</primary> |
|---|
| 291 |
</indexterm> |
|---|
| 292 |
|
|---|
| 293 |
<para> |
|---|
| 294 |
La localisation physique de la version de rangée au sein de sa table. Notez que |
|---|
| 295 |
bien que le <structfield>ctid</structfield> peut être utilisé pour |
|---|
| 296 |
trouver la version de rangée très rapidement, le <structfield>ctid</structfield> |
|---|
| 297 |
d'une rangée changera chaque fois qu'il est mis à jour ou déplacé par |
|---|
| 298 |
<structfield>ctid</structfield> changera à chaque lancement de la commande |
|---|
| 299 |
<command>VACUUM FULL</command>. Donc |
|---|
| 300 |
<structfield>ctid</structfield> est inutile en tant qu'identifiant de rangée |
|---|
| 301 |
à long terme. L'OID, ou encore mieux un numéro de série définie par |
|---|
| 302 |
l'utilisateur, devrait être utilisé pour identifier des rangées logiques. |
|---|
| 303 |
</para> |
|---|
| 304 |
</listitem> |
|---|
| 305 |
</varlistentry> |
|---|
| 306 |
</variablelist> |
|---|
| 307 |
|
|---|
| 308 |
<para> |
|---|
| 309 |
Les OIDs sont des nombres de 32 bits et sont attribués d'un seul compteur sur tout |
|---|
| 310 |
le cluster. Dans une base de données grande ou vieille, il est possible que le |
|---|
| 311 |
compteur boucle sur lui-même. Donc il est peu pertinent de partir du principe |
|---|
| 312 |
que les OIDs sont uniques, sauf si vous prenez les précautions nécessaires. |
|---|
| 313 |
La marche a suivre recommandée lorsqu'on utilise les OIDs pour l'identification |
|---|
| 314 |
de rangée est de créer une contrainte unique sur la colonne OID de chaque table |
|---|
| 315 |
pour laquelle l'OID sera utilisé. Ne jamais supposer que les OIDs sont uniques |
|---|
| 316 |
sur toutes les tables; utilisez la combinaison de <structfield>tableoid</structfield> |
|---|
| 317 |
et OID de rangée si vous avez besoin d'un identifiant unique sur toute la base. |
|---|
| 318 |
(Les versions futures de <productname>PostgreSQL</productname> auront |
|---|
| 319 |
probablement un compteur OID pour chaque table, pour que le <structfield>tableoid</structfield> |
|---|
| 320 |
<emphasis>puisse</emphasis> être inclus pour arriver à un identifiant unique globale.) |
|---|
| 321 |
</para> |
|---|
| 322 |
|
|---|
| 323 |
<para> |
|---|
| 324 |
Les identifiants de transaction sont aussi des nombres de 32 bits. Dans une |
|---|
| 325 |
base de données de longue vie, il est possible pour les ID de transaction de |
|---|
| 326 |
boucler sur eux-mêmes. Ceci n'est pas un problème fatal avec des procédures |
|---|
| 327 |
de maintenance appropriées; voir <xref linkend="maintenance"> pour les détails. |
|---|
| 328 |
Il est, par contre, imprudent de dépendre de l'aspect unique des ID de |
|---|
| 329 |
transaction à long terme (plus d'un milliard de transactions). |
|---|
| 330 |
</para> |
|---|
| 331 |
|
|---|
| 332 |
<para> |
|---|
| 333 |
Les identifiants de commande sont aussi des nombres de 32 bits. Ceci |
|---|
| 334 |
crée une limite dure de 2<superscript>32</superscript> (4 milliards) commandes |
|---|
| 335 |
<acronym>SQL</acronym> au sein d'une seule transaction. En pratique, |
|---|
| 336 |
cette limite n'est pas un problème --- notez que la limite est sur le nombre |
|---|
| 337 |
de commandes <acronym>SQL</acronym>, pas le nombre de rangées traitées. |
|---|
| 338 |
</para> |
|---|
| 339 |
</sect1> |
|---|
| 340 |
|
|---|
| 341 |
<sect1 id="ddl-default"> |
|---|
| 342 |
<title>Valeurs par défaut</title> |
|---|
| 343 |
|
|---|
| 344 |
<indexterm zone="ddl-default"> |
|---|
| 345 |
<primary>valeur par défaut</primary> |
|---|
| 346 |
</indexterm> |
|---|
| 347 |
|
|---|
| 348 |
<para> |
|---|
| 349 |
On peut attribuer une valeur par défaut à une colonne. Quand une nouvelle |
|---|
| 350 |
rangée est créée et qu'aucune valeur n'est spécifiée pour certaines de ses |
|---|
| 351 |
colonnes, celles-ci sont remplies avec leur valeur par défaut respective. |
|---|
| 352 |
Une commande de manipulation de données peut aussi demander explicitement |
|---|
| 353 |
qu'une colonne soit mise à sa valeur par défaut sans connaître la valeur |
|---|
| 354 |
en question. (Les détails sur les commandes de manipulation de données |
|---|
| 355 |
sont dans <xref linkend="dml">.) |
|---|
| 356 |
</para> |
|---|
| 357 |
|
|---|
| 358 |
<para> |
|---|
| 359 |
<indexterm><primary>valeur nulle</primary><secondary>valeur par défaut</secondary></indexterm> |
|---|
| 360 |
Si aucune valeur par défaut n'est déclarée explicitement, la valeur |
|---|
| 361 |
par défaut est la valeur nulle. Ceci est d'habitude cohérent car on |
|---|
| 362 |
peut imaginer que la valeur nulle représente des données inconnues. |
|---|
| 363 |
</para> |
|---|
| 364 |
|
|---|
| 365 |
<para> |
|---|
| 366 |
Dans une définition de table, les valeurs par défaut sont listées après |
|---|
| 367 |
le type de donnée de la colonne. Par exemple: |
|---|
| 368 |
<programlisting> |
|---|
| 369 |
CREATE TABLE produits ( |
|---|
| 370 |
no_produit integer, |
|---|
| 371 |
nom text, |
|---|
| 372 |
prix numeric <emphasis>DEFAULT 9.99</emphasis> |
|---|
| 373 |
); |
|---|
| 374 |
</programlisting> |
|---|
| 375 |
</para> |
|---|
| 376 |
|
|---|
| 377 |
<para> |
|---|
| 378 |
La valeur par défaut peut être une expression scalaire, qui |
|---|
| 379 |
sera évaluée à l'insertion de la valeur par défaut |
|---|
| 380 |
(<emphasis>pas</emphasis> à la création de la table.) |
|---|
| 381 |
</para> |
|---|
| 382 |
</sect1> |
|---|
| 383 |
|
|---|
| 384 |
<sect1 id="ddl-constraints"> |
|---|
| 385 |
<title>Contraintes</title> |
|---|
| 386 |
|
|---|
| 387 |
<indexterm zone="ddl-constraints"> |
|---|
| 388 |
<primary>contrainte</primary> |
|---|
| 389 |
</indexterm> |
|---|
| 390 |
|
|---|
| 391 |
<para> |
|---|
| 392 |
Les types de données sont un moyen de limiter ce qui peut être stocké |
|---|
| 393 |
dans une table. Pour beaucoup d'applications, par contre, la contrainte |
|---|
| 394 |
qu'elles appliquent sont trop fortes. Par exemple, une colonne qui |
|---|
| 395 |
contient le prix d'un produit ne devrait accepter que des valeurs |
|---|
| 396 |
positives. Mais il n'y a pas de type de données qui n'acceptent que |
|---|
| 397 |
des valeurs positives. Un autre problème est le fait de vouloir limiter |
|---|
| 398 |
les données d'une colonne par rapport à d'autres colonnes ou rangées. |
|---|
| 399 |
Par exemple, dans une table contenant des informations de produit, il |
|---|
| 400 |
ne devrait y avoir qu'une rangée pour chaque numéro de produit. |
|---|
| 401 |
</para> |
|---|
| 402 |
|
|---|
| 403 |
<para> |
|---|
| 404 |
Dans ce but, SQL vous permet de définir les contraintes sur les colonnes |
|---|
| 405 |
et les tables. Les contraintes vous donnent autant de contrôle sur les |
|---|
| 406 |
données de vos tables que vous désirez. Si un utilisateur tente de stocker |
|---|
| 407 |
des données dans une colonne qui violerait un contrainte, une erreur est |
|---|
| 408 |
soulevée. Ceci s'applique même si la valeur vient de la définition de la |
|---|
| 409 |
valeur par défaut. |
|---|
| 410 |
</para> |
|---|
| 411 |
|
|---|
| 412 |
<sect2> |
|---|
| 413 |
<title>Contraintes de Vérification</title> |
|---|
| 414 |
|
|---|
| 415 |
<indexterm> |
|---|
| 416 |
<primary>contrainte de vérification</primary> |
|---|
| 417 |
</indexterm> |
|---|
| 418 |
|
|---|
| 419 |
<indexterm> |
|---|
| 420 |
<primary>contrainte</primary> |
|---|
| 421 |
<secondary>vérification</secondary> |
|---|
| 422 |
</indexterm> |
|---|
| 423 |
|
|---|
| 424 |
<para> |
|---|
| 425 |
Une contrainte de vérification est le type de contrainte le plus |
|---|
| 426 |
générique qui soit. Elle vous permet de spécifier l'expression |
|---|
| 427 |
que doit satisfaire la valeur d'une certaine colonne. Par exemple, |
|---|
| 428 |
pour obliger des prix de produits positifs, on pourrait utiliser: |
|---|
| 429 |
<programlisting> |
|---|
| 430 |
CREATE TABLE produits ( |
|---|
| 431 |
no_produit integer, |
|---|
| 432 |
nom text, |
|---|
| 433 |
prix numeric <emphasis>CHECK (prix > 0)</emphasis> |
|---|
| 434 |
); |
|---|
| 435 |
</programlisting> |
|---|
| 436 |
</para> |
|---|
| 437 |
|
|---|
| 438 |
<para> |
|---|
| 439 |
Comme vous pouvez le voir, la définition de contrainte vient après |
|---|
| 440 |
le type de données comme les définitions de valeur par défaut. Les |
|---|
| 441 |
valeurs par défaut et les contraintes peuvent être données dans |
|---|
| 442 |
n'importe quel ordre. Une contrainte de vérification s'utilise avec |
|---|
| 443 |
le mot clé <literal>CHECK</literal> suivi d'une expression entre |
|---|
| 444 |
parenthèses. L'expression de contrainte de vérification peut |
|---|
| 445 |
impliquer la colonne ainsi contrainte, sinon la contrainte n'aurait |
|---|
| 446 |
pas beaucoup de sens. |
|---|
| 447 |
</para> |
|---|
| 448 |
|
|---|
| 449 |
<indexterm> |
|---|
| 450 |
<primary>contrainte</primary> |
|---|
| 451 |
<secondary>nom</secondary> |
|---|
| 452 |
</indexterm> |
|---|
| 453 |
|
|---|
| 454 |
<para> |
|---|
| 455 |
Vous pouvez aussi donner à la contrainte un nom diffèrent. Ceci |
|---|
| 456 |
clarifie les messages d'erreur et vous permet de faire référence |
|---|
| 457 |
à la contrainte lorsque vous avez besoin de la modifier. |
|---|
| 458 |
La syntaxe est: |
|---|
| 459 |
<programlisting> |
|---|
| 460 |
CREATE TABLE produits ( |
|---|
| 461 |
no_produit integer, |
|---|
| 462 |
nom text, |
|---|
| 463 |
prix numeric <emphasis>CONSTRAINT positive_price</emphasis> CHECK (prix > 0) |
|---|
| 464 |
); |
|---|
| 465 |
</programlisting> |
|---|
| 466 |
Alors, pour spécifier une contrainte nommée, utilisez le mot-clé |
|---|
| 467 |
<literal>CONSTRAINT</literal> suivi d'un identifiant et de la |
|---|
| 468 |
définition de contrainte. |
|---|
| 469 |
</para> |
|---|
| 470 |
|
|---|
| 471 |
<para> |
|---|
| 472 |
Une contrainte de vérification peut faire référence à plusieurs |
|---|
| 473 |
colonnes. Admettons que vous souhaitez stocker un prix normal et un |
|---|
| 474 |
prix de promotion et, être sur que le prix de |
|---|
| 475 |
promotion soit inférieur au prix normal. |
|---|
| 476 |
<programlisting> |
|---|
| 477 |
CREATE TABLE produits ( |
|---|
| 478 |
no_produit integer, |
|---|
| 479 |
nom text, |
|---|
| 480 |
prix numeric CHECK (prix > 0), |
|---|
| 481 |
prix_solde numeric CHECK (prix_solde > 0), |
|---|
| 482 |
CHECK (prix > prix_solde) |
|---|
| 483 |
); |
|---|
| 484 |
</programlisting> |
|---|
| 485 |
</para> |
|---|
| 486 |
|
|---|
| 487 |
<para> |
|---|
| 488 |
Les deux premières contraintes devrait vous être familières. La troisième |
|---|
| 489 |
utilise une nouvelle syntaxe. Elle n'est pas attachée à une colonne |
|---|
| 490 |
particulière, elle apparaît comme un élément distinct dans |
|---|
| 491 |
la liste de colonnes séparées par des virgules. Les définitions de |
|---|
| 492 |
colonnes et ces définitions de contraintes peut être définies dans |
|---|
| 493 |
un ordre quelconque. |
|---|
| 494 |
</para> |
|---|
| 495 |
|
|---|
| 496 |
<para> |
|---|
| 497 |
On dit que les deux premières contraintes sont des contraintes de |
|---|
| 498 |
colonnes tandis que la troisième est une contrainte de table parce |
|---|
| 499 |
qu'elle est écrite séparément, des définitions de colonnes tandis que |
|---|
| 500 |
l'inverse n'est pas forcément possible. L'exemple ci-dessus aurait |
|---|
| 501 |
pu s'écrire: |
|---|
| 502 |
<programlisting> |
|---|
| 503 |
CREATE TABLE produits ( |
|---|
| 504 |
no_produit integer, |
|---|
| 505 |
nom text, |
|---|
| 506 |
prix numeric, |
|---|
| 507 |
CHECK (prix > 0), |
|---|
| 508 |
prix_solde numeric, |
|---|
| 509 |
CHECK (prix_solde > 0), |
|---|
| 510 |
CHECK (prix > prix_solde) |
|---|
| 511 |
); |
|---|
| 512 |
</programlisting> |
|---|
| 513 |
ou même |
|---|
| 514 |
<programlisting> |
|---|
| 515 |
CREATE TABLE produits ( |
|---|
| 516 |
no_produit integer, |
|---|
| 517 |
nom text, |
|---|
| 518 |
prix numeric CHECK (prix > 0), |
|---|
| 519 |
prix_solde numeric, |
|---|
| 520 |
CHECK (prix_solde > 0 AND prix > prix_solde) |
|---|
| 521 |
); |
|---|
| 522 |
</programlisting> |
|---|
| 523 |
C'est une question de goût. |
|---|
| 524 |
</para> |
|---|
| 525 |
|
|---|
| 526 |
<indexterm> |
|---|
| 527 |
<primary>valeur nulle</primary> |
|---|
| 528 |
<secondary sortas="check constraints">avec contraintes de vérification</secondary> |
|---|
| 529 |
</indexterm> |
|---|
| 530 |
|
|---|
| 531 |
<para> |
|---|
| 532 |
Il faut noter qu'une contrainte de vérification est satisfaite si |
|---|
| 533 |
l'expression est évaluée à vrai ou la valeur nulle. Puisque la |
|---|
| 534 |
plupart des expressions seront évaluées à la valeur nulle si l'un |
|---|
| 535 |
des opérandes est NULL, elles n'empêchent pas les valeurs nulles |
|---|
| 536 |
dans les colonnes contraintes. Pour s'assurer qu'une colonne ne |
|---|
| 537 |
contient pas de valeurs nulles, la contrainte non-nulle décrite |
|---|
| 538 |
dans la section suivante devrait être utilisée. |
|---|
| 539 |
</para> |
|---|
| 540 |
</sect2> |
|---|
| 541 |
|
|---|
| 542 |
<sect2> |
|---|
| 543 |
<title>Contraintes Non Nulles</title> |
|---|
| 544 |
|
|---|
| 545 |
<indexterm> |
|---|
| 546 |
<primary>contrainte non nulle</primary> |
|---|
| 547 |
</indexterm> |
|---|
| 548 |
|
|---|
| 549 |
<indexterm> |
|---|
| 550 |
<primary>contrainte</primary> |
|---|
| 551 |
<secondary>NOT NULL</secondary> |
|---|
| 552 |
</indexterm> |
|---|
| 553 |
|
|---|
| 554 |
<para> |
|---|
| 555 |
Une contrainte non nulle dit simplement qu'une colonne ne peut |
|---|
| 556 |
pas prendre la valeur nulle. Un exemple de syntaxe: |
|---|
| 557 |
<programlisting> |
|---|
| 558 |
CREATE TABLE produits ( |
|---|
| 559 |
no_produit integer <emphasis>NOT NULL</emphasis>, |
|---|
| 560 |
nom text <emphasis>NOT NULL</emphasis>, |
|---|
| 561 |
prix numeric |
|---|
| 562 |
); |
|---|
| 563 |
</programlisting> |
|---|
| 564 |
</para> |
|---|
| 565 |
|
|---|
| 566 |
<para> |
|---|
| 567 |
Une contrainte non nulle est toujours écrite comme une contrainte de |
|---|
| 568 |
colonne. Une contrainte non nulle est l'équivalente fonctionnelle de |
|---|
| 569 |
créer une contrainte <literal>CHECK (<replaceable>nom_colonne</replaceable> |
|---|
| 570 |
IS NOT NULL)</literal>, mais dans <productname>PostgreSQL</productname>, |
|---|
| 571 |
créer une contrainte explicitement non nulle est plus efficace. |
|---|
| 572 |
L'inconvénient est que vous ne pouvez pas donner de noms explicites |
|---|
| 573 |
à des contraintes non nulles créées de cette manière. |
|---|
| 574 |
</para> |
|---|
| 575 |
|
|---|
| 576 |
<para> |
|---|
| 577 |
Bien sur, une colonne peut avoir plus d'une contrainte. Écrivez juste |
|---|
| 578 |
les contraintes les unes après les autres: |
|---|
| 579 |
<programlisting> |
|---|
| 580 |
CREATE TABLE produits ( |
|---|
| 581 |
no_produit integer NOT NULL, |
|---|
| 582 |
nom text NOT NULL, |
|---|
| 583 |
prix numeric NOT NULL CHECK (prix > 0) |
|---|
| 584 |
); |
|---|
| 585 |
</programlisting> |
|---|
| 586 |
L'ordre n'importe pas. Il ne détermine pas dans quel ordre les contraintes |
|---|
| 587 |
seront vérifiées. |
|---|
| 588 |
</para> |
|---|
| 589 |
|
|---|
| 590 |
<para> |
|---|
| 591 |
La contrainte <literal>NOT NULL</literal> a un opposé; la contrainte |
|---|
| 592 |
<literal>NULL</literal> . Ceci ne veut pas dire que la colonne doit |
|---|
| 593 |
être NULL, ce qui serait inutile. Au lieu, ceci définit le comportement |
|---|
| 594 |
par défaut que la colonne doit être nulle. La contrainte <literal>NULL |
|---|
| 595 |
</literal> n'est pas définie dans le standard SQL et ne devrait pas |
|---|
| 596 |
être utilisé dans des applications portables. (Elle n'a été ajoutée |
|---|
| 597 |
dans <productname>PostgreSQL</productname> que pour assurer la |
|---|
| 598 |
compatibilité avec d'autres bases de données.) Certains utilisateurs |
|---|
| 599 |
l'apprécient car elle facilite le fait d'activer une contrainte |
|---|
| 600 |
dans un fichier de script. Par exemple, vous pourriez commencer avec: |
|---|
| 601 |
<programlisting> |
|---|
| 602 |
CREATE TABLE produits ( |
|---|
| 603 |
no_produit integer NULL, |
|---|
| 604 |
nom text NULL, |
|---|
| 605 |
prix numeric NULL |
|---|
| 606 |
); |
|---|
| 607 |
</programlisting> |
|---|
| 608 |
et puis insérer le mot-clé <literal>NOT</literal> suivant vos besoins. |
|---|
| 609 |
</para> |
|---|
| 610 |
|
|---|
| 611 |
<tip> |
|---|
| 612 |
<para> |
|---|
| 613 |
Dans beaucoup de conceptions de bases de données, la majorité des |
|---|
| 614 |
colonnes devraient être marquées non nulle. |
|---|
| 615 |
</para> |
|---|
| 616 |
</tip> |
|---|
| 617 |
</sect2> |
|---|
| 618 |
|
|---|
| 619 |
<sect2> |
|---|
| 620 |
<title>Contraintes Uniques</title> |
|---|
| 621 |
|
|---|
| 622 |
<indexterm> |
|---|
| 623 |
<primary>contrainte unique</primary> |
|---|
| 624 |
</indexterm> |
|---|
| 625 |
|
|---|
| 626 |
<indexterm> |
|---|
| 627 |
<primary>contrainte</primary> |
|---|
| 628 |
<secondary>unique</secondary> |
|---|
| 629 |
</indexterm> |
|---|
| 630 |
|
|---|
| 631 |
<para> |
|---|
| 632 |
Les contraintes uniques garantissent que les données contenues dans |
|---|
| 633 |
la colonne ou un groupe de colonnes est unique par rapport à toutes |
|---|
| 634 |
les rangées dans la table. La syntaxe est: |
|---|
| 635 |
<programlisting> |
|---|
| 636 |
CREATE TABLE produits ( |
|---|
| 637 |
no_produit integer <emphasis>UNIQUE</emphasis>, |
|---|
| 638 |
nom text, |
|---|
| 639 |
prix numeric |
|---|
| 640 |
); |
|---|
| 641 |
</programlisting> |
|---|
| 642 |
est écrit comme contrainte de colonne et |
|---|
| 643 |
<programlisting> |
|---|
| 644 |
CREATE TABLE produits ( |
|---|
| 645 |
no_produit integer, |
|---|
| 646 |
nom text, |
|---|
| 647 |
prix numeric, |
|---|
| 648 |
<emphasis>UNIQUE (no_produit)</emphasis> |
|---|
| 649 |
); |
|---|
| 650 |
</programlisting> |
|---|
| 651 |
est écrit comme contrainte de table. |
|---|
| 652 |
</para> |
|---|
| 653 |
|
|---|
| 654 |
<para> |
|---|
| 655 |
Si une contrainte unique fait référence à un groupe de colonnes, |
|---|
| 656 |
celles-ci sont listées séparées par des virgules: |
|---|
| 657 |
<programlisting> |
|---|
| 658 |
CREATE TABLE exemple ( |
|---|
| 659 |
a integer, |
|---|
| 660 |
b integer, |
|---|
| 661 |
c integer, |
|---|
| 662 |
<emphasis>UNIQUE (a, c)</emphasis> |
|---|
| 663 |
); |
|---|
| 664 |
</programlisting> |
|---|
| 665 |
</para> |
|---|
| 666 |
|
|---|
| 667 |
<para> |
|---|
| 668 |
Il est aussi possible d'attribuer des noms à des contraintes uniques: |
|---|
| 669 |
<programlisting> |
|---|
| 670 |
CREATE TABLE produits ( |
|---|
| 671 |
no_produit integer <emphasis>CONSTRAINT must_be_different</emphasis> UNIQUE, |
|---|
| 672 |
nom text, |
|---|
| 673 |
prix numeric |
|---|
| 674 |
); |
|---|
| 675 |
</programlisting> |
|---|
| 676 |
</para> |
|---|
| 677 |
|
|---|
| 678 |
<indexterm> |
|---|
| 679 |
<primary>valeur nulle</primary> |
|---|
| 680 |
<secondary sortas="unique constraints">avec contrainte unique</secondary> |
|---|
| 681 |
</indexterm> |
|---|
| 682 |
|
|---|
| 683 |
<para> |
|---|
| 684 |
En général, une contrainte unique est violée lorsqu'il y'a (au |
|---|
| 685 |
moins) deux rangées dans une table ou la valeur de chacune des |
|---|
| 686 |
colonnes correspondantes qui font partie de la contrainte sont |
|---|
| 687 |
égales. Par contre, les valeurs nulles ne sont pas assimilées |
|---|
| 688 |
à une égalités dans cette situation. Ceci veut dire qu'il est possible |
|---|
| 689 |
de stocker un nombre illimité de rangées qui contiennent une |
|---|
| 690 |
valeur nulle dans au moins l'une des colonnes contraintes. Ce |
|---|
| 691 |
comportement est conforme au standard SQL mais nous avons |
|---|
| 692 |
été informé que d'autres bases SQL ne suivent pas cette règle. Alors, |
|---|
| 693 |
soyez prudents en développant des applications qui sont prévues |
|---|
| 694 |
pour être portable. |
|---|
| 695 |
</para> |
|---|
| 696 |
</sect2> |
|---|
| 697 |
|
|---|
| 698 |
<sect2> |
|---|
| 699 |
<title>Clés Primaires</title> |
|---|
| 700 |
|
|---|
| 701 |
<indexterm> |
|---|
| 702 |
<primary>clé primaire</primary> |
|---|
| 703 |
</indexterm> |
|---|
| 704 |
|
|---|
| 705 |
<indexterm> |
|---|
| 706 |
<primary>contrainte</primary> |
|---|
| 707 |
<secondary>clé primaire</secondary> |
|---|
| 708 |
</indexterm> |
|---|
| 709 |
|
|---|
| 710 |
<para> |
|---|
| 711 |
Techniquement, une contrainte de clé primaire est tout |
|---|
| 712 |
simplement une combinaison d'une contrainte unique et |
|---|
| 713 |
d'une contrainte non nulle. Donc, les définitions de |
|---|
| 714 |
tables suivantes accepteront les mêmes données: |
|---|
| 715 |
<programlisting> |
|---|
| 716 |
CREATE TABLE produits ( |
|---|
| 717 |
no_produit integer UNIQUE NOT NULL, |
|---|
| 718 |
nom text, |
|---|
| 719 |
prix numeric |
|---|
| 720 |
); |
|---|
| 721 |
</programlisting> |
|---|
| 722 |
|
|---|
| 723 |
<programlisting> |
|---|
| 724 |
CREATE TABLE produits ( |
|---|
| 725 |
no_produit integer <emphasis>PRIMARY KEY</emphasis>, |
|---|
| 726 |
name text, |
|---|
| 727 |
prix numeric |
|---|
| 728 |
); |
|---|
| 729 |
</programlisting> |
|---|
| 730 |
</para> |
|---|
| 731 |
|
|---|
| 732 |
<para> |
|---|
| 733 |
Les clés primaires peuvent contraindre sur plus d'une colonne; la |
|---|
| 734 |
syntaxe est semblable aux contraintes uniques: |
|---|
| 735 |
<programlisting> |
|---|
| 736 |
CREATE TABLE exemple ( |
|---|
| 737 |
a integer, |
|---|
| 738 |
b integer, |
|---|
| 739 |
c integer, |
|---|
| 740 |
<emphasis>PRIMARY KEY (a, c)</emphasis> |
|---|
| 741 |
); |
|---|
| 742 |
</programlisting> |
|---|
| 743 |
</para> |
|---|
| 744 |
|
|---|
| 745 |
<para> |
|---|
| 746 |
Une clé primaire indique qu'une colonne ou un groupe de colonnes peut |
|---|
| 747 |
être utilisé comme identifiant unique pour les rangées de la table. (Ceci |
|---|
| 748 |
est une conséquence directe de la définition d'une clé primaire. Notez |
|---|
| 749 |
qu'une contrainte unique ne donne pas par elle-même, un identifiant unique |
|---|
| 750 |
car elle n'exclut pas les valeurs nulles.) Ceci est pratique à la fois |
|---|
| 751 |
pour des raisons de documentation et pour les applications clientes. Par |
|---|
| 752 |
exemple, une application graphique qui permet de modifier les valeurs de |
|---|
| 753 |
rangées a probablement besoin de connaître la clé primaire d'une table pour |
|---|
| 754 |
pouvoir identifier les rangées de manière unique correctement. |
|---|
| 755 |
</para> |
|---|
| 756 |
|
|---|
| 757 |
<para> |
|---|
| 758 |
Une table peut avoir au mieux une clé primaire (tandis qu'elle peut |
|---|
| 759 |
avoir plusieurs contraintes uniques et non nulles). La théorie des |
|---|
| 760 |
bases de données relationnelles dit que chaque table doit avoir |
|---|
| 761 |
une clé primaire. Cette règle n'est pas appliquée par |
|---|
| 762 |
<productname>PostgreSQL</productname>, mais il vaut mieux la respecter |
|---|
| 763 |
autant que possible. |
|---|
| 764 |
</para> |
|---|
| 765 |
</sect2> |
|---|
| 766 |
|
|---|
| 767 |
<sect2 id="ddl-constraints-fk"> |
|---|
| 768 |
<title>Clés Étrangères</title> |
|---|
| 769 |
|
|---|
| 770 |
<indexterm> |
|---|
| 771 |
<primary>clé étrangère</primary> |
|---|
| 772 |
</indexterm> |
|---|
| 773 |
|
|---|
| 774 |
<indexterm> |
|---|
| 775 |
<primary>contrainte</primary> |
|---|
| 776 |
<secondary>clé étrangère</secondary> |
|---|
| 777 |
</indexterm> |
|---|
| 778 |
|
|---|
| 779 |
<indexterm> |
|---|
| 780 |
<primary>intégrité référentielle</primary> |
|---|
| 781 |
</indexterm> |
|---|
| 782 |
|
|---|
| 783 |
<para> |
|---|
| 784 |
Une contrainte de clé étrangère stipule que les valeurs dans cette |
|---|
| 785 |
colonne (ou un groupe de colonnes) doit correspondre aux valeurs |
|---|
| 786 |
apparaissant dans des rangées d'une autre table. |
|---|
| 787 |
Nous disons que ceci maintient l'<firstterm>intégrité |
|---|
| 788 |
référentielle</firstterm> entre deux tables liées. |
|---|
| 789 |
</para> |
|---|
| 790 |
|
|---|
| 791 |
<para> |
|---|
| 792 |
Disons que vous avez la table de produits que nous avons déjà utilisé plusieurs fois: |
|---|
| 793 |
<programlisting> |
|---|
| 794 |
CREATE TABLE produits ( |
|---|
| 795 |
no_produit integer PRIMARY KEY, |
|---|
| 796 |
name text, |
|---|
| 797 |
prix numeric |
|---|
| 798 |
); |
|---|
| 799 |
</programlisting> |
|---|
| 800 |
Disons aussi que vous avez une table stockant les commandes de |
|---|
| 801 |
ces produits. Nous voulons aussi nous assurer que la table des |
|---|
| 802 |
commandes ne contienne que des commandes concernant des produits |
|---|
| 803 |
qui existent réellement. Alors, nous définissons une contrainte |
|---|
| 804 |
de clé étrangère dans la table des commandes qui référence la |
|---|
| 805 |
table produit: |
|---|
| 806 |
<programlisting> |
|---|
| 807 |
CREATE TABLE orders ( |
|---|
| 808 |
order_id integer PRIMARY KEY, |
|---|
| 809 |
no_produit integer <emphasis>REFERENCES produits (no_produit)</emphasis>, |
|---|
| 810 |
quantity integer |
|---|
| 811 |
); |
|---|
| 812 |
</programlisting> |
|---|
| 813 |
Maintenant, il est impossible de créer des commandes avec une entrée |
|---|
| 814 |
<literal>no_produit</literal> qui n'apparaît pas dans la table produits. |
|---|
| 815 |
</para> |
|---|
| 816 |
|
|---|
| 817 |
<para> |
|---|
| 818 |
Nous disons que, dans cette situation, la table de commandes est la table |
|---|
| 819 |
<firstterm>référente</firstterm> et la table produits est la table |
|---|
| 820 |
<firstterm>référée</firstterm>. De la même façon, il y a des colonnes |
|---|
| 821 |
référentes et des colonnes référées. |
|---|
| 822 |
</para> |
|---|
| 823 |
|
|---|
| 824 |
<para> |
|---|
| 825 |
On peut aussi raccourcir la commande ci-dessus en |
|---|
| 826 |
<programlisting> |
|---|
| 827 |
CREATE TABLE orders ( |
|---|
| 828 |
order_id integer PRIMARY KEY, |
|---|
| 829 |
no_produit integer REFERENCES produits, |
|---|
| 830 |
quantity integer |
|---|
| 831 |
); |
|---|
| 832 |
</programlisting> |
|---|
| 833 |
parce qu'en l'absence d'une liste de colonnes, la clé primaire de la |
|---|
| 834 |
table référente est utilisée comme colonne référée. |
|---|
| 835 |
</para> |
|---|
| 836 |
|
|---|
| 837 |
<para> |
|---|
| 838 |
Une clé étrangère peut aussi contraindre et référencer un groupe de colonnes. |
|---|
| 839 |
Comme d'habitude, il faut aussi l'écrire sous forme de contrainte de table. |
|---|
| 840 |
Voici un exemple de syntaxe: |
|---|
| 841 |
<programlisting> |
|---|
| 842 |
CREATE TABLE t1 ( |
|---|
| 843 |
a integer PRIMARY KEY, |
|---|
| 844 |
b integer, |
|---|
| 845 |
c integer, |
|---|
| 846 |
<emphasis>FOREIGN KEY (b, c) REFERENCES other_table (c1, c2)</emphasis> |
|---|
| 847 |
); |
|---|
| 848 |
</programlisting> |
|---|
| 849 |
Bien sur, le nombre et le type des colonnes contraintes doit correspondre |
|---|
| 850 |
aux nombres et types des colonnes référées. |
|---|
| 851 |
</para> |
|---|
| 852 |
|
|---|
| 853 |
<para> |
|---|
| 854 |
Une table peut contenir plus d'une contrainte de clé étrangère. Ceci peut |
|---|
| 855 |
être utilisé pour implémenter des relations n à n entre tables. Disons |
|---|
| 856 |
que vous avez des tables contenant des produits et des commandes mais vous |
|---|
| 857 |
voulez maintenant autoriser une commande qui contient peut-être beaucoup |
|---|
| 858 |
de produits (ce que la structure ci-dessus ne permet pas). On pourrait |
|---|
| 859 |
utiliser cette structure de table: |
|---|
| 860 |
<programlisting> |
|---|
| 861 |
CREATE TABLE produits ( |
|---|
| 862 |
no_produit integer PRIMARY KEY, |
|---|
| 863 |
name text, |
|---|
| 864 |
prix numeric |
|---|
| 865 |
); |
|---|
| 866 |
|
|---|
| 867 |
CREATE TABLE orders ( |
|---|
| 868 |
order_id integer PRIMARY KEY, |
|---|
| 869 |
shipping_address text, |
|---|
| 870 |
... |
|---|
| 871 |
); |
|---|
| 872 |
|
|---|
| 873 |
CREATE TABLE order_items ( |
|---|
| 874 |
no_produit integer REFERENCES produits, |
|---|
| 875 |
order_id integer REFERENCES orders, |
|---|
| 876 |
quantity integer, |
|---|
| 877 |
PRIMARY KEY (no_produit, order_id) |
|---|
| 878 |
); |
|---|
| 879 |
</programlisting> |
|---|
| 880 |
Notez aussi que la clé primaire chevauche les clés étrangères dans la dernière table. |
|---|
| 881 |
</para> |
|---|
| 882 |
|
|---|
| 883 |
<indexterm> |
|---|
| 884 |
<primary>CASCADE</primary> |
|---|
| 885 |
<secondary>action clé étrangère</secondary> |
|---|
| 886 |
</indexterm> |
|---|
| 887 |
|
|---|
| 888 |
<indexterm> |
|---|
| 889 |
<primary>RESTRICT</primary> |
|---|
| 890 |
<secondary>action clé étrangère</secondary> |
|---|
| 891 |
</indexterm> |
|---|
| 892 |
|
|---|
| 893 |
<para> |
|---|
| 894 |
Nous savons que les clés étrangères n'autorisent pas la création |
|---|
| 895 |
de commandes qui ne sont pas liés à un produit. Et si un produit |
|---|
| 896 |
est retiré après qu'une commande qui y réfère soit créée ? SQL vous |
|---|
| 897 |
permet aussi de le spécifier. Intuitivement, nous avons plusieurs options: |
|---|
| 898 |
<itemizedlist spacing="compact"> |
|---|
| 899 |
<listitem><para>Interdire d'effacer un produit référé</para></listitem> |
|---|
| 900 |
<listitem><para>Effacer aussi les commandes</para></listitem> |
|---|
| 901 |
<listitem><para>Autre chose ?</para></listitem> |
|---|
| 902 |
</itemizedlist> |
|---|
| 903 |
</para> |
|---|
| 904 |
|
|---|
| 905 |
<para> |
|---|
| 906 |
Pour illustrer ce cas, implémentons la politique suivante sur |
|---|
| 907 |
l'exemple de relations n à n évoquée plus haut: Quand quelqu'un |
|---|
| 908 |
veut retirer un produit qui est encore référencé par un ordre |
|---|
| 909 |
(via <literal>ordre_items</literal>), on l'interdit. Si quelqu'un |
|---|
| 910 |
retire une commande, les éléments de l'ordre sont aussi retirés. |
|---|
| 911 |
<programlisting> |
|---|
| 912 |
CREATE TABLE produits ( |
|---|
| 913 |
no_produit integer PRIMARY KEY, |
|---|
| 914 |
name text, |
|---|
| 915 |
prix numeric |
|---|
| 916 |
); |
|---|
| 917 |
|
|---|
| 918 |
CREATE TABLE orders ( |
|---|
| 919 |
order_id integer PRIMARY KEY, |
|---|
| 920 |
shipping_address text, |
|---|
| 921 |
... |
|---|
| 922 |
); |
|---|
| 923 |
|
|---|
| 924 |
CREATE TABLE order_items ( |
|---|
| 925 |
no_produit integer REFERENCES produits <emphasis>ON DELETE RESTRICT</emphasis>, |
|---|
| 926 |
order_id integer REFERENCES orders <emphasis>ON DELETE CASCADE</emphasis>, |
|---|
| 927 |
quantity integer, |
|---|
| 928 |
PRIMARY KEY (no_produit, order_id) |
|---|
| 929 |
); |
|---|
| 930 |
</programlisting> |
|---|
| 931 |
</para> |
|---|
| 932 |
|
|---|
| 933 |
<para> |
|---|
| 934 |
Restreindre et mettre en cascade les effacements sont les deux options les plus récurrentes. |
|---|
| 935 |
<literal>RESTRICT</literal> peut aussi s'écrire <literal>NO |
|---|
| 936 |
ACTION</literal> et c'est aussi le cas par défaut si on ne |
|---|
| 937 |
précise rien du tout. Il y'a deux autres options pour ce qui devrait |
|---|
| 938 |
se passer sur les colonnes de clé étrangère lorsqu'une clé primaire |
|---|
| 939 |
est effacée : |
|---|
| 940 |
<literal>SET NULL</literal> et <literal>SET DEFAULT</literal>. |
|---|
| 941 |
Notez que ceci ne vous permet pas de passer outre ces contraintes. |
|---|
| 942 |
Par exemple, si une action précise <literal>SET DEFAULT</literal> |
|---|
| 943 |
mais que la valeur par défaut ne satisfait pas la clé étrangère, la |
|---|
| 944 |
suppression de la clé primaire peut échouer. |
|---|
| 945 |
</para> |
|---|
| 946 |
|
|---|
| 947 |
<para> |
|---|
| 948 |
Sur le même principe que <literal>ON DELETE</literal>, il y a aussi |
|---|
| 949 |
<literal>ON UPDATE</literal> qui est évoqué lorsqu'une clé primaire |
|---|
| 950 |
est modifiée (mise à jour). Les actions possibles sont les mêmes. |
|---|
| 951 |
</para> |
|---|
| 952 |
|
|---|
| 953 |
<para> |
|---|
| 954 |
Il y a plus d'informations sur la mise à jour et la suppression de données dans <xref |
|---|
| 955 |
linkend="dml">. |
|---|
| 956 |
</para> |
|---|
| 957 |
|
|---|
| 958 |
<para> |
|---|
| 959 |
Enfin, nous devrions dire que la clé étrangère peut référencer |
|---|
| 960 |
des colonnes qui sont soit une clé primaire ou former une contrainte unique. |
|---|
| 961 |
Si la clé étrangère référence une contrainte unique, il y a des |
|---|
| 962 |
possibilités supplémentaires selon que l'on souhaite faire correspondre |
|---|
| 963 |
les valeurs nulles. |
|---|
| 964 |
Ceux-ci sont expliqués dans la documentation de référence pour |
|---|
| 965 |
<xref linkend="sql-createtable" endterm="sql-createtable-title">. |
|---|
| 966 |
</para> |
|---|
| 967 |
</sect2> |
|---|
| 968 |
</sect1> |
|---|
| 969 |
|
|---|
| 970 |
<sect1 id="ddl-inherit"> |
|---|
| 971 |
<title>Héritage</title> |
|---|
| 972 |
|
|---|
| 973 |
<comment>Cette section doit être repensée. Une partie de cette |
|---|
| 974 |
information doit aller dans les chapitres suivants.</comment> |
|---|
| 975 |
|
|---|
| 976 |
<para> |
|---|
| 977 |
Créons deux tables. La table capitales contient les capitales |
|---|
| 978 |
d'état qui sont aussi des villes. Naturellement, la table |
|---|
| 979 |
capitales doit hériter de villes. |
|---|
| 980 |
|
|---|
| 981 |
<programlisting> |
|---|
| 982 |
CREATE TABLE villes ( |
|---|
| 983 |
name text, |
|---|
| 984 |
population float, |
|---|
| 985 |
altitude int -- (in ft) |
|---|
| 986 |
); |
|---|
| 987 |
|
|---|
| 988 |
CREATE TABLE capitales ( |
|---|
| 989 |
state char(2) |
|---|
| 990 |
) INHERITS (villes); |
|---|
| 991 |
</programlisting> |
|---|
| 992 |
|
|---|
| 993 |
Dans ce cas une rangée de capitales <firstterm>hérite</firstterm> tout |
|---|
| 994 |
les attributs (nom, population, et altitude) de son parent |
|---|
| 995 |
villes. Le type de l'attribut name est |
|---|
| 996 |
<type>text</type>, un type natif de <productname>PostgreSQL</productname> |
|---|
| 997 |
pour des chaînes de caractères de longueur variable. Le type de l'attribut |
|---|
| 998 |
population est |
|---|
| 999 |
<type>float</type>, un type natif de <productname>PostgreSQL</productname> |
|---|
| 1000 |
pour les nombres flottants de précision double. Les capitales d'états ont |
|---|
| 1001 |
un attribut supplémentaire state qui donne leur état. Dans <productname>PostgreSQL</productname>, |
|---|
| 1002 |
une table peut hériter de zéro tables ou plus et une requête peut référencer |
|---|
| 1003 |
toutes les rangées d'une table ou toutes les rangées d'une table plus celles de |
|---|
| 1004 |
ses descendants. |
|---|
| 1005 |
|
|---|
| 1006 |
<note> |
|---|
| 1007 |
<para> |
|---|
| 1008 |
La hiérarchie d'héritage est en fait un graphe acyclique dirigé. |
|---|
| 1009 |
</para> |
|---|
| 1010 |
</note> |
|---|
| 1011 |
</para> |
|---|
| 1012 |
|
|---|
| 1013 |
<para> |
|---|
| 1014 |
Par exemple, la requête suivante cherche les noms de toutes les villes, |
|---|
| 1015 |
y compris les capitales d'état, qui se situent à une altitude de plus |
|---|
| 1016 |
de 500 pieds: |
|---|
| 1017 |
|
|---|
| 1018 |
<programlisting> |
|---|
| 1019 |
SELECT name, altitude |
|---|
| 1020 |
FROM villes |
|---|
| 1021 |
WHERE altitude > 500; |
|---|
| 1022 |
</programlisting> |
|---|
| 1023 |
|
|---|
| 1024 |
qui retourne: |
|---|
| 1025 |
|
|---|
| 1026 |
<programlisting> |
|---|
| 1027 |
name | altitude |
|---|
| 1028 |
-----------+---------- |
|---|
| 1029 |
Las Vegas | 2174 |
|---|
| 1030 |
Mariposa | 1953 |
|---|
| 1031 |
Madison | 845 |
|---|
| 1032 |
</programlisting> |
|---|
| 1033 |
</para> |
|---|
| 1034 |
|
|---|
| 1035 |
<para> |
|---|
| 1036 |
D'un autre côté, la requête suivante cherche toutes |
|---|
| 1037 |
les villes qui ne sont pas des capitales d'état et |
|---|
| 1038 |
qui sont situés à une altitude de plus de 500 pieds: |
|---|
| 1039 |
|
|---|
| 1040 |
<programlisting> |
|---|
| 1041 |
SELECT name, altitude |
|---|
| 1042 |
FROM ONLY villes |
|---|
| 1043 |
WHERE altitude > 500; |
|---|
| 1044 |
|
|---|
| 1045 |
name | altitude |
|---|
| 1046 |
-----------+---------- |
|---|
| 1047 |
Las Vegas | 2174 |
|---|
| 1048 |
Mariposa | 1953 |
|---|
| 1049 |
</programlisting> |
|---|
| 1050 |
</para> |
|---|
| 1051 |
|
|---|
| 1052 |
<para> |
|---|
| 1053 |
Ici, le <quote>ONLY</quote> avant villes indique que la requête ne devrait |
|---|
| 1054 |
être lancée que sur villes et non les tables en dessous de villes dans la |
|---|
| 1055 |
hiérarchie d'héritage. Beaucoup des commandes donc nous avons déjà discuté |
|---|
| 1056 |
-- <command>SELECT</command>, <command>UPDATE</command> et <command>DELETE</command> -- |
|---|
| 1057 |
gèrent cette syntaxe <quote>ONLY</quote>. |
|---|
| 1058 |
</para> |
|---|
| 1059 |
|
|---|
| 1060 |
<para> |
|---|
| 1061 |
Dans certain cas, vous souhaiterez savoir dans quel table |
|---|
| 1062 |
provient une rangée donnée. Il y a une colonne système appelée |
|---|
| 1063 |
<structfield>TABLEOID</structfield> dans chaque table qui peut vous |
|---|
| 1064 |
donner la table d'origine: |
|---|
| 1065 |
|
|---|
| 1066 |
<programlisting> |
|---|
| 1067 |
SELECT c.tableoid, c.name, c.altitude |
|---|
| 1068 |
FROM villes c |
|---|
| 1069 |
WHERE c.altitude > 500; |
|---|
| 1070 |
</programlisting> |
|---|
| 1071 |
|
|---|
| 1072 |
qui renvoie : |
|---|
| 1073 |
|
|---|
| 1074 |
<programlisting> |
|---|
| 1075 |
tableoid | name | altitude |
|---|
| 1076 |
----------+-----------+---------- |
|---|
| 1077 |
139793 | Las Vegas | 2174 |
|---|
| 1078 |
139793 | Mariposa | 1953 |
|---|
| 1079 |
139798 | Madison | 845 |
|---|
| 1080 |
</programlisting> |
|---|
| 1081 |
|
|---|
| 1082 |
(Si vous essayez de reproduire cet exemple, vous obtiendrez probablement des OIDs numériques différents.) |
|---|
| 1083 |
En faisant une jointure avec <structname>pg_class</structname>, vous pourrez voir les noms de tables actuelles: |
|---|
| 1084 |
|
|---|
| 1085 |
<programlisting> |
|---|
| 1086 |
SELECT p.relname, c.name, c.altitude |
|---|
| 1087 |
FROM villes c, pg_class p |
|---|
| 1088 |
WHERE c.altitude > 500 and c.tableoid = p.oid; |
|---|
| 1089 |
</programlisting> |
|---|
| 1090 |
|
|---|
| 1091 |
ce qui retourne: |
|---|
| 1092 |
|
|---|
| 1093 |
<programlisting> |
|---|
| 1094 |
relname | name | altitude |
|---|
| 1095 |
-----------+-----------+---------- |
|---|
| 1096 |
villes | Las Vegas | 2174 |
|---|
| 1097 |
villes | Mariposa | 1953 |
|---|
| 1098 |
capitales | Madison | 845 |
|---|
| 1099 |
</programlisting> |
|---|
| 1100 |
|
|---|
| 1101 |
</para> |
|---|
| 1102 |
|
|---|
| 1103 |
<note> |
|---|
| 1104 |
<title>Obsolète</title> |
|---|
| 1105 |
<para> |
|---|
| 1106 |
Dans les versions précédentes de <productname>PostgreSQL</productname>, le |
|---|
| 1107 |
comportement par défaut était de ne pas inclure les tables filles dans les requêtes. |
|---|
| 1108 |
Ceci provoquait des erreurs et était aussi en violation du standard SQL99. |
|---|
| 1109 |
Sous l'ancienne syntaxe, pour avoir les sous-tables, il fallait |
|---|
| 1110 |
ajouter <literal>*</literal> au nom de la table. |
|---|
| 1111 |
Par exemple |
|---|
| 1112 |
<programlisting> |
|---|
| 1113 |
SELECT * from villes*; |
|---|
| 1114 |
</programlisting> |
|---|
| 1115 |
Vous pouvez toujours préciser explicitement les tables filles en rajoutant |
|---|
| 1116 |
<literal>*</literal> en plus de spécifier explicitement de ne pas parcourir |
|---|
| 1117 |
les tables filles en écrivant <quote>ONLY</quote>. Mais, a partir de la |
|---|
| 1118 |
version 7.1, le comportement par défaut pour un nom de table brut est de |
|---|
| 1119 |
parcourir aussi ses tables filles bien qu'avant, la norme était de ne |
|---|
| 1120 |
pas le faire. Pour retrouver l'ancien comportement, mettez l'option |
|---|
| 1121 |
de configuration <literal>SQL_Inheritance</literal> à off, i.e., |
|---|
| 1122 |
<programlisting> |
|---|
| 1123 |
SET SQL_Inheritance TO OFF; |
|---|
| 1124 |
</programlisting> |
|---|
| 1125 |
ou ajoutez une ligne dans votre fichier <filename>postgresql.conf</filename>. |
|---|
| 1126 |
</para> |
|---|
| 1127 |
</note> |
|---|
| 1128 |
|
|---|
| 1129 |
<para> |
|---|
| 1130 |
Une limite de la fonctionnalité d'héritage est que les indexes (y compris |
|---|
| 1131 |
les contraintes uniques) et les contraintes de clés étrangères ne s'appliquent |
|---|
| 1132 |
qu'aux tables seules et non leurs descendants d'héritage. Donc, dans l'exemple |
|---|
| 1133 |
précédant, spécifier qu'une colonne d'une autre table <literal>REFERENCES villes(name)</literal> |
|---|
| 1134 |
autorisera l'autre table a contenir des noms de villes mais pas de noms de capitales. |
|---|
| 1135 |
Cette lacune sera probablement corrigée dans une future version. |
|---|
| 1136 |
</para> |
|---|
| 1137 |
</sect1> |
|---|
| 1138 |
|
|---|
| 1139 |
<sect1 id="ddl-alter"> |
|---|
| 1140 |
<title>Modification des Tables</title> |
|---|
| 1141 |
|
|---|
| 1142 |
<indexterm zone="ddl-alter"> |
|---|
| 1143 |
<primary>table</primary> |
|---|
| 1144 |
<secondary>modification</secondary> |
|---|
| 1145 |
</indexterm> |
|---|
| 1146 |
|
|---|
| 1147 |
<para> |
|---|
| 1148 |
Quand on crée une table et qu'on se rend compte qu'on a fait une erreur |
|---|
| 1149 |
ou que les besoins de l'application ont changés, on peut alors effacer |
|---|
| 1150 |
la table et la recréer. Mais ceci n'est pas pratique si la table contient |
|---|
| 1151 |
déjà des données ou si la table est référencée par d'autres objets de la base |
|---|