Bohr-L Bohr-L
首页
技术
常见面试题
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

刘博

I'm a slow walker, But I never walk backwards.
首页
技术
常见面试题
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 数据处理与存储类

  • Spring 生态类

  • 缓存问题类

  • 多线程类

  • JVM 类

  • MySQL 类

    • MySQL 为什么一定要有一个主键
    • MySQL 中的 RR 隔离级别,到底有没有解决幻读问题
    • MySQL 的行级锁到底锁的是什么东西?
    • 存储 MD5 值应该用 VARCHAR 还是用 CHAR?
      • 数据库的三范式是什么?
      • 说说 InnoDB 与 MyISAM 的区别
      • drop、truncate、delete 的区别
      • 聊一聊数据库事务机制
      • 聊一聊 MySQL 中的关联查询
      • 事务隔离级别有哪些?MySQL 的默认隔离级别是什么
      • 分库分表之后,id 主键如何处理?
      • 说说在 MySQL 中一条查询 SQL 是如何执行的?
      • 讲解下 DDL、DML、DCL
      • 存储过程和触发器的作用
      • MySQL 如何行转列和列转行
      • 如何查看 SQL 的执行计划
      • union 和 unionAll 的区别
      • having 和 where 的区别
      • 常见的索引原则
      • MySQL 中的 IN 和 EXISTS 子句有什么区别?
      • MySQL 如何处理 NULL 值,对性能有什么影响?
      • 如何在 MySQL 中处理和避免全表扫描?
      • MySQL 中的表空间是什么,它的作用是什么?
      • 在 MySQL 中,如何优化 ORDER BY 查询?
    • Java 8 + 特性类

    • 其他技术类

    • 常见面试题
    • MySQL 类
    刘博
    2025-12-29
    目录

    存储 MD5 值应该用 VARCHAR 还是用 CHAR?

    存储 MD5 值(128 位哈希值,通常表示为 32 位十六进制字符串)时,推荐使用 CHAR (32),而非 VARCHAR (32),核心原因是 “MD5 值长度固定、CHAR 性能更优、避免存储冗余”,具体对比如下:

    # 1. 长度特性:MD5 值长度固定,CHAR 更适配

    • MD5 值的长度:MD5 算法生成的哈希值是 128 位二进制数,转换为十六进制字符串后,长度固定为 32 个字符(1 个十六进制字符对应 4 位二进制,128/4=32),不存在长度变化;
    • CHAR 的特性:CHAR 是固定长度字符串类型,存储时会占用指定长度的空间(如 CHAR (32) 占用 32 字节),无论实际存储的字符串是否达到 32 位(不足时用空格填充,查询时自动去除空格);
    • VARCHAR 的特性:VARCHAR 是可变长度字符串类型,存储时除了字符串本身,还需额外存储 1-2 字节的 “长度标识”(记录字符串的实际长度);
    • 结论:MD5 值长度固定,无需 VARCHAR 的 “可变长度” 特性,CHAR 更适配。

    # 2. 性能对比:CHAR 查询和存储效率更高

    • 存储效率:
      • CHAR (32):存储 MD5 值时,直接占用 32 字节,无额外开销;
      • VARCHAR (32):存储 MD5 值时,需占用 32 字节(字符串)+1 字节(长度标识,因 32<255,需 1 字节)=33 字节,比 CHAR 多 1 字节开销;
    • 查询效率:
      • CHAR 存储的字符串是固定长度,InnoDB 在索引中存储时更紧凑,索引查找时无需解析长度标识,速度更快;
      • VARCHAR 存储的字符串需先解析长度标识,再读取实际字符串,查询时多一步操作,效率略低;
    • 示例:在百万级数据的表中,基于 CHAR (32) 的 MD5 字段查询,比 VARCHAR (32) 快 5%-10%(具体取决于数据量和索引结构)。

    # 3. 避免空格问题:CHAR 需注意字符集,VARCHAR 无此问题

    • CHAR 的空格填充:若 CHAR 字段的字符集是utf8或utf8mb4,且存储的字符串不足指定长度,会用空格填充;但 MD5 值是 32 位固定长度,不存在不足的情况,因此无需担心空格填充问题;
    • 注意事项:若误将 CHAR (33) 用于存储 MD5 值,会导致存储的字符串末尾多一个空格,查询时需用TRIM()函数去除,影响效率;因此,CHAR 的长度必须严格设置为 32。

    # 4. 特殊场景:若 MD5 值可能带前缀 / 后缀,可考虑 VARCHAR

    若业务中 MD5 值并非纯 32 位十六进制字符串(如带业务前缀,如user_abc123...),长度不固定,则需使用 VARCHAR;但这种场景极少,绝大多数情况下 MD5 值是固定 32 位。

    # 5. 扩展:更优的存储方式 ——BINARY (16)

    除了 CHAR (32),还可将 MD5 值转换为 16 字节二进制数据,用 BINARY (16) 存储,相比 CHAR (32) 更节省空间:

    • 转换方式:将 32 位十六进制字符串转换为 16 字节二进制(如UNHEX('md5_str'));
    • 优点:仅占用 16 字节,比 CHAR (32) 节省 50% 空间,索引更紧凑,查询更快;
    • 缺点:查询时需用HEX()函数转换为十六进制字符串(如SELECT HEX(md5_col) FROM table),可读性略差;
    • 推荐场景:对存储空间和查询性能要求极高的场景(如千万级数据的用户表)。

    # 结论

    • 优先推荐:BINARY(16)(节省空间,性能最优);
    • 次选推荐:CHAR(32)(可读性好,性能优于 VARCHAR,适配大多数场景);
    • 不推荐:VARCHAR(32)(额外的长度标识开销,性能略低,无适配优势)。

    上次更新: 12/30/2025
    MySQL 的行级锁到底锁的是什么东西?
    数据库的三范式是什么?

    ← MySQL 的行级锁到底锁的是什么东西? 数据库的三范式是什么?→

    最近更新
    01
    CPU 使用率较高排查和解决
    12-29
    02
    JVM OOM 问题如何排查和解决
    12-29
    03
    接口防刷怎么实现?
    12-29
    更多文章>
    Theme by Vdoing | Copyright © 2025-2026 Bohr-L's note
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式