php 存储 MD5 散列或 NULL 的最佳 MySQL 数据类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19056925/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 18:44:16  来源:igfitidea点击:

Best MySQL data type to store MD5 hash or NULL

phpmysqlmd5

提问by user1032531

I have a PHP application which stores all accounts regardless of whether they are active or not in a single table. The table has a column called "active" which is either is NULL which means the account is active, or contains a MD5 hash which means the account is inactive.

我有一个 PHP 应用程序,它存储所有帐户,无论它们是否在单个表中处于活动状态。该表有一个名为“active”的列,该列要么为 NULL,表示该帐户处于活动状态,要么包含一个 MD5 哈希值,表示该帐户处于非活动状态。

According to Best practices for efficiently storing md5 hashes in mysql, if the column always contains a MD5 hash and never NULL, then BINARY(16) is preferred and CHAR(32) is the next best choice. Since most of my accounts are active and thus most of the column values will be NULL, am I better off using a different data type such as VARCHAR(32)?

根据在 mysql 中有效存储 md5 哈希的最佳实践,如果该列始终包含 MD5 哈希并且从不为 NULL,则首选 BINARY(16),而 CHAR(32) 是下一个最佳选择。由于我的大多数帐户都处于活动状态,因此大多数列值将为 NULL,我是否最好使用不同的数据类型,例如 VARCHAR(32)?

回答by Bill Karwin

There's no point to using VARCHAR. MD5 hashes are always 128-bit, so a CHAR(32) holds the string of hex digits, or BINARY(16) holds the string of bytes after you UNHEX() the hex digits.

使用 VARCHAR 毫无意义。MD5 哈希值始终为 128 位,因此 CHAR(32) 保存十六进制数字字符串,或者 BINARY(16) 保存在 UNHEX() 十六进制数字之后的字节字符串。

Using NULL is independent of data type choice. MySQL can store NULL in lieu of a string, either CHAR or VARCHAR. But in fact, in InnoDB's default row format, MySQL does not store NULLs at all, it stores nothing for columns that are NULL.

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



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

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

  • Helpful Notes About NULLs:

    For the third row, I inserted NULLs in FIELD2 and FIELD3. Therefore in the Field Start Offsets the top bit is on for these fields (the values are 94 hexadecimal, 94 hexadecimal, instead of 14 hexadecimal, 14 hexadecimal). And the row is shorter because the NULLs take no space.

  • 关于 NULL 的有用说明:

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

(emphasis mine)

(强调我的)

回答by Raymond Nijland

Note:Updated: 05-11-2019

注:更新时间:05-11-2019

Ideally you should not be using MD5 anymore to hash passwords. PHP manual has added a Safe Password Hashingsection like 4 - 5 years ago now i believe where password_hash()and password_verify()are explained and why MD5 / SHA1 is not suitable..

理想情况下,您不应再使用 MD5 来散列密码。PHP 手册在4 - 5 年前添加了一个安全密码哈希部分,现在我相信在哪里password_hash()password_verify()被解释以及为什么 MD5 / SHA1 不适合..

Keep in mind as most RDMS are designed to deliver very stabile times as most RDMS buffer data in memory and or indexed which makes timing attacks very possible when the passwordcolumn is in the WHEREclause

请记住,大多数 RDMS 旨在提供非常稳定的时间,因为大多数 RDMS 缓冲内存中的数据或索引,这使得当password列在WHERE子句中时很可能进行计时攻击

The safe way to use password_verify()in combination with SQL is in "pseudo" PHP code..

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..
}

In the MySQL source code in the file strings/ctype-bin.c the BINARY type is defined.

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

This looks like the default C ascii based charset converted into binary. This should in thoery be faster then the CHAR(32) with ascii_bin charset.

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

Because less time is needed to write / read the binary and it takes less diskspace in indexes and memory and because the CHAR(32) datatype is 16 bytes larger

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

If you want to use this you should use this php code

如果你想使用它,你应该使用这个 php 代码

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

回答by Toni Albuquerque

You can use the php function md5(); Is more efficient and if anyone can catch the data when you sent to database, that will be already crypted.

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