69
4.1 Modélisation de la base de données
Vous générez les valeurs de GUID dans vos colonnes UNIQUEIDENTIFIER à l’aide
de la fonction T-SQL NEWID(), que vous pouvez placer dans la contrainte DEFAULT de
la colonne. Si vous devez utiliser un UNIQUEIDENTIFIER et que vous voulez l’indexer,
vous pouvez utiliser (seulement en contrainte DEFAULT) la fonction NEWSEQUENTIALID(), qui génère un GUID plus grand que tous ceux présents dans la colonne. Cette
fonction a été créée pour éviter la fragmentation. Toutefois, si vous l’utilisez, vous
perdez l’avantage de la génération aléatoire, et un pirate intelligent pourra facilement deviner des GUID précédents. Dans les problématiques d’identifiant Web, il
vaut mieux programmer dans l’application cliente un algorithme de génération de
hachage à partir des identifiants de la base de données, pour les protéger des curieux.
Cela permet de conserver de bonnes performances du côté SQL Server.
Objets larges
SQL Server proposait les types TEXT, NTEXT et IMAGE, pour stocker respectivement des
objets larges de type chaînes ANSI et UNICODE, et des objets binaires, comme des
documents en format propriétaire, des fichiers image ou son. Ces types sont toujours
à disposition, mais ils sont obsolètes et remplacés par (N)VARCHAR(MAX) et VARBINARY(MAX). Comme leurs anciens équivalents, ils permettent de stocker jusqu’à 2 Go
de données (2^31 − 1 octets, précisément), mais leur comportement est sensiblement différent. Ces types sont ce qu’on appelle des LOB (Large Objects, objets
larges), bien que dans les BOL, vous verrez utiliser le nom « valeurs larges » (large
values) pour les nouveaux types (le type XML en fait aussi partie). Ils sont stockés à
même le fichier de données, dans des pages de 8 Ko organisées d’une façon particulière.
Les types TEXT, NTEXT et IMAGE, conformément à leur comportement dans SQL
Server 2000, placent dans la ligne de la table un pointeur de 16 octets vers une structure externe à la page. Cette structure est organisée en arbre équilibré (B-Tree),
comme un index, pour permettre un accès rapide aux différentes positions à l’intérieur du LOB. Lors de toute restitution de la ligne, le moteur de stockage doit donc
suivre ce pointeur et récupérer ces pages, même si la colonne ne contient que quelques octets. En SQL Server 2000, nous avions un moyen de forcer SQL Server à
stocker dans la page elle-même le contenu du LOB, s’il ne dépassait pas une certaine
taille, à l’aide de la procédure stockée sp_tableoption. Cette option existe toujours
sur SQL Server 2005 et peut être utile pour optimiser des colonnes (N)TEXT. Par
exemple :
EXEC sp_tableoption nomtable 'text in row', taille;
où taille est la taille en octets des données à inclure dans la page, dans une plage
allant de 24 à 7 000 (la chaîne 'ON' est aussi acceptée, elle correspond à une taille
de 256 octets). Dès que cette option est activée, si le contenu de la colonne est inférieur à la taille indiquée, il est inséré dans la page, comme une valeur traditionnelle.
Pourquoi la limite inférieure est-elle de 24 octets ? Simplement parce que, quand
'text in row' est activé, le moteur de stockage ne place plus de pointeur vers la
structure LOB. Si la donnée insérée est plus grande que la taille maximum spécifiée,
il inscrira dans la page la racine de la structure B-Tree du LOB, qui pèse… 24 bits.
4.1 Modélisation de la base de données
Vous générez les valeurs de GUID dans vos colonnes UNIQUEIDENTIFIER à l’aide
de la fonction T-SQL NEWID(), que vous pouvez placer dans la contrainte DEFAULT de
la colonne. Si vous devez utiliser un UNIQUEIDENTIFIER et que vous voulez l’indexer,
vous pouvez utiliser (seulement en contrainte DEFAULT) la fonction NEWSEQUENTIALID(), qui génère un GUID plus grand que tous ceux présents dans la colonne. Cette
fonction a été créée pour éviter la fragmentation. Toutefois, si vous l’utilisez, vous
perdez l’avantage de la génération aléatoire, et un pirate intelligent pourra facilement deviner des GUID précédents. Dans les problématiques d’identifiant Web, il
vaut mieux programmer dans l’application cliente un algorithme de génération de
hachage à partir des identifiants de la base de données, pour les protéger des curieux.
Cela permet de conserver de bonnes performances du côté SQL Server.
Objets larges
SQL Server proposait les types TEXT, NTEXT et IMAGE, pour stocker respectivement des
objets larges de type chaînes ANSI et UNICODE, et des objets binaires, comme des
documents en format propriétaire, des fichiers image ou son. Ces types sont toujours
à disposition, mais ils sont obsolètes et remplacés par (N)VARCHAR(MAX) et VARBINARY(MAX). Comme leurs anciens équivalents, ils permettent de stocker jusqu’à 2 Go
de données (2^31 − 1 octets, précisément), mais leur comportement est sensiblement différent. Ces types sont ce qu’on appelle des LOB (Large Objects, objets
larges), bien que dans les BOL, vous verrez utiliser le nom « valeurs larges » (large
values) pour les nouveaux types (le type XML en fait aussi partie). Ils sont stockés à
même le fichier de données, dans des pages de 8 Ko organisées d’une façon particulière.
Les types TEXT, NTEXT et IMAGE, conformément à leur comportement dans SQL
Server 2000, placent dans la ligne de la table un pointeur de 16 octets vers une structure externe à la page. Cette structure est organisée en arbre équilibré (B-Tree),
comme un index, pour permettre un accès rapide aux différentes positions à l’intérieur du LOB. Lors de toute restitution de la ligne, le moteur de stockage doit donc
suivre ce pointeur et récupérer ces pages, même si la colonne ne contient que quelques octets. En SQL Server 2000, nous avions un moyen de forcer SQL Server à
stocker dans la page elle-même le contenu du LOB, s’il ne dépassait pas une certaine
taille, à l’aide de la procédure stockée sp_tableoption. Cette option existe toujours
sur SQL Server 2005 et peut être utile pour optimiser des colonnes (N)TEXT. Par
exemple :
EXEC sp_tableoption nomtable 'text in row', taille;
où taille est la taille en octets des données à inclure dans la page, dans une plage
allant de 24 à 7 000 (la chaîne 'ON' est aussi acceptée, elle correspond à une taille
de 256 octets). Dès que cette option est activée, si le contenu de la colonne est inférieur à la taille indiquée, il est inséré dans la page, comme une valeur traditionnelle.
Pourquoi la limite inférieure est-elle de 24 octets ? Simplement parce que, quand
'text in row' est activé, le moteur de stockage ne place plus de pointeur vers la
structure LOB. Si la donnée insérée est plus grande que la taille maximum spécifiée,
il inscrira dans la page la racine de la structure B-Tree du LOB, qui pèse… 24 bits.
