【问题标题】:Storing a binary SHA1 hash into a mySQL BINARY(20) column将二进制 SHA1 哈希存储到 mySQL BINARY(20) 列中
【发布时间】:2013-01-14 12:41:54
【问题描述】:

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

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

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

【问题讨论】:

  • 你有充分的理由不对其进行十六进制或base64编码吗?
  • 是的:大约有 10 亿行,所以 20 个额外的字节很重要,而且我被告知数字查找的速度是字符串查找的两倍(并且 BINARY 字段将被视为数字)。
  • 你让我在“十亿行”:)
  • @BartFriederichs - 他需要理由吗?
  • 是的 - 我已经阅读了有关“使用十六进制值更容易”等的各种帖子。我们是专家。我们可以处理二进制文件。 ;-)

标签: mysql insert binary


【解决方案1】:

在插入前使用UNHEX函数翻译它:

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

您将解决空间需求,但将哈希从二进制转换为十六进制再转换回二进制可能会降低性能。

【讨论】:

  • 我不确定是什么导致了这里的语法错误...execute failed: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(name_id='1', name_sha1=UNHEX('00000001823453423a34ec426f109497436924d9'), title=N') '1' 周围的那些单引号显然是由 mysql 放在那里的,尽管 name_id 是一个 bigint。 name_sha1 分配看起来正确吗?
  • 完整的查询是什么?我在 MySQL 命令行上测试并尝试了UNHEX 方法。还 HEX 把它找回来,工作。
  • INSERT INTO dw_name SET (name_id=?,name_sha1=UNHEX(?),title=?,prefix=?,first_name=?,middle_name=?,last_name=?,maturity_suffix=?,professional_suffix=?,company_name=?,gender_id=?,insert_date=?,update_date=?) 是准备好的stmt。
  • 去掉字段列表周围的括号。
  • 那些是从哪里来的??谢谢!还有其他问题,但我已经解决了二进制问题。
【解决方案2】:

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

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)

【讨论】:

    【解决方案3】:

    如果您要从字符串拼凑最终的 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。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-11
      • 2021-11-23
      • 1970-01-01
      • 1970-01-01
      • 2010-10-04
      • 2010-10-30
      • 2017-06-16
      • 2011-01-28
      相关资源
      最近更新 更多