В настоящее время я храню значение SHA1 в SQL Server как char (40). У меня сложилось впечатление, что я мог бы увеличить скорость поиска, изменив это поле на числовое значение. Однако я не уверен, какое поле / тип данных использовать для хранения этого в SQL Server и как преобразовать его в VBScript. Должен ли я использовать число или десятичное число и сколько цифр мне нужно использовать?
Я где-то читал, что рекомендуется использовать Binary (20). Тем не менее, работа с двоичными значениями в VBScript не кажется слишком простой, поэтому я полагаю, что лучше использовать числовое значение.
В настоящее время это моя функция SHA1. Я сохраняю строковое значение, которое оно возвращает в моем поле char (40) в базе данных, и выполняю поиск, используя второй бит кода ниже.
Private Function SHA1(s)
Dim asc, enc, bytes, outstr, pos
Set asc = CreateObject("System.Text.UTF8Encoding")
Set enc = CreateObject("System.Security.Cryptography.SHA1CryptoServiceProvider")
'Convert the string to a byte array and hash it
bytes = asc.GetBytes_4(s) 'This is how you use .Net overloaded methods in VBScript
bytes = enc.ComputeHash_2((bytes))
outstr = ""
'Convert the byte array to a hex string
For pos = 1 To Lenb(bytes)
outstr = outstr & LCase(Right("0" & Hex(Ascb(Midb(bytes, pos, 1))), 2))
Next
SHA1 = outstr
Set asc = Nothing
Set enc = Nothing
End Function
Вот моя функция поиска. Он работает довольно быстро, но я ищу способ оптимизировать мой код. Если я использую двоичные данные для хранения данных, мне придется использовать их и при поиске. Я полагаю, что я мог бы использовать хранимые процедуры, которые позволили бы мне использовать функции SQL Server для преобразования туда и обратно. Может быть, это был бы лучший маршрут. Пожалуйста, сообщите.
Function GetHTTPRefererIDBySHA1(s)
Dim r
Set r = Server.CreateObject("ADODB.Recordset")
r.open "SELECT httprefererid FROM httpreferer " & _
"WHERE sha1 = '" & s & "'", con, adOpenForwardOnly, adLockReadOnly
If Not (r.eof and r.bof) then
GetHTTPRefererIDBySHA1 = r("httprefererid")
End If
r.close
set r = nothing
End Function
Edit:
Благодаря ScottE и Google я смог заметно ускорить свои запросы. Вот небольшая информация о моем решении.
1) Я создал поле с именем SHA1Bin. Это поле типа двоичное (20).
2) Когда я вставляю новую запись, я использую хранимую процедуру. Поскольку я не слишком обеспокоен пространством, я сохраняю необработанное значение httpreferer и его двоичное значение SHA1 в той же таблице и той же строке. Моя хранимая процедура преобразует необработанное значение в двоичный файл SHA1 с помощью функции HashBytes (SQL Server 2008).
3) Моя функция SHA1 в VBScript остается такой же, как указано выше, но теперь я использую ее при поиске. Вот модифицированная версия функции GetReferer:
Function GetHTTPRefererIDBySHA1(s)
Dim r
Set r = Server.CreateObject("ADODB.Recordset")
r.open "SELECT httprefererid FROM httpreferer WHERE " & _
"sha1bin = CONVERT(binary(20), 0x" & SHA1(s) & ")", _
tcon, adOpenForwardOnly, adLockReadOnly
If Not (r.eof and r.bof) then
GetHTTPRefererIDBySHA1 = r("httprefererid")
Else
'//Insert new record code intentionally omitted
End If
r.close
set r = nothing
End Function