我想将SHA1哈希存储到BINARY(20)列中。我通过准备INSERT INTO foo SET ( hash=? )
然后执行绑定到包含20字节二进制值的变量的语句来尝试它,但得到了运行时语法错误“... hash ='\ 0 \ 0#* $ ^!。 ..'”。 (我很困惑为什么执行预准备语句会表示这样的值。)This post并不表示将SHA1存储到BINARY(20)列中有什么问题,但是没有说明它是如何完成的SQL。
更新:“为什么二进制而不是十六进制?”将有大约十亿行,所以20个额外的字节是重要的,而且我被告知数字查找的速度是字符串查找的两倍(并且BINARY字段将被视为数字)
UPDATE 2 :错误消息没有抱怨二进制值的表示,而是关于SET列表周围的括号。
答案 0 :(得分:4)
在插入之前使用UNHEX功能进行翻译:
INSERT INTO foo SET hash=UNHEX('0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33');
您将获得空间要求,但是您可以获得一些性能命中,将您的哈希从二进制转换为十六进制再转换为二进制。
答案 1 :(得分: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)
答案 2 :(得分: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);
显然,在后一种情况下你可以使用MySQL的SHA1()
函数,如果你给的是普通的字符串,而不是它的SHA1。