Choisir le bon algorithme dans la fonction HashBytes


20

Nous devons créer une valeur de hachage des données nvarchar à des fins de comparaison. Il existe plusieurs algorithmes de hachage disponibles dans T-SQL, mais lequel parmi les meilleurs dans ce scénario?

Nous voulons nous assurer que le risque d'avoir une valeur de hachage en double pour deux valeurs nvarchar différentes est le minimum. Sur la base de mes recherches sur Internet, MD5 semble le meilleur. Est-ce correct? MSDN nous renseigne (lien ci-dessous) sur les algorithmes disponibles, mais aucune description sur lequel pour quelles conditions?

HASHBYTES (Transact-SQL)

Nous devons joindre deux tables sur deux colonnes nvarchar (max). Comme vous pouvez l'imaginer, la requête prend du temps à s'exécuter. Nous avons pensé qu'il serait préférable de conserver la valeur de hachage de chaque donnée nvarchar (max) et de faire la jointure sur les valeurs de hachage plutôt que les valeurs nvarchar (max) qui sont des blobs. La question est de savoir quel algorithme de hachage fournit l'unicité, de sorte que nous ne courons pas le risque d'avoir une valeur de hachage pour plus d'un nvarchar (max).

Réponses:


18

La HASHBYTESfonction ne prend que 8 000 octets en entrée. Parce que vos entrées sont potentiellement plus grande que celle, des doublons dans la gamme du champ qui obtient haché va provoquer des collisions, quel que soit l'algorithme choisi. Considérez soigneusement la plage de données que vous prévoyez de hacher - l'utilisation des 4000 premiers caractères est le choix évident , mais peut-être pas le meilleur choix pour vos données.

Dans tous les cas, en raison de ce qu'est une fonction de hachage, même si les entrées sont de 8000 octets ou moins, la seule façon de garantir l'exactitude de 100% dans les résultats est de comparer les valeurs de base à un moment donné (lire: pas nécessairement en premier ). Période.

L'entreprise déterminera si une précision de 100% est requise ou non. Cela vous indiquera que (a) la comparaison des valeurs de base est requise , ou (b) vous devriez envisager de ne pas comparer les valeurs de base - combien de précision doit être échangée contre les performances.

Bien que les collisions de hachage soient possibles dans un ensemble d'entrée unique, elles sont extrêmement rares, quel que soit l'algorithme choisi. L'idée globale d'utiliser une valeur de hachage dans ce scénario est de réduire efficacement les résultats de jointure à un ensemble plus gérable, pour ne pas nécessairement arriver à l'ensemble final de résultats immédiatement. Encore une fois, pour une précision de 100%, cela ne peut pas être la dernière étape du processus. Ce scénario n'utilise pas de hachage à des fins de cryptographie, donc un algorithme tel que MD5 fonctionnera bien.

Il serait extrêmement difficile pour moi de justifier le passage à un algorithme SHA-x à des fins de «précision», car si l'entreprise va paniquer sur les minuscules possibilités de collision de MD5, il y a de fortes chances qu'elles paniquent également les algorithmes SHA-x ne sont pas parfaits non plus. Ils doivent soit accepter la légère imprécision, soit exiger que la requête soit exacte à 100% et en direct avec les implications techniques associées. Je suppose que si le PDG dort mieux la nuit en sachant que vous avez utilisé SHA-x au lieu de MD5, eh bien, très bien; cela ne signifie toujours pas grand-chose d'un point de vue technique dans ce cas.

En parlant de performances, si les tables sont principalement en lecture et que le résultat de la jointure est nécessaire fréquemment, envisagez d'implémenter une vue indexée pour éliminer la nécessité de calculer la jointure entière chaque fois qu'elle est demandée. Bien sûr, vous échangez le stockage pour cela, mais cela peut en valoir la peine pour l'amélioration des performances, en particulier si une précision de 100% est requise.

Pour plus d'informations sur l'indexation des valeurs de chaînes longues, j'ai publié un article qui présente un exemple de procédure à suivre pour une seule table et présente les éléments à prendre en compte lors de la tentative du scénario complet dans cette question.


8

MD5 devrait être bien et la sortie peut être stockée dans un binaire (16). La probabilité d'une collision (voir paradoxe d'anniversaire ) est encore très faible, même avec un échantillon physique important. La sortie de SHA-1 prend 20 octets et la sortie de SHA-256 prend 32 octets. À moins que vous ne disposiez d'un si grand nombre d'enregistrements que votre probabilité de collision d'anniversaire devienne significative (physiquement impossible ou du moins impraticable avec les technologies matérielles actuelles), elle sera probablement OK.



0

Je n'ai pas vu cela mentionné dans les réponses mais par MSDN :

Depuis SQL Server 2016 (13.x), tous les algorithmes autres que SHA2_256 et SHA2_512 sont obsolètes. Les algorithmes plus anciens (non recommandés) continueront de fonctionner, mais ils déclencheront un événement de dépréciation.

J'ai posé une question similaire , c'est donc à vous de décider si vous souhaitez utiliser une fonction obsolète telle que MD5 (si vous êtes sur 2016+). Vous pouvez effectuer des tests pour voir la différence de stockage et de performances entre MD5 et SHA2.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.