Manipuler les masques de bits

Fabien Celaia

- Titre : Manipuler les masques de bits

- Auteur : Fabien Celaia

- Parution : 3 juillet 2004

- Mise à jour : 4 juillet 2004

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2013 Fabien Celaia. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Présentation

I - Présentation

Certains champs, surtout dans les tables système de MS-SQL ou de Sybase ASE, stockent des informations sous forme de masque de bits. Souvent l'utilisateur rechigne à utiliser ce genre de champ par méconnaissance. Ce petit document a pour but de vous familiariser avec ce type de données. Vous approuverez rapidement qu'un masque de bits n'est pas si compliqué qu'il en a l'air…

Quelques exemples de champs des tables système :

Moteur

Table

Colonne

Sybase ASE
MS-SQL

master..sysdatabases

status
status2

Sybase ASE

master..sysdatabases

status3

MS-SQL

master..sysdatabases

category

MS-SQL

master..sysdatabases

category

Sybase ASE
MS-SQL

master..sysdevices

status
cntrltype

Sybase ASE

master..syssegments

status

L'idée de base est de stocker dans un champ unique plusieurs informations.

Imaginons que l'on veuille spécifier quatre options cumulables. Un enregistrement pourrait donc avoir zéro à quatre options. La façon lisible que l'on utilise généralement est la suivante :

create table MasqueBit

(

MonChamp vachar(30) primary key,

option1 bit,

option2 bit,

option3 bit,

option4 bits
)

On aurait donc des tuples de type {"monchamp1",1,1,0,1} ou encore {"monchamp2",0,1,0,0}. Le problème majeur de cette façon de faire et qu'un nombre important d'options génère autant de colonnes dans la table. De plus, l'ajout d'une option supplémentaire modifie la structure (le DDL, pour les initiés) de la table, avec tout ce que cela implique comme risque de cas de bord lorsque l'on touche aux tables système.

L'idée du masque est de stocker tout le quadruplet final dans un champ binaire, soit - en reprenant notre exemple précédent - {"monchamp1",1101} et {"monchamp2",0100}.

Ne pouvant stocker du binaire sous cette forme, on a imaginé remplacer cette mantisse par le chiffre correspondant en élevant chacun des bits activés à sa puissance de 2, soit

monchamp1 => 1101 => 1*23+1*22 + 0*21+1*20 = 13
monchamp2 => 0100 => 0*23+1*22 + 0*21+0*20 = 4

Maintenant que nous stockons toute l'info dans un champ unique, il faut appliquer un masque binaire pour retrouver l'information qui nous intéresse. Si l'on désire les valeurs dont l'option 4 est activée, nous ferons donc

SELECT *

FROM MasqueBit

WHERE OptionBit & 1 = 1

Si on désire les options 2 et 4 activées, on fera donc

SELECT *

FROM MasqueBit

WHERE OptionBit & 5 = 5

5 étant égal à 4 + 1 = 0x23+1*22+0*21+1*20, soit notre fameux masque 0101.

L'opérateur & permet donc d'appliquer le masque sur le champ numérique afin de retourner la valeur cherchée si elle existe, ou sinon 0.

Vous voyez par vous-même que tous ces champs incongrus n'auront bientôt plus de secret pour vous et votre table de multiplication de 2…

Autre lien sur ce sujet Une seule colonne, plusieurs données… par SQLPro.