千家信息网

如何理解MySQL中的varchar(N)

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,本篇文章给大家分享的是有关如何理解MySQL中的 varchar(N),小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。一 前言varcha
千家信息网最后更新 2026年10月31日如何理解MySQL中的varchar(N)

本篇文章给大家分享的是有关如何理解MySQL中的 varchar(N),小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

一 前言
varchar(N) N代表什么意思,能存放多少个中文字符?属于老生常谈的问题了,今天又被一个开发同事问我关于这个问题,索性写一篇文章来具体介绍一下。

二 理论知识

先说明一下 MySQL 历来版本对 varchar 的定义:
4.0版本以下,varchar(50),指的是50字节,如果存放UTF8汉字时,只能存16个(每个中文3字节)
5.0版本以上,varchar(50),指的是50字符,无论存放的是数字、字母还是UTF8中文(每个中文3字节),都可以存放50个
存储限制
需要额外占用字节存放字符的长度:小于255为1个字节,大于255则要2个字节
编码限制
gbk :每个字符最多占用2个字节
utf8:每个字符最多占用3个字节
utf8mb4 每个字符最多占用4个字节,中文占3个字节,emoji表情符号 占用4个字节
长度限制
MySQL定义行的长度不能超过65535,该数值限制了列的数目,比如char(128) utf8字符集,最多有65535/(128*3)=170个汉字。

三 测试
环境 Server version: 5.6.26-74.0-log Percona Server
mysql> create table t1
-> (id int NOT NULL AUTO_INCREMENT primary key,
-> name varchar(10)
-> ) engine=innodb default charset=utf8mb4;
Query OK, 0 rows affected (0.01 sec)
mysql> create table t2
-> (id int NOT NULL AUTO_INCREMENT primary key,
-> name varchar(10)
-> ) engine=innodb default charset=utf8;
Query OK, 0 rows affected (0.01 sec)
mysql> create table t3
-> (id int NOT NULL AUTO_INCREMENT primary key,
-> name varchar(10)
-> ) engine=innodb default charset=gbk;
Query OK, 0 rows affected (0.01 sec)
utf8mb4 字符集
mysql> insert into t1(name) values('abcdfeghi');
Query OK, 1 row affected (0.00 sec)
mysql> insert into t1(name) values('abcdfeghij');
Query OK, 1 row affected (0.00 sec)
mysql> insert into t1(name) values('abcdfeghijk');
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> insert into t1(name) values('一二三四五六七八九十');
Query OK, 1 row affected (0.00 sec)
mysql> insert into t1(name) values('一二三四五六七八九十一');
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> show warnings;
+---------+------+-------------------------------------------+
| Level | Code | Message |
+---------+------+-------------------------------------------+
| Warning | 1265 | Data truncated for column 'name' at row 1 |
+---------+------+-------------------------------------------+
1 row in set (0.00 sec)
mysql> insert into t1(name) values('0123456789');
Query OK, 1 row affected (0.00 sec)
mysql> insert into t1(name) values('01234567890');
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> select id,name,length(name),char_length(name) from t1;
+----+--------------------------------+--------------+-------------------+
| id | name | length(name) | char_length(name) |
+----+--------------------------------+--------------+-------------------+
| 1 | abcdfeghi | 9 | 9 |
| 2 | abcdfeghij | 10 | 10 |
| 3 | abcdfeghij | 10 | 10 |
| 4 | 一二三四五六七八九十 | 30 | 10 |
| 5 | 一二三四五六七八九十 | 30 | 10 |
| 6 | 0123456789 | 10 | 10 |
| 7 | 0123456789 | 10 | 10 |
+----+--------------------------------+--------------+-------------------+
7 rows in set (0.00 sec)
utf8 字符集
mysql> insert into t2(name) values('abcdfeghi');
Query OK, 1 row affected (0.00 sec)
mysql> insert into t2(name) values('abcdfeghij');
Query OK, 1 row affected (0.00 sec)
mysql> insert into t2(name) values('abcdfeghijk');
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> insert into t2(name) values('一二三四五六七八九十');
Query OK, 1 row affected (0.00 sec)
mysql> insert into t2(name) values('一二三四五六七八九十一');
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> insert into t2(name) values('0123456789');
Query OK, 1 row affected (0.00 sec)
mysql> insert into t2(name) values('01234567890');
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> select id,name,length(name),char_length(name) from t2;
+----+--------------------------------+--------------+-------------------+
| id | name | length(name) | char_length(name) |
+----+--------------------------------+--------------+-------------------+
| 1 | abcdfeghi | 9 | 9 |
| 2 | abcdfeghij | 10 | 10 |
| 3 | abcdfeghij | 10 | 10 |
| 4 | 一二三四五六七八九十 | 30 | 10 |
| 5 | 一二三四五六七八九十 | 30 | 10 |
| 6 | 0123456789 | 10 | 10 |
| 7 | 0123456789 | 10 | 10 |
+----+--------------------------------+--------------+-------------------+
7 rows in set (0.00 sec)
gbk 字符集
mysql> insert into t3(name) values('abcdfeghi');
Query OK, 1 row affected (0.00 sec)
mysql> insert into t3(name) values('abcdfeghij');
Query OK, 1 row affected (0.00 sec)
mysql> insert into t3(name) values('abcdfeghijk');
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> insert into t3(name) values('一二三四五六七八九十');
Query OK, 1 row affected (0.01 sec)
mysql> insert into t3(name) values('一二三四五六七八九十一');
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> insert into t3(name) values('0123456789');
Query OK, 1 row affected (0.00 sec)
mysql> insert into t3(name) values('01234567890');
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> select id,name,length(name),char_length(name) from t3;
+----+--------------------------------+--------------+-------------------+
| id | name | length(name) | char_length(name) |
+----+--------------------------------+--------------+-------------------+
| 1 | abcdfeghi | 9 | 9 |
| 2 | abcdfeghij | 10 | 10 |
| 3 | abcdfeghij | 10 | 10 |
| 4 | 一二三四五六七八九十 | 20 | 10 |
| 5 | 一二三四五六七八九十 | 20 | 10 |
| 6 | 一二三四五六七八九十 | 20 | 10 |
| 7 | 0123456789 | 10 | 10 |
| 8 | 0123456789 | 10 | 10 |
+----+--------------------------------+--------------+-------------------+
8 rows in set (0.00 sec)
从上面的测试可以看出,目前版本中 varchar(N) 定义的长度的单位是字符,length(str)表示str占用的字节数,char_length(str)表示str占用的字符数。
不论什么字符集,对于数字和英文字母都是只占用1个字符,也占用一个字节。而中文汉字因字符集不同而不同。

