Elegir el algoritmo correcto en la función HashBytes

20

Necesitamos crear un valor hash de los datos nvarchar para fines de comparación. Hay múltiples algoritmos hash disponibles en T-SQL, pero ¿cuál es el mejor para elegir en este escenario?

Queremos asegurarnos de que el riesgo de tener un valor hash duplicado para dos valores nvarchar diferentes es el mínimo. Según mi investigación en Internet, MD5 parece ser el mejor. ¿Está bien? MSDN nos dice (enlace a continuación) sobre los algoritmos disponibles, pero no hay una descripción sobre cuál para qué condiciones.

HASHBYTES (Transact-SQL)

Necesitamos unir dos tablas en dos columnas nvarchar (max). Como se puede imaginar, la consulta tarda mucho tiempo en ejecutarse. Pensamos que sería mejor mantener el valor hash de cada dato nvarchar (max) y unir los valores hash en lugar de los valores nvarchar (max) que son blobs. La pregunta es qué algoritmo hash proporciona la unicidad, para que no corramos el riesgo de tener un valor hash para más de un nvarchar (max).

Cielo
fuente

Respuestas:

18

La HASHBYTESfunción solo toma hasta 8000 bytes como entrada. Debido a que sus entradas son potencialmente más grandes que eso, los duplicados en el rango del campo que se procesa generarán colisiones, independientemente del algoritmo elegido. Considere cuidadosamente el rango de datos que planea dividir: el uso de los primeros 4000 caracteres es la opción obvia , pero puede no ser la mejor opción para sus datos.

En cualquier caso, debido a lo que es una función hash, incluso si las entradas son de 8000 bytes o menos, la única forma de garantizar el 100% de corrección en los resultados es comparar los valores base en algún momento (leer: no necesariamente primero ). Período.

El negocio determinará si se requiere o no una precisión del 100%. Esto le indicará que (a) se requiere comparar los valores base o (b) debe considerar no comparar los valores base: cuánta precisión se debe cambiar por rendimiento.

Si bien las colisiones hash son posibles en un conjunto de entrada único, son infinitamente raras, independientemente del algoritmo elegido. La idea de usar un valor hash en este escenario es reducir de manera eficiente los resultados de la combinación a un conjunto más manejable, no necesariamente llegar al conjunto final de resultados de inmediato. Nuevamente, para una precisión del 100%, este no puede ser el paso final en el proceso. Este escenario no está utilizando el hash con fines de criptografía, por lo que un algoritmo como MD5 funcionará bien.

Sería extremadamente difícil para mí justificar pasar a un algoritmo SHA-x con fines de "precisión" porque si el negocio va a enloquecer por las minúsculas posibilidades de colisión de MD5, lo más probable es que también se asusten los algoritmos SHA-x tampoco son perfectos. Deben aceptar la leve inexactitud o exigir que la consulta sea 100% precisa y viva con las implicaciones técnicas asociadas. Supongo que si el CEO duerme mejor por la noche sabiendo que usaste SHA-x en lugar de MD5, bueno, está bien; todavía no significa mucho desde un punto de vista técnico en este caso.

Hablando de rendimiento, si las tablas son en su mayoría de lectura y el resultado de la unión se necesita con frecuencia, considere implementar una vista indizada para eliminar la necesidad de calcular la unión completa cada vez que se solicite. Por supuesto, intercambia el almacenamiento por eso, pero puede valer la pena por la mejora del rendimiento, especialmente si se requiere una precisión del 100%.

Para leer más sobre la indexación de valores de cadena larga, publiqué un artículo que muestra un ejemplo de cómo hacer esto para una sola tabla, y presenta cosas a considerar al intentar el escenario completo en esta pregunta.

Jon Seigel
fuente
8

MD5 debería estar bien y la salida se puede almacenar en un binario (16). La probabilidad de una colisión (ver paradoja de cumpleaños ) sigue siendo muy baja, incluso con un gran tamaño de muestra física. La salida de SHA-1 toma 20 bytes y la salida de SHA-256 toma 32 bytes. A menos que tenga una cantidad tan grande de registros que la probabilidad de colisión de su cumpleaños se vuelva significativa (físicamente imposible o al menos poco práctica con las tecnologías de hardware actuales), probablemente estará bien.

Preocupado por TunbridgeWells
fuente
0

No he visto esto mencionado en las respuestas, pero según MSDN :

A partir de SQL Server 2016 (13.x), todos los algoritmos que no sean SHA2_256 y SHA2_512 están en desuso. Los algoritmos más antiguos (no recomendados) continuarán funcionando, pero generarán un evento de desaprobación.

Hice una pregunta similar, así que depende de usted si desea usar una función obsoleta como MD5 (si está en 2016+). Puede hacer pruebas para ver cuánta diferencia hay en el almacenamiento y el rendimiento entre MD5 y SHA2.

Gabe
fuente