Более быстрый хэш с меньшим количеством коллизий?
Какая форма хэширования будет возвращать самые быстрые результаты (и наименьший шанс того, что 2 результата вернут тот же хеш) при суммировании хеша всех строк (10 миллионов) для одного столбца (может быть NUMBER, VARCHAR, DATE, TIMESTAMP, но без CLOBS,XML.etc)? Затем это значение будет сравниваться с той же операцией в другой таблице, чтобы проверить, все ли строки для этого же столбца абсолютно одинаковы.
SET SERVEROUTPUT ON
DECLARE
HASH_VAL NUMBER;
begin
DBMS_OUTPUT.PUT_LINE (OWA_OPT_LOCK.CHECKSUM('column_here'));
DBMS_OUTPUT.PUT_LINE (DBMS_UTILITY.GET_HASH_VALUE('column_here',1,POWER(2,31)-1));
EXECUTE IMMEDIATE 'SELECT ORA_HASH(''column_here'') FROM DUAL' INTO HASH_VAL;
DBMS_OUTPUT.PUT_LINE (HASH_VAL);
DBMS_OUTPUT.PUT_LINE (DBMS_OBFUSCATION_TOOLKIT.MD5( INPUT_STRING => 'column_here'));
DBMS_OUTPUT.PUT_LINE ( DBMS_CRYPTO.HASH(UTL_RAW.CAST_TO_RAW('column_here'),3) );
END;
/
1 ответ
Какой метод быстрее?
Я не отмечал это на стенде, но я думаю, что DBMS_SQLHASH - самый быстрый, так как он был создан именно для этого типа проблемы.
Это официальный пакет, но он недостаточно документирован в Руководстве по безопасности. Его нет в справочнике по пакетам и типам PL/SQL на 5,964 (!) Страницах, и вам нужно grant execute on dbms_sqlhash to [user];
для того, чтобы это сработало, наверное, поэтому почти никто не слышал об этом.
Например:
select sys.DBMS_SQLHASH.GETHASH(sqltext=>'select 1 from dual', digest_type=>1)
from dual;
тип дайджеста: 1 = HASH_MD4, 2 = HASH_MD5, 3 = HASH_SH1
Вероятность столкновения
Есть несколько вопросов о вероятности столкновения: Hash Collision - каковы шансы?, Могут ли две разные строки генерировать один и тот же хэш-код MD5?
Я не совсем уверен, что случится с шансом, когда вы начнете суммировать много строк, но вероятность одного столкновения настолько смехотворно мала, что вы, вероятно, в порядке.
Я не знаю математику, но я уверен, что наиболее вероятной причиной столкновения является ошибка программирования, если вы попытаетесь написать свою собственную функцию.
Я видел и создавал сценарии, как это, и есть много тонких способов испортить это. Например, нулевые значения и значения обмена между строками или столбцами. Несмотря на то, что вы сейчас используете только один столбец, чтобы кто-то никогда не писал один из этих уродливых сценариев, вы должны по возможности использовать поставляемый Oracle пакет.