14 votes

Stockage des valeurs hexadécimales en tant que valeurs binaires dans MySQL

Je pensais à la façon dont je stocke les mots de passe dans ma base de données : des chaînes SHA1 salées de façon appropriée dans un champ CHAR(40). Cependant, étant donné que les données de caractère dans ce champ ne sont en fait qu'une représentation hexadécimale d'un nombre de 160 bits, j'ai pensé qu'il serait préférable de les stocker en tant que BINARY(20).

CREATE TABLE users (
    password BINARY(20)
    /* snip */
);

INSERT INTO users (password) VALUES (UNHEX(SHA1('mypassword'));

De mon point de vue, l'un des avantages de cette approche est qu'elle réduit de moitié la taille de ce champ, mais j'imagine qu'il y a probablement aussi des inconvénients.

Quel est votre avis ?

28voto

wsorenson Points 2364

Nous avons utilisé le format binaire pour une tonne d'identifiants différents dans notre base de données afin d'économiser de l'espace, car la majorité de nos données étaient constituées de ces identifiants. Comme il ne semble pas que vous ayez besoin d'économiser de l'espace (puisqu'il ne s'agit que de mots de passe, et non d'un autre élément à grande échelle), je ne vois pas de raison d'utiliser le binaire ici.

Le plus gros problème que nous avons rencontré est que des données binaires apparaissent constamment dans la console (chaque fois que vous tapez select *, vous entendez un million de bips), et vous devez toujours faire select HEX() ou insert UNHEX(), ce qui est pénible.

Enfin, si vous mélangez (par erreur) des données binaires et HEX/UNHEX et que vous effectuez une jointure sur cette valeur, vous risquez de faire correspondre des enregistrements que vous n'aviez pas l'intention de faire correspondre.

9voto

Jeffrey Hulten Points 651

Voici ma répartition :

  1. Si vous utilisez des chaînes au lieu de binaires, utilisez un champ de longueur fixe. Étant donné que les algorithmes de hachage produisent tous une longueur fixe, vous pouvez gagner de la place.
  2. Étant donné que vous n'effectuez qu'une comparaison d'égalité, il n'est pas nécessaire d'utiliser des index. Les champs binaires n'ont pas de type de collation ni de jeu de caractères.
  3. Les types de colonnes BINARY ne présentent pas d'inconvénients particuliers en matière de stockage, contrairement aux BLOB.
  4. Chaque caractère hexadécimal représente 4 bits dans les 8 (ou 7) bits qu'il consomme. Cela signifie que le stockage binaire est deux fois plus efficace.
  5. IMPORTANT : à moins que vous ne travailliez dans un système embarqué où chaque octet compte, ne le faites pas. Le fait de disposer d'une représentation en caractères vous permettra de mieux déboguer. De plus, chaque fois qu'un développeur travaille sur un problème de ce type, je me demande pourquoi. Chaque décision architecturale de ce type comporte des compromis et celle-ci ne semble pas apporter de valeur ajoutée à votre projet.
  6. Vous pouvez toujours convertir en BINAIRE plus tard avec un simple script.

En bref, utilisez un champ de texte de longueur fixe. Il n'y a aucun avantage à compter les octets dans le monde actuel, surtout lorsque le changement est facile à réaliser.

2voto

Asaph Points 56989

Les économies d'espace sur le disque dur réalisées en stockant vos mots de passe hachés sous forme binaire plutôt que sous forme varchar sont probablement insignifiantes. Combien d'utilisateurs sont susceptibles de figurer dans cette table ? Multipliez ce chiffre par la différence d'espace entre BINARY(20) y VARCHAR(n) et je pense que vous constaterez qu'il ne s'agit pas d'une économie importante. Personnellement, je préfère la représentation hexagonale parce qu'au moins je peux la taper dans une requête si je fais une opération ad hoc pendant le développement ou si j'écris un test unitaire pour valider les opérations liées au mot de passe. L'hexadécimal est un peu plus lisible que le binaire s'il m'arrive de charger un vidage de données dans un éditeur de texte, etc. En fin de compte, la représentation hexagonale serait plus pratique pendant le cycle de développement.

2voto

lexmooze Points 191

Si vous voulez un moyen simple de stocker des données binaires en SQL... vous pouvez les convertir en hexadécimales avant. Consultez cette page : http://kekoav.com/blog/36-computers/58-uuids-as-primary-keys-in-mysql.html

Convertissez en hexadécimal, enlevez le "-" et mettez "0x" devant la chaîne. Mysql comprendra qu'il s'agit d'un contenu d'octets.

Exemple :

INSERT INTO users SET password=0x1e8ef774581c102cbcfef1ab81872213

1voto

David M Points 2605

Pourquoi réinventer la roue ? Pourquoi ne pas utiliser CHAR(41) comme la table `mysql.user' ? C'est un format bien connu, donc les futurs responsables de la maintenance n'auront pas à se gratter la tête à cause de votre système spécial ? Facilitez la tâche à tout le monde en notant simplement "comme les mots de passe MySQL".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X