用于存储MD5哈希或NULL的最佳MySQL数据类型

问题描述 投票:10回答:3

我有一个PHP应用程序,它存储所有帐户,而不管它们是否在单个表中都处于活动状态。该表具有一个称为“活动”的列,该列为NULL表示该帐户处于活动状态,或者包含MD5哈希表示该帐户处于非活动状态。

根据Best practices for efficiently storing md5 hashes in mysql,如果该列始终包含MD5哈希且从不包含NULL,则首选BINARY(16),而CHAR(32)是下一个最佳选择。由于我的大多数帐户都处于活动状态,因此大多数列值将为NULL,所以我最好使用其他数据类型(例如VARCHAR(32))吗?

php mysql md5
3个回答
20
投票

没有必要使用VARCHAR。 MD5哈希始终为128位,因此,在对十六进制数字进行UNHEX()之后,CHAR(32)将保留十六进制数字的字符串,而BINARY(16)将保留字节字符串。

使用NULL与数据类型选择无关。 MySQL可以存储NULL来代替CHAR或VARCHAR字符串。但是实际上,在InnoDB的默认行格式中,MySQL根本不存储NULL,对于NULL的列则不存储任何内容。


参考:http://dev.mysql.com/doc/internals/en/innodb-field-contents.html

  • 有关NULL的有用说明:

    对于第三行,我在FIELD2和FIELD3中插入了NULL。因此,在“字段起始偏移量”中,这些字段的最高位处于打开状态(值是94十六进制,94十六进制,而不是14十六进制,14十六进制)。 并且行较短,因为NULL不占空间。

(重点是我的)


3
投票

注意:更新日期:05-11-2019

理想情况下,您不应再使用MD5哈希密码。PHP手册已像4-5年前一样添加了Safe Password Hashing部分,现在我相信password_hash()password_verify()的解释位置以及为何不适合使用MD5 / SHA1。

请记住,因为大多数RDMS旨在提供与内存中大多数RDMS缓冲数据或索引相同的非常稳定的时间,当password列位于WHERE子句中时,计时攻击非常可能

password_verify()与SQL结合使用的安全方法是在“伪” PHP代码中。

$row = prepare("SELECT password FROM users WHERE username = :username").execute().fetch(); 
if (password_verify($_POST['password'], $row->password)) { 
  // password correct
} else {
  // password incorrect..
}

在文件string / ctype-bin.c中的MySQL源代码中,定义了BINARY类型。

这看起来像默认的基于C ascii的字符集转换为二进制。这应该比带ascii_bin字符集的CHAR(32)更快。

因为写入/读取二进制文件所需的时间更少,并且索引和内存中的磁盘空间更少,并且CHAR(32)数据类型大16个字节,所以

如果要使用此,则应使用此php代码

<?php
  md5 ( "password", true ); // true returns the binary what is 16 bytes long  MySQl BINARY(16)
?>

您可以使用php函数md5();效率更高,如果有人在发送到数据库时可以捕获数据,则该数据将已经加密。


-7
投票

您可以使用php函数md5();效率更高,如果有人在发送到数据库时可以捕获数据,则该数据将已经加密。

© www.soinside.com 2019 - 2024. All rights reserved.