在MySQL中将十六进制值存储为二进制

在MySQL中将十六进制值存储为二进制,mysql,binary,hex,Mysql,Binary,Hex,我在考虑如何在数据库中存储密码:在CHAR(40)字段中适当地添加SHA1字符串。然而,由于其中的字符数据实际上只是160位数字的十六进制表示,因此我认为最好将其存储为二进制(20) 在我看来,这种方法的一个好处是它将该领域的规模缩小了一半,但我可以想象,它可能也有一些缺点 您的看法是什么?将哈希密码存储为二进制而不是varchar所节省的硬盘空间可能微不足道。此表中可能有多少用户?乘以BINARY(20)和VARCHAR(n)之间的空间差,我想你会发现这并不是一个显著的节约。就个人而言,我更喜

我在考虑如何在数据库中存储密码:在CHAR(40)字段中适当地添加SHA1字符串。然而,由于其中的字符数据实际上只是160位数字的十六进制表示,因此我认为最好将其存储为二进制(20)

在我看来,这种方法的一个好处是它将该领域的规模缩小了一半,但我可以想象,它可能也有一些缺点


您的看法是什么?

将哈希密码存储为二进制而不是varchar所节省的硬盘空间可能微不足道。此表中可能有多少用户?乘以
BINARY(20)
VARCHAR(n)
之间的空间差,我想你会发现这并不是一个显著的节约。就个人而言,我更喜欢十六进制表示法,因为如果我在开发过程中执行一些特殊操作或编写单元测试以验证密码相关操作,至少我可以在查询中键入十六进制表示法。如果我碰巧在文本编辑器等中加载数据转储,十六进制的可读性比二进制的要好一些。我的底线是十六进制表示法在开发周期中会更方便。

下面是我的分类:

  • 如果使用字符串而不是二进制,请使用固定长度字段。由于散列算法都输出一个固定的长度,您可以在那里节省一些空间
  • 因为您只是在进行相等比较,所以不需要索引。二进制字段没有排序规则类型或字符集
  • 二进制列类型没有像blob那样的奇数存储警告
  • 每个十六进制字符表示它所使用的8(或7)位中的4位。这意味着二进制存储的效率是原来的两倍
  • 最重要的是:除非您在一个每个字节都计数的嵌入式系统中工作,否则不要这样做。使用字符表示可以更好地进行调试。另外,每次开发人员处理这样的问题时,我都想知道为什么。每一个这样的架构决策都有权衡,而这一个似乎并没有为您的项目增加价值
  • 您可以在以后使用简单的SQL脚本将其转换为二进制

  • 简而言之,使用固定长度的文本字段。在当今世界,计算字节没有任何好处,特别是当改变很容易实现时。

    为什么要重新发明轮子?为什么不像“mysql.user”表那样使用CHAR(41)?这是一种众所周知的格式,所以任何未来的维护人员都不会对您的特殊方案感到困惑?只需注意“就像MySQL密码一样”,就可以让每个人都感到轻松。

    我们在数据库中使用了大量不同ID的二进制代码来节省空间,因为我们的大多数数据都是由这些ID组成的。因为它似乎不需要节省空间(因为它只是密码,而不是其他大型项目),所以我不认为有任何理由在这里使用二进制文件

    我们遇到的最大问题是,在控制台中不断地显示二进制数据(每次键入select*时,您都会听到一百万声蜂鸣),而且您必须始终执行select HEX()或insert UNHEX(),这是一个痛苦的过程


    最后,如果您(错误地)混合和匹配二进制和十六进制/UNHEX,并在此值上进行连接,则可以匹配您从未打算匹配的记录。

    如果您希望在sql中轻松存储二进制。。。您可以先转换为十六进制。 查看此页面:

    转换为十六进制,去掉“-”并将“0x”放在字符串前面。Mysql将理解为字节内容

    例如:

    INSERT INTO users SET password=0x1e8ef774581c102cbcfef1ab81872213
    

    这是一个老问题,但我注意到没有人提到数据验证是二进制列的优势。具体来说,可以使用非十六进制数字(0-9,a-f)的字符在CHAR(40)列中存储无效值


    您仍然可以将错误的值插入二进制列(例如,如果忘记调用unHEX),但您将永远不必考虑从不正确解析的数据库中读取值。

    您只需保存每个密码的几个字节。值得吗?这就是我想知道的。好处可能很小,但代价是什么?好吧,似乎大家都同意,好处很小,没有人提出任何重大的代价。如果进行了更改,将来的备份是否与以前的备份兼容?是否需要更改任何代码?您可以随时调用HEX(myBinaryField)将其视为HEX。@nickf:当然可以。那就不那么方便了。我喜欢你用
    二进制文件
    来节省空间!你觉得你能帮我走上正轨吗?
    
    INSERT INTO users SET password=0x1e8ef774581c102cbcfef1ab81872213