mysql 数据库中varchar的长度与字节,字符串的关系

经常看到别人设置varchar的长度是255,它可以存储多少个汉字。在phpmyadmin中看到varchar的定义是变长(0-65535),它的最大长度到底是255还是65535,是不是可以设置成varchar(60000)?还有长度和字节的关系,如上设置,它的长度就是60000,可以存储60000个字节,这样理解对吗?图片描述

阅读 52.7k
6 个回答
CREATE TABLE `test` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `content` varchar(5) NOT NULL DEFAULT '',
    PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
INSERT INTO `test`(`content`) VALUES ('123456');
INSERT INTO `test`(`content`) VALUES ('中国人民银行');
SELECT * FROM `test`;
返回:
id  content
1   12345
2   中国人民银

可见,varchar(5)能存储5个字符,不管是数字,字母,还是汉字.

CREATE TABLE `test2` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `content` varchar(21842) NOT NULL DEFAULT '',
    PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;

该表中varchar类型的字段能容纳的最大字符数21842是怎么得来的?
21842 = (65535-1-2-4)/3
MySQL要求一个行的定义长度不能超过65535(包括多个字段),所以有65535.
varchar的最大有效长度取决于最大行大小.
减1的原因是实际行的存储从第2个字节开始.
减2的原因是varchar头部的2个字节表示长度.
减4的原因是字段id的int类型占用4个字节.
除以3的原因是一个utf8字符占用3个字节.

如果你在test2表里把varchar(21842)改为varchar(21844),那么就会报以下错误:
1118 - Row size too large.
The maximum row size for the used table type, not counting BLOBs, is 65535.
This includes storage overhead, check the manual.
You have to change some columns to TEXT or BLOBs.

MySQL中char,varchar与text类型的选用:
知道固定长度的用char,比如MD5串固定是32位.
经常变化的字段用varchar.
超过255字符的只能用varchar或者text,不能用char.
能用varchar的地方不用text.

MySQL 的字符大小和字符集有关,如果字符集是 ascii,保存不了中文(会显示成乱码),如果是 UTF8,每个字符是1-3个字节。

用事实说话

试验用的 MySQL 5.6

先检查数据库字符集

sqlshow variables like '%char%';

结果:UTF8

Variable_name Value
character_set_client utf8mb4
character_set_connection utf8mb4
character_set_database utf8
character_set_filesystem binary
character_set_results utf8mb4
character_set_server utf8
character_set_system utf8
character_sets_dir D:\Program Files\MySQL\MySQL Server 5.6\share\charsets\

创建表(注意:varchar(10)

sqlCREATE TABLE `test_char` (
    `s` VARCHAR(10) NULL DEFAULT NULL
)

插入数据

十字ASCII字符,正确执行

sqlinsert into test_char
(s)
values
('0123456789')
;

十个中文字符,正确执行

sqlinsert into test_char
(s)
values
('一二三四五六七八九十')
;

但是十一个ASCII或中文都是报错,说数据太长。

结论

长度是当前字符集的字符长度,而不是字节长度!

varchar和char的长度并不是指字节长度,而是当前字符集下,最多多少个字符,比如,varchar 100,存ascii字符,最多存储100个,存中文也是最多存100个,而不是33个。

MySQL一行占用的空间是 65535个字节(byte), 注意这个大小是被整行上所有的列所共享的。
而blob和text类型只占用9到12个字节,它们的内容分散到不同行上去了。 string一般存储短字符串,它的长度可以理解为字符长度,一般最好不要超过255个。 如果长度大于255 最好考虑text 或者blob

具体参考mysql 官方手册The CHAR and VARCHAR Types
Limits on Table Column Count and Row Size

varchar(6000)是可以存储6000个字节,如果字符集采用UTF-8的话,由于UTF-8是一种“可变长编码”,英文字母被编成一个字节,汉字通常是3个字节,只有极其生僻的字才会被编码成4-6个字节。因此可认为编码是UTF-8时varchar(6000)里可以存储2000个汉字

新手上路,请多包涵

varchar声明的长度是字符数,但能声明多长与字符集有关。
以utf8mb4为例、单字符最大可能占用4字节,那么一行最多存储(65535-1-2)/4个字符。
具体可参考VARCHAR最大有多长?

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