68
Chapitre 4. Optimisation des objets et de la structure de la base de données
par rapport à la valeur stockée. C’est évidemment un type à éviter absolument, tant
par son impact sur les performances que par son laxisme en terme de contraintes de
données. Le type sql_variant peut contenir 8 016 octets, il est donc indexable à vos
risques et périls (une clé d’index supérieure à 900 octets générera une erreur). On ne
peut le concaténer, ni l’utiliser dans une colonne calculée, ou un LIKE... Bref,
oubliez-le.
Le type de données UNIQUEIDENTIFIER correspond à un GUID (Globally Unique
Identifier), une valeur codée sur 16 octets générés à partir d’un algorithme qui la rend
unique à travers le monde et au delà (le GUID n’est pas garanti unique, mais les probabilités que deux GUID identiques puissent être générés sont statistiquement infinitésimales). Vous voyez des GUID un peu partout dans le monde Microsoft,
notamment dans la base de registre. On entend en général par le terme GUID,
l’implémentation par Microsoft de la norme UUID (Universally Unique Identifier),
qui calcule notamment une partie de la chaîne avec l’adresse matérielle (MAC) de
l’ordinateur. Un exemple de GUID serait :
CC61D24F-125B-4347-BB37-9E7908613279.
Certaines personnes l’utilisent pour générer des clés primaires de tables, profitant
de l’unicité globale du GUID pour obtenir une clé unique à travers différentes tables
ou bases de données, ou pour générer des identifiants non séquentiels, par exemple
pour un identifiant d’utilisateur sur une application Web, et ainsi éviter qu’un pirate
ne devine l’ID d’un autre utilisateur. En termes de performances, utiliser un UNIQUEIDENTIFIER en clé primaire est une très mauvaise idée, à plus forte raison si l’index
sur la clé est clustered. Cela tient bien sûr à la taille de la donnée (vous verrez dans le
chapitre 6 que tous les index incorporent la clé de l’index clustered). C’est aussi un
excellent moyen de fragmenter la table : si vous créez un index clustered sur une
colonne où les données s’insèrent à des positions aléatoires, vous provoquez une
intense activité de séparation de pages (les pages doivent se séparer et déplacer une
partie de leurs lignes ailleurs, pour accommoder les nouvelles lignes insérées, plus de
détails dans le chapitre sur les index), donc une baisse de performances, ainsi qu’une
forte fragmentation, d’où une nouvelle baisse de performances. Enfin, cela a de fortes
chances d’augmenter significativement la taille de votre base, puisqu’une clé primaire est souvent déplacée dans plusieurs tables filles en clés étrangères. Tout cela
faisant 16 octets par clé, le stockage est plus lourd, les index plus gros, et les jointures
plus coûteuses pour les requêtes.
Si vous songez à utiliser des GUID dans une problématique de bases de données
dispersées, optez plutôt pour une clé primaire composite, à deux colonnes : une
colonne donnant un identifiant de serveur ou de base de données, et l’autre identifiant un compteur IDENTITY propre à la table. Vous aurez non seulement l’information de la base source de la ligne dans la clé, mais de plus celle-ci pèsera 5 ou
6 octets (un TINYINT ou SMALLINT pour l’ID de base, un INT pour l’ID de ligne) au
lieu de 16.
Chapitre 4. Optimisation des objets et de la structure de la base de données
par rapport à la valeur stockée. C’est évidemment un type à éviter absolument, tant
par son impact sur les performances que par son laxisme en terme de contraintes de
données. Le type sql_variant peut contenir 8 016 octets, il est donc indexable à vos
risques et périls (une clé d’index supérieure à 900 octets générera une erreur). On ne
peut le concaténer, ni l’utiliser dans une colonne calculée, ou un LIKE... Bref,
oubliez-le.
Le type de données UNIQUEIDENTIFIER correspond à un GUID (Globally Unique
Identifier), une valeur codée sur 16 octets générés à partir d’un algorithme qui la rend
unique à travers le monde et au delà (le GUID n’est pas garanti unique, mais les probabilités que deux GUID identiques puissent être générés sont statistiquement infinitésimales). Vous voyez des GUID un peu partout dans le monde Microsoft,
notamment dans la base de registre. On entend en général par le terme GUID,
l’implémentation par Microsoft de la norme UUID (Universally Unique Identifier),
qui calcule notamment une partie de la chaîne avec l’adresse matérielle (MAC) de
l’ordinateur. Un exemple de GUID serait :
CC61D24F-125B-4347-BB37-9E7908613279.
Certaines personnes l’utilisent pour générer des clés primaires de tables, profitant
de l’unicité globale du GUID pour obtenir une clé unique à travers différentes tables
ou bases de données, ou pour générer des identifiants non séquentiels, par exemple
pour un identifiant d’utilisateur sur une application Web, et ainsi éviter qu’un pirate
ne devine l’ID d’un autre utilisateur. En termes de performances, utiliser un UNIQUEIDENTIFIER en clé primaire est une très mauvaise idée, à plus forte raison si l’index
sur la clé est clustered. Cela tient bien sûr à la taille de la donnée (vous verrez dans le
chapitre 6 que tous les index incorporent la clé de l’index clustered). C’est aussi un
excellent moyen de fragmenter la table : si vous créez un index clustered sur une
colonne où les données s’insèrent à des positions aléatoires, vous provoquez une
intense activité de séparation de pages (les pages doivent se séparer et déplacer une
partie de leurs lignes ailleurs, pour accommoder les nouvelles lignes insérées, plus de
détails dans le chapitre sur les index), donc une baisse de performances, ainsi qu’une
forte fragmentation, d’où une nouvelle baisse de performances. Enfin, cela a de fortes
chances d’augmenter significativement la taille de votre base, puisqu’une clé primaire est souvent déplacée dans plusieurs tables filles en clés étrangères. Tout cela
faisant 16 octets par clé, le stockage est plus lourd, les index plus gros, et les jointures
plus coûteuses pour les requêtes.
Si vous songez à utiliser des GUID dans une problématique de bases de données
dispersées, optez plutôt pour une clé primaire composite, à deux colonnes : une
colonne donnant un identifiant de serveur ou de base de données, et l’autre identifiant un compteur IDENTITY propre à la table. Vous aurez non seulement l’information de la base source de la ligne dans la clé, mais de plus celle-ci pèsera 5 ou
6 octets (un TINYINT ou SMALLINT pour l’ID de base, un INT pour l’ID de ligne) au
lieu de 16.
