我在想我是如何在我的数据库中存储密码的:在CHAR(40)字段中适当加盐的SHA1字符串。但是,由于其中的字符数据实际上只是160位数的十六进制表示,我认为将它存储为BINARY(20)可能更好。
CREATE TABLE users (
password BINARY(20)
/* snip */
);
INSERT INTO users (password) VALUES (UNHEX(SHA1('mypassword'));
正如我所看到的,这种方法的一个好处是它将该字段的大小减半,但我可以想象也可能存在一些缺点。
你有什么看法?
答案 0 :(得分:26)
我们在数据库中使用二进制文件来存储大量不同的ID以节省空间,因为我们的大部分数据都包含这些ID。因为它似乎不需要节省空间(因为它只是密码,而不是其他大型项目),我认为没有任何理由在这里使用二进制文件。
我们遇到的最大问题是不断地,令人讨厌的是,在控制台中显示二进制数据(每次键入select *你会听到一百万次哔声),你必须总是选择HEX()或插入UNHEX() ,这是一种痛苦。
最后,如果你混合和匹配(错误地)二进制和HEX / UNHEX并加入这个值,你可以匹配你从未想过的记录。
答案 1 :(得分:7)
这是我的细分:
简而言之,使用固定长度的文本字段。在当前世界中计算字节没有任何好处,特别是在容易实现变化时。
希望这会有所帮助。
答案 2 :(得分:2)
将散列密码存储为二进制而非varchar的硬盘空间节省可能无关紧要。您在此表中可能拥有多少用户?乘以BINARY(20)
和VARCHAR(n)
之间的空格差异,我认为您会发现它并不是一笔可观的节省。就个人而言,我更喜欢十六进制表示,因为至少我可以在查询中输入它,如果我在开发期间进行一些临时操作或编写单元测试来验证密码相关操作。如果我碰巧在文本编辑器中加载数据转储等,则Hex比二进制文件更具可读性。我的底线是在开发周期中十六进制表示会更方便。
答案 3 :(得分:2)
如果你想在sql中存储二进制文件的简单方法...你可以转换为十六进制。 看看这个页面: http://kekoav.com/blog/36-computers/58-uuids-as-primary-keys-in-mysql.html
转换为十六进制,取下“ - ”并将“0x”放在字符串前面。 Mysql将理解为字节内容。
实施例: INSERT INTO用户SET密码= 0x1e8ef774581c102cbcfef1ab81872213
答案 4 :(得分:2)
这是一个老问题,但我注意到没有人提到数据验证作为BINARY列的优势。具体来说,可以使用非十六进制数字(0-9,a-f)的字符在CHAR(40)列中存储无效值。
您仍然可以将错误的值插入BINARY列(例如,如果您忘记调用UNHEX),但您永远不必考虑从数据库中读取无法正确解析的值。
答案 5 :(得分:0)
为什么重新发明轮子?为什么不使用像表`mysql.user'那样的CHAR(41)
?这是一种众所周知的格式,因此任何未来的维护者都不会对您的特殊计划感到头疼?只需注意“就像MySQL密码一样”,让每个人都感到轻松。