经常有开发在问建表语句的时候varchar字段的长度大小。或者建表语句中的字段varchar是乱写的。比如直接写个varchar(50000)。今天统一总结下:
提示:VARCHAR(N) 指的是可以存放的最大字符个数,不是字节数。
需要区分字符和字节。一个汉字,一个数字,一个字母都是一个字符。
字节是计算机的基础存储单元,8位一个字节。 具体区分可以查看 字符,字节和编码
因为VARCHAR列中的值为可变长字符串。长度可以指定为0到65,535之间的值。(VARCHAR的最大有效长度由最大行大小和使用的字符集确定。整体最大长度是65,532字节)。所以不同字符集对应的varchar可以支持的最大长度是不一样的。
字符类型若为gbk,每个字符最多占2个字节,最大长度不能超过32766;
字符类型若为utf8,每个字符最多占3个字节,最大长度不能超过21845。
若定义的时候超过上述限制,则varchar字段会被强行转为text类型,并产生warning。
实践出真知:
表结构如下:
CREATE TABLE `test2` (
`a` int(11) NOT NULL,
`b` varchar(4) DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
插入数据:
mysql> insert into test2 values (1,'a');
Query OK, 1 row affected (0.04 sec)
mysql> insert into test2 values (2,'aa');
Query OK, 1 row affected (0.01 sec)
mysql> insert into test2 values (3,'aaa');
Query OK, 1 row affected (0.04 sec)
mysql> insert into test2 values (4,'aaaa');
Query OK, 1 row affected (0.08 sec)
mysql> insert into test2 values (5,'aaaaa');
Query OK, 1 row affected, 1 warning (0.04 sec) //超过字段设定的最大长度,会出现警告,这个跟你设置的库SQL服务器模式有关系,也会报错。 出现警告后自动的截取最大长度的字符串
mysql> show warnings;
+---------+------+----------------------------------------+
| Level | Code | Message |
+---------+------+----------------------------------------+
| Warning | 1265 | Data truncated for column 'b' at row 1 |
+---------+------+----------------------------------------+
mysql> insert into test2 values (6,'te111'); //可以看到的是存储的是字符个数,而不是字节数
Query OK, 1 row affected, 1 warning (0.03 sec)
mysql> show warnings;
+---------+------+----------------------------------------+
| Level | Code | Message |
+---------+------+----------------------------------------+
| Warning | 1265 | Data truncated for column 'b' at row 1 |
+---------+------+----------------------------------------+
查询结果:
mysql> select * from test2;
+---+------+
| a | b |
+---+------+
| 1 | a |
| 2 | aa |
| 3 | aaa |
| 4 | aaaa |
| 5 | aaaa |
| 6 | te11 |
+---+------+
mysql> CREATE TABLE `test3` (
-> `var` varchar(21845) default NULL
-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8
-> ;
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to change some columns to TEXT or BLOBs
提示:VARCHAR(N) 指的是可以存放的最大字符个数,不是字节数。
需要区分字符和字节。一个汉字,一个数字,一个字母都是一个字符。
字节是计算机的基础存储单元,8位一个字节。 具体区分可以查看 字符,字节和编码
因为VARCHAR列中的值为可变长字符串。长度可以指定为0到65,535之间的值。(VARCHAR的最大有效长度由最大行大小和使用的字符集确定。整体最大长度是65,532字节)。所以不同字符集对应的varchar可以支持的最大长度是不一样的。
字符类型若为gbk,每个字符最多占2个字节,最大长度不能超过32766;
字符类型若为utf8,每个字符最多占3个字节,最大长度不能超过21845。
若定义的时候超过上述限制,则varchar字段会被强行转为text类型,并产生warning。
实践出真知:
表结构如下:
CREATE TABLE `test2` (
`a` int(11) NOT NULL,
`b` varchar(4) DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
插入数据:
mysql> insert into test2 values (1,'a');
Query OK, 1 row affected (0.04 sec)
mysql> insert into test2 values (2,'aa');
Query OK, 1 row affected (0.01 sec)
mysql> insert into test2 values (3,'aaa');
Query OK, 1 row affected (0.04 sec)
mysql> insert into test2 values (4,'aaaa');
Query OK, 1 row affected (0.08 sec)
mysql> insert into test2 values (5,'aaaaa');
Query OK, 1 row affected, 1 warning (0.04 sec) //超过字段设定的最大长度,会出现警告,这个跟你设置的库SQL服务器模式有关系,也会报错。 出现警告后自动的截取最大长度的字符串
mysql> show warnings;
+---------+------+----------------------------------------+
| Level | Code | Message |
+---------+------+----------------------------------------+
| Warning | 1265 | Data truncated for column 'b' at row 1 |
+---------+------+----------------------------------------+
mysql> insert into test2 values (6,'te111'); //可以看到的是存储的是字符个数,而不是字节数
Query OK, 1 row affected, 1 warning (0.03 sec)
mysql> show warnings;
+---------+------+----------------------------------------+
| Level | Code | Message |
+---------+------+----------------------------------------+
| Warning | 1265 | Data truncated for column 'b' at row 1 |
+---------+------+----------------------------------------+
查询结果:
mysql> select * from test2;
+---+------+
| a | b |
+---+------+
| 1 | a |
| 2 | aa |
| 3 | aaa |
| 4 | aaaa |
| 5 | aaaa |
| 6 | te11 |
+---+------+
mysql> CREATE TABLE `test3` (
-> `var` varchar(21845) default NULL
-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8
-> ;
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to change some columns to TEXT or BLOBs