当我想在SHA数据库中存储SHA1哈希的结果时,我遇到了一个简单的问题:
VARCHAR字段应该在多长时间内存储哈希的结果?
我会将 VARCHAR 用于可变长度数据,但不使用固定长度数据 . 因为SHA-1值总是160位长,所以 VARCHAR 只会浪费an additional byte for the length of the fixed-length field .
VARCHAR
而且我也不会存储SHA1返回的值 . 因为它每个字符仅使用4位,因此需要160/4 = 40个字符 . 但是如果你每个字符使用8位,你只需要一个160/8 = 20个字符的长字段 .
所以我建议你使用BINARY(20)和UNHEX function将 SHA1 值转换为二进制 .
SHA1
我比较了 BINARY(20) 和 CHAR(40) 的存储要求 .
BINARY(20)
CHAR(40)
CREATE TABLE `binary` ( `id` int unsigned auto_increment primary key, `password` binary(20) not null ); CREATE TABLE `char` ( `id` int unsigned auto_increment primary key, `password` char(40) not null );
有数百万条记录 binary(20) 需要44.56M,而 char(40) 需要64.57M . InnoDB 引擎 .
binary(20)
char(40)
InnoDB
SHA1哈希是40个字符长!
Reference taken from this blog:
Below is a list of hashing algorithm along with its require bit size:
MD5 = 128位哈希值 .
SHA1 = 160位哈希值 .
SHA224 = 224位哈希值 .
SHA256 = 256位哈希值 .
SHA384 = 384位哈希值 .
SHA512 = 512位哈希值 .
Created one sample table with require CHAR(n):
CREATE TABLE tbl_PasswordDataType ( ID INTEGER ,MD5_128_bit CHAR(32) ,SHA_160_bit CHAR(40) ,SHA_224_bit CHAR(56) ,SHA_256_bit CHAR(64) ,SHA_384_bit CHAR(96) ,SHA_512_bit CHAR(128) ); INSERT INTO tbl_PasswordDataType VALUES ( 1 ,MD5('SamplePass_WithAddedSalt') ,SHA1('SamplePass_WithAddedSalt') ,SHA2('SamplePass_WithAddedSalt',224) ,SHA2('SamplePass_WithAddedSalt',256) ,SHA2('SamplePass_WithAddedSalt',384) ,SHA2('SamplePass_WithAddedSalt',512) );
sha1的输出大小为160位 . 这是160/8 == 20个字符(如果使用8位字符)或160/16 = 10(如果使用16位字符) .
所以长度在10个16位字符和40个十六进制数字之间 .
在任何情况下,决定您要存储的格式,并根据该格式将字段设置为固定大小 . 这样你就不会浪费任何空间 .
如果您不总是为用户存储哈希值(即验证帐户/忘记登录URL),您可能仍希望使用VARCHAR . 一旦用户验证/更改了他们的登录信息,他们就不应该使用哈希并且没有理由 . 您可以创建一个单独的表来存储临时哈希 - >可以删除的用户关联,但我认为大多数人都不愿意这样做 .
如果你需要sha1列的索引,我建议CHAR(40)出于性能原因 . 在我的情况下,sha1列是电子邮件确认令牌,因此在登录页面上,查询仅使用令牌输入 . 在这种情况下,CHAR(40)与INDEX,在我看来,是最好的选择:)
如果你想采用这种方法,记得留下$ raw_output = false .
7 回答
我会将
VARCHAR
用于可变长度数据,但不使用固定长度数据 . 因为SHA-1值总是160位长,所以VARCHAR
只会浪费an additional byte for the length of the fixed-length field .而且我也不会存储SHA1返回的值 . 因为它每个字符仅使用4位,因此需要160/4 = 40个字符 . 但是如果你每个字符使用8位,你只需要一个160/8 = 20个字符的长字段 .
所以我建议你使用BINARY(20)和UNHEX function将
SHA1
值转换为二进制 .我比较了
BINARY(20)
和CHAR(40)
的存储要求 .有数百万条记录
binary(20)
需要44.56M,而char(40)
需要64.57M .InnoDB
引擎 .SHA1哈希是40个字符长!
Reference taken from this blog:
Below is a list of hashing algorithm along with its require bit size:
MD5 = 128位哈希值 .
SHA1 = 160位哈希值 .
SHA224 = 224位哈希值 .
SHA256 = 256位哈希值 .
SHA384 = 384位哈希值 .
SHA512 = 512位哈希值 .
Created one sample table with require CHAR(n):
sha1的输出大小为160位 . 这是160/8 == 20个字符(如果使用8位字符)或160/16 = 10(如果使用16位字符) .
所以长度在10个16位字符和40个十六进制数字之间 .
在任何情况下,决定您要存储的格式,并根据该格式将字段设置为固定大小 . 这样你就不会浪费任何空间 .
如果您不总是为用户存储哈希值(即验证帐户/忘记登录URL),您可能仍希望使用VARCHAR . 一旦用户验证/更改了他们的登录信息,他们就不应该使用哈希并且没有理由 . 您可以创建一个单独的表来存储临时哈希 - >可以删除的用户关联,但我认为大多数人都不愿意这样做 .
如果你需要sha1列的索引,我建议CHAR(40)出于性能原因 . 在我的情况下,sha1列是电子邮件确认令牌,因此在登录页面上,查询仅使用令牌输入 . 在这种情况下,CHAR(40)与INDEX,在我看来,是最好的选择:)
如果你想采用这种方法,记得留下$ raw_output = false .