当前位置: 首页 > news >正文

MySQL 中 VARCHAR 和 TEXT 的区别

在 MySQL 表设计中,字符串字段常用 VARCHARTEXT 类型,但它们在 存储方式、性能、使用限制 等方面存在明显区别。


一、VARCHAR 和 TEXT 基本介绍

1. VARCHAR

  • 可变长度字符串,最大长度由定义决定。
  • 最大长度:0 ~ 65535 字节(受行大小限制)。
  • 存储时需要额外 1-2 个字节记录字符串长度。
  • 适用场景:长度可预估的字符串,如用户名、标题。

2. TEXT

  • 专门用于存储大文本数据。
  • 不需要指定长度,但 MySQL 有四种 TEXT 类型:
    类型最大长度
    TINYTEXT255 字节
    TEXT65,535 字节
    MEDIUMTEXT16,777,215 字节
    LONGTEXT4,294,967,295 字节
  • TEXT 不支持默认值。
  • 适用场景:文章正文、评论、描述等大文本。

二、VARCHAR 和 TEXT 的主要区别

对比项VARCHARTEXT
存储方式存储在 行内(页内),长度小于页大小(16KB)存储在 独立溢出页,行内只保存指针(20字节)
最大长度受表行大小限制(理论 65535 字节)TEXT 类型分为 TINYTEXT ~ LONGTEXT
是否需要指定长度需要(如 VARCHAR(255))不需要(直接使用 TEXT)
默认值支持支持不支持
是否可以创建索引可以,且索引长度可以完整覆盖可以,但必须指定前缀长度(如 INDEX(title(100))
占用存储字符串实际长度 + 1 或 2 字节长度信息只存储 20B 指针,数据在溢出页
性能访问速度快(行内存储)较慢(需要额外读取溢出页)
适合场景用户名、邮箱、标题评论、正文、描述

三、存储结构差异

VARCHAR

  • 数据直接存储在 页(Page)中,行内存储。
  • 页大小默认 16KB,如果 VARCHAR 太大(> 16KB),会使用页外存储(类似 TEXT)。

TEXT

  • TEXT 类型采用 页外存储
    • 行内存储 20 字节指针,指向溢出页。
    • 实际数据存储在 溢出页(Overflow Page)
  • 因此 TEXT 类型访问需要 额外一次 I/O,性能略差。

四、索引方面的区别

  • VARCHAR:
    • 可以直接创建完整索引。
    • 适合做主键或联合索引。
  • TEXT:
    • 必须指定索引前缀长度,否则报错:
    CREATE INDEX idx_text ON articles(content(100));
    
    • 无法作为主键(主键必须 NOT NULL 且有默认值)。

五、内存占用差异

  • VARCHAR(N):需要额外 1-2 字节存储长度信息。
    • N ≤ 255,用 1 字节。
    • N > 255,用 2 字节。
  • TEXT:只存储一个 20B 指针在行内,实际数据在页外。

六、应用场景对比

场景推荐类型
用户名、邮箱、标题VARCHAR(50~255)
文章正文、长评论TEXT(或 MEDIUMTEXT)
大量短文本,需频繁查询VARCHAR
大字段,偶尔查询TEXT

七、限制与注意事项

  1. TEXT 字段不能有默认值。
  2. TEXT 字段不能直接排序,需要指定前缀:
    SELECT * FROM articles ORDER BY SUBSTRING(content, 1, 100);
    
  3. TEXT 字段不能设置 FULLTEXT 索引,除非引擎支持(InnoDB 5.6+)。
  4. VARCHAR 受行大小限制,单行最大 65535 字节(不包括 BLOB/TEXT 外存数据)。

八、面试高频问答

Q1:VARCHAR 和 TEXT 的存储方式区别?

  • VARCHAR 存储在页内(行内)。
  • TEXT 存储在溢出页,行内只保留指针。

Q2:TEXT 字段为什么不能有默认值?

  • 因为 TEXT 存储结构特殊,MySQL 没有为其分配默认值空间。

Q3:TEXT 可以建索引吗?

  • 可以,但必须指定前缀长度。

Q4:TEXT 查询为什么比 VARCHAR 慢?

  • TEXT 存储在溢出页,访问时需要额外 I/O。

Q5:什么时候选择 TEXT?

  • 当字段内容长度不确定且可能非常大,比如文章正文、长评论。

九、总结

维度VARCHARTEXT
存储方式行内页外
是否指定长度必须不需要
默认值支持支持不支持
索引支持完整支持必须指定前缀
性能较低
适用场景短字符串长文本

实践

  • 如果字段长度可以预估(如用户名、邮箱、标题):用 VARCHAR
  • 如果字段内容超大且不确定:用 TEXT
http://www.lryc.cn/news/611018.html

相关文章:

  • 区分邮科工业交换机与路由器
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘pytorch-lightning’问题
  • 【图像算法 - 09】基于深度学习的烟雾检测:从算法原理到工程实现,完整实战指南
  • Google AI 发布 MLE-STAR:一款能够自动执行各种 AI 任务的先进机器学习工程代理
  • 《算法导论》第 3 章 - 函数的增长
  • UE5.5使用ControlRig实现MetaHumanNPC看向玩家
  • oelove奥壹新版v11.7旗舰版婚恋系统微信原生小程序源码上架容易遇到的几个坑,避免遗漏参数白屏显示等问题
  • 【开源工具】基于Python的PDF清晰度增强工具全解析(附完整源码)
  • bluetooth matlab GFSK 调制解调,误码率统计
  • eclipse类IDE导入现有工程教程
  • 主数据变更流程
  • 文件夹的类型:文件夹 (.0)是什么意思?
  • 三极管三种基本放大电路:共射、共集、共基放大电路
  • 深入浅出 RabbitMQ-路由模式详解
  • SpringBoot中策略模式使用
  • 如何通过 5 种方式将照片从 iPad 传输到电脑
  • qt窗口--01
  • 【数据结构入门】数组和链表的OJ题(2)
  • LeetCood算法题~水果成篮
  • 美化一下达梦grant授权说明
  • 使用vscode编写markdown文档(使用Markdown Preview Enhanced和markdownlint两个插件)以及若干配置
  • vscode 关闭自动更新
  • 英语中日期与时间缩写
  • 计算机网络:目的网络在路由表项中的作用
  • RabbitMQ削峰填谷详解:让系统在流量洪峰中“稳如泰山”
  • Rust进阶-part4-智能指针2
  • linux查看kafka的消费组里是否有积压
  • 带 TrustZone 的按键点灯工程示例
  • 【C++篇】C++11:右值引用与移动语义
  • mac安装pycharm