四 总结
回过头来回答文章开头的问题varchar(N)可以存放多少个中文汉字。答案是在 5.0 以后的版本中 varchar(N) 可以存放N个汉字 。
抛开字符集 ,如果一行数据全部为 varchar 类型,其最大长度为 65535 个字节。
行长度计算公式如下:
row length = 1
+ (sum of column lengths)
+ (number of NULL columns + delete_flag + 7)/8
+ (number of variable-length columns)
对于MyISAM,需要额外1个位来记录值是否为NULL;对于InnoDB,没有区别
对于row_format为fixed,delete_flag为1;对于row_format=dynamic,delete_flag为0

根据这个公式,我们便能够解答开头N的最大值:(65535-1-2)/3
减1是因为实际存储从第2个字节开始
减2则因为要在列表长度存储实际字符长度
除3是因为utf8编码限制
再来一道:
create table t4(c int, c2 char(30), c3 varchar(N)) charset=utf8;
N的最大值:(65535-1-2-4-30*3)/3
则此处N的最大值为 (65535-1-2-4-30*3)/3=21812
减1和减2与上例相同;
减4的原因是int类型的c占4个字节;
减30*3的原因是char(30)占用90个字节,编码是utf8。
如果被varchar超过上述的b规则,被强转成text类型,则每个字段占用定义长度为11字节,当然这已经不是"varchar"了。

以上就是如何理解MySQL中的 varchar(N),小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注行业资讯频道。

字节 字符 长度 字符集 中文 版本 汉字 限制 最大 最大值 知识 篇文章 类型 编码 问题 存储 不同 公式 原因 字母 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 湖北九亚互联网络科技有限公司 广东万易互联网科技有限公司惠州分公司 美国互联网科技巨头监管 易互联网科技有限公司 互联网金融公司科技 狮子座互联网科技有限公司 致聘互联网科技 互联网女皇 腾讯科技 长亮科技 互联网金融 科技互联网创业计划书 海南科技产业互联网平台 广州恒生互联网科技有限 互联网科技项目计划书材料类 成都铂石互联网科技做什么的 互联网还是高科技吗 雨阳互联网卡科技有限公司 互联网科技包装股份有限公司上市 互联网高科技行业有哪些企业 第三届互联网大会安防黑科技 每日互联网科技新闻 上海睿民互联网科技有限公司 唐信互联网科技 互联网科技缩写 西安互联网科技公司 中正互联网科技招聘 互联网科技实习生岗位职责 米聚互联网科技南京有限公司排面 畅思互联网科技 北京市互联网新科技 安徽九吞吴互联网科技有限公司
0