Mysql 在数据库中存储MD5时二进制(16)和字符(32)之间的差异

Mysql 在数据库中存储MD5时二进制(16)和字符(32)之间的差异,mysql,sql,binary,md5,Mysql,Sql,Binary,Md5,根据各种建议,例如,我可以将md5存储为字符(32)或二进制(16)。但是,当我使用二进制(16)时,存储的值与CHAR(32)存储结果的前16个字符以及SELECT MD5()results的前16个字符相同。后面16个字符的意义是什么?它们在二进制列中不存在会导致数据丢失吗 CREATE TABLE test (id INT NOT NULL AUTO_INCREMENT, value VARCHAR(6), md5_char CHAR(32) NOT NULL, md5_binary B

根据各种建议,例如,我可以将md5存储为字符(32)或二进制(16)。但是,当我使用二进制(16)时,存储的值与CHAR(32)存储结果的前16个字符以及
SELECT MD5()
results的前16个字符相同。后面16个字符的意义是什么?它们在二进制列中不存在会导致数据丢失吗

CREATE  TABLE test (id INT NOT NULL AUTO_INCREMENT, value VARCHAR(6), md5_char CHAR(32) NOT NULL, md5_binary BINARY(16) NOT NULL, PRIMARY KEY (id)) ENGINE = InnoDB;
INSERT INTO test(value,md5_char,md5_binary) VALUES("one!",md5("one!"),md5("one!"));
INSERT INTO test(value,md5_char,md5_binary) VALUES("two%",md5("two%"),md5("two%"));
INSERT INTO test(value,md5_char,md5_binary) VALUES("three~",md5("three~"),md5("three~"));
SELECT value,md5(value),md5_char,md5_binary FROM test;
DROP TABLE test;

+--------+----------------------------------+----------------------------------+------------------+
| value  | md5(value)                       | md5_char                         | md5_binary       |
+--------+----------------------------------+----------------------------------+------------------+
| one!   | 633c8403325f1cf963809e6eb224d77e | 633c8403325f1cf963809e6eb224d77e | 633c8403325f1cf9 |
| two%   | 48bbec047b4451a2018e0f652807b7d0 | 48bbec047b4451a2018e0f652807b7d0 | 48bbec047b4451a2 |
| three~ | fee453bb4eb68dcdfee07575e75c8cc5 | fee453bb4eb68dcdfee07575e75c8cc5 | fee453bb4eb68dcd |
+--------+----------------------------------+----------------------------------+------------------+

当前,使用
二进制(16)
时,将丢失一半校验和。将MD5校验和存储为二进制(16)时,应将其存储为二进制数据,而不是十六进制编码。即:

INSERT INTO test (md5_binary) VALUES(UNHEX(md5("one!")));
如果要将其与另一个校验和进行比较,可以使用HEX函数再次将其编码为HEX:

SELECT HEX(md5_binary) FROM test;

使用二进制而不是十六进制文本存储校验和的好处是需要一半的存储空间。

感谢Joni,类似的,基于河豚的bcrypt需要CHAR(60)来存储校验和。如果使用
UNHEX()
,是否可以使用二进制(30)?存储的好处与数据类型无关。你可以用二进制存储十六进制,用字符列存储未经十六进制的数据。但是二进制总是需要字符位数的一半吗?刚刚意识到你的帖子中说“需要一半的存储空间”。Thanks@Andomar,不建议将二进制数据存储在字符列中:然后数据库会将数据解释为具有特定字符编码,并且除非您知道自己在做什么,否则可能会损坏数据(即使用单字节编码和二进制排序规则)