4

我想将 SHA1 哈希存储到 BINARY(20) 列中。我尝试了准备,INSERT INTO foo SET ( hash=? )然后执行绑定到包含 20 字节二进制值的变量的语句,但出现运行时语法错误“... hash='\0\0#*$^!...'”。(我很困惑为什么执行一个准备好的语句会代表这样的值。) 这篇文章并没有表明将 SHA1 存储到 BINARY(20) 列有什么问题,但没有说明它是如何使用 SQL 完成的。

更新:“为什么是二进制而不是十六进制?” 将有大约 10 亿行,因此 20 个额外的字节很重要,而且我被告知数字查找的速度是字符串查找的两倍(并且 BINARY 字段将被视为数字)

更新 2:错误消息不是抱怨二进制值的表示,而是抱怨 SET 列表周围的括号。

4

3 回答 3

4

在插入之前使用UNHEX函数对其进行翻译:

 INSERT INTO foo SET hash=UNHEX('0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33');

您将解决空间需求,但是您可能会在将哈希从二进制转换为十六进制再转换回二进制时获得一些性能。

于 2013-01-30T16:21:52.060 回答
1

我想说你不需要做任何特别的事情:

mysql> CREATE TABLE binary_test (
    ->     id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    ->     hash BINARY(20) NOT NULL,
    ->     PRIMARY KEY (id)
    -> );
Query OK, 0 rows affected (0.05 sec)

mysql> DELIMITER //
mysql> CREATE PROCEDURE binary_insert(IN hash BINARY(20))
    -> BEGIN
    ->     INSERT INTO binary_test (hash) VALUES (hash);
    -> END
    -> //
Query OK, 0 rows affected (0.00 sec)

mysql> DELIMITER ;
mysql> CALL binary_insert( UNHEX(SHA1('password')) );
Query OK, 1 row affected (0.04 sec)

mysql> SELECT * FROM binary_test;
+----+----------------------+
| id | hash                 |
+----+----------------------+
|  1 | [¬aõ╔╣??♠é%♂l°3←~µÅÏ |
+----+----------------------+
1 row in set (0.00 sec)
于 2013-01-30T16:31:43.067 回答
0

如果您从字符串拼凑最终的 SQL,则在 SHA1 十六进制字符串前面加上0x. 在这里,我假设您计算或获得 SHA1 字符串,例如在变量中strSha1

strSQL = "INSERT INTO TableName SET BinaryHash=0x";
strSQL .= strSha1;
DbConn.Query(strSQL);

或者,如果您使用参数化或准备好的 SQL,请参阅下面的伪代码。

preparedStmt = DbConn.Prepare("INSERT INTO TableName SET BinaryHash = UNHEX( ? )");
DbConn.Query(preparedStmt, strSha1);

显然,SHA1()在后一种情况下,您可以使用 MySQL 中的函数,如果您有明确的字符串,而不是它的 SHA1。

于 2013-05-07T12:42:17.220 回答