河内分分-医院胸痛是什么原因

首页

AD联系:507867812

河内分分

时间:2019-11-17 12:23:22 作者:澳门银河娱乐场网址 浏览量:46748

河内分分MySQL基础教程:关于varchar(N)MySQL基础教程:关于varchar(N)MySQL基础教程:关于varchar(N)MySQL基础教程:关于varchar(N)MySQL基础教程:关于varchar(N)MySQL基础教程:关于varchar(N)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”了

linux

一 前言 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”了

linux,见下图

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”了

linux

一 前言 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”了

linux

一 前言 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”了

linux,如下图

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”了

linux

一 前言 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”了

linux

如下图

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”了

linuxMySQL基础教程:关于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”了

linux

一 前言 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”了

linux

一 前言 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”了

linux

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”了

linux

一 前言 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”了

linux

一 前言 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”了

linuxMySQL基础教程:关于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”了

linuxMySQL基础教程:关于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”了

linux

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”了

linux

一 前言 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”了

linux

一 前言 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”了

linuxMySQL基础教程:关于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”了

linuxMySQL基础教程:关于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”了

linuxMySQL基础教程:关于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”了

linuxMySQL基础教程:关于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”了

linux

河内分分

一 前言 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”了

linux

一 前言 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”了

linux

一 前言 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”了

linuxMySQL基础教程:关于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”了

linuxMySQL基础教程:关于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”了

linuxMySQL基础教程:关于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”了

linuxMySQL基础教程:关于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”了

linux

1.

一 前言 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”了

linux

一 前言 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”了

linuxMySQL基础教程:关于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”了

linux

一 前言 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”了

linux

一 前言 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”了

linuxMySQL基础教程:关于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”了

linuxMySQL基础教程:关于varchar(N)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”了

linux

一 前言 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”了

linuxMySQL基础教程:关于varchar(N)MySQL基础教程:关于varchar(N)MySQL基础教程:关于varchar(N)

2.MySQL基础教程:关于varchar(N)。

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”了

linux

一 前言 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”了

linux

3.

一 前言 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”了

linux

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”了

linuxMySQL基础教程:关于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”了

linuxMySQL基础教程:关于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”了

linuxMySQL基础教程:关于varchar(N)

4.MySQL基础教程:关于varchar(N)。

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”了

linuxMySQL基础教程:关于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”了

linuxMySQL基础教程:关于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”了

linux

一 前言 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”了

linux

一 前言 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”了

linux。河内分分

展开全文
相关文章
天晨娱乐

MySQL基础教程:关于varchar(N)

就九息娱乐动态图

MySQL基础教程:关于varchar(N)....

u 优乐国际pt老虎机

MySQL基础教程:关于varchar(N)....

澳门二十一点游戏平台

MySQL基础教程:关于varchar(N)....

ag所有平台都一样的,怎么骗

一 前言 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”了

linux....

相关资讯
澳门新莆竟是免费观看

一 前言 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”了

linux....

九息娱乐动态图片

一 前言 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”了

linux....

娱乐小平台

一 前言 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”了

linux....

热门资讯