MySQL数据库varchar到底可以存多少个汉字,多少个英⽂呢?我们来搞搞清楚⼀、关于UTF-8
UTF-8 Unicode Transformation Format-8bit。是⽤以解决国际上字符的⼀种多字节编码。
它对英⽂使⽤8位(即⼀个字节) ,中⽂使⽤24位(三个字节)来编码。
UTF-8包含全世界所有国家需要⽤到的字符,是国际编码,通⽤性强。
UTF-8编码的⽂字可以在各国⽀持UTF8字符集额的浏览器上显⽰。
如果是UTF8编码,则在外国⼈的英⽂IE也能显⽰中⽂,他们⽆需下载IE的中⽂语⾔⽀持包。
⼆、关于GBK
GBK是国家标准GB2312基础上扩容后兼容GB2312的标准。
GBK的⽂字编码是⽤双字节来表⽰的,即不论中、英⽂字符均使⽤双字节来表⽰,为了区分中⽂,将其最⾼位都设定成1。
GBK包含全部中⽂字符,是国家编码,通⽤性⽐UTF8差,不过UTF8占⽤的⽐GBK⼤。
三、关于utf8mb4
5.5 之前,UTF8 编码只⽀持1-3个字节,只⽀持BMP这部分的unicode编码区,BMP是从哪到哪?
基本就是 0000 ~ FFFF 这⼀区。
从 5.5 开始,可⽀持4个字节UTF编码utf8mb4,⼀个字符最多能有4字节,所以能⽀持更多的字符集。
utf8mb4 is a superset of utf8
tf8mb4兼容utf8,且⽐utf8能表⽰更多的字符。
⾄于什么时候⽤,看你做的什么项⽬了。。。
在做移动应⽤时,会遇到⽤户在⽂本的区域输⼊emoji表情,如果不做⼀定处理,就会导致插⼊数据库异常。
四、汉字长度与编码有关
MySql 5.0 以上的版本:
1、⼀个汉字占多少长度与编码有关:
UTF-8:⼀个汉字 = 3个字节,英⽂是⼀个字节
GBK:⼀个汉字 = 2个字节,英⽂是⼀个字节
2、varchar(n) 表⽰n个字符,⽆论汉字和英⽂,MySql都能存⼊n个字符,仅实际字节长度有所区别。
3、MySQL检查长度,可⽤SQL语⾔
SELECT LENGTH(fieldname) FROM tablename
五、实际测试
1、⾸先使⽤utf8创建str_test表。
CREATE TABLE `str_test` (
`name_chn` varchar(20) NOT NULL,
`name_en`  varchar(20) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=62974 DEFAULT CHARSET=utf8
然后插⼊值
mysql> insert into  str_test values ('我爱Ruby', 'I Love Ruby!');
Query OK, 1 row affected (0.02 sec)
打开irb
>> "我爱Ruby".size
=> 6
>> "I Love Ruby!".size
=> 12
>>
从MySQL中查询出来的结果,对⽐
mysql> select * from str_test;
+------------+--------------+
| name_chn  | name_en      |
+------------+--------------+
| 我爱Ruby  | I Love Ruby! |
+------------+--------------+
1 row in set (0.0
2 sec)
mysql> select length(name_chn) from str_test;
+------------------+
| length(name_chn) |
+------------------+
|              10 |
+------------------+
1 row in set (0.01 sec)
3[⼀个汉字三字节] * 2 + 1[⼀个英⽂⼀字节] * 4 = 10
mysql> select length(name_en) from str_test;
+-----------------+
| length(name_en) |
+-----------------+
|              12 |
+-----------------+sql包含哪几个部分
1 row in set (0.00 sec)
10[⼀个英⽂⼀字节] * 1 + 2[空格⼀字节] * whitespace = 12
2、使⽤GBK做
创建表
CREATE TABLE `str_test` (
`name_chn` varchar(20) NOT NULL,
`name_en`  varchar(20) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=62974 DEFAULT CHARSET=gbk
插⼊数据,并且测试
mysql> insert into  str_test values ('我爱Ruby', 'I Love Ruby!');
Query OK, 1 row affected (0.00 sec)
mysql> select * from str_test;
+------------+--------------+
| name_chn  | name_en      |
+------------+--------------+
| 我爱Ruby  | I Love Ruby! |
+------------+--------------+
1 row in set (0.01 sec)
GBK中⽂是两个字节,英⽂是⼀个字节。
mysql> select length(name_chn) from str_test;
+------------------+
| length(name_chn) |
+------------------+
|                8 |
+------------------+
1 row in set (0.00 sec)
2[中⽂两个字节] * 2 + 4[英⽂⼀个字节] * 1 = 8
mysql> select length(name_en) from str_test;
+-----------------+
| length(name_en) |
+-----------------+
|              12 |
+-----------------+
1 row in set (0.00 sec)
10[英⽂⼀个字节] * 1 + 2[空格⼀个字节] * whitespace = 12
六、关于varchar 最多能存多少值
mysql的记录⾏长度是有限制的,不是⽆限长的,这个长度是64K,即65535个字节,对所有的表都是⼀样的。
MySQL对于变长类型的字段会有1-2个字节来保存字符长度。
当字符数⼩于等于255时,MySQL只⽤1个字节来记录,因为2的8次⽅减1只能存到255。
当字符数多余255时,就得⽤2个字节来存长度了。
在utf-8状态下的varchar,最⼤只能到 (65535 - 2) / 3 = 21844 余 1。
在gbk状态下的varchar, 最⼤只能到 (65535 - 2) / 2 = 32766 余 1
使⽤utf-8创建
mysql>    CREATE TABLE `str_test` (
->        `id`  tinyint(1)  NOT NULL,
->        `name_chn` varchar(21845) NOT NULL
->    ) ENGINE=InnoDB AUTO_INCREMENT=62974 DEFAULT CHARSET=utf8
-> ;
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs        mysql>    CREATE TABLE `str_test` (
->        `id`  tinyint(1)  NOT NULL,
->        `name_chn` varchar(21844) NOT NULL
->    ) ENGINE=InnoDB AUTO_INCREMENT=62974 DEFAULT CHARSET=utf8
->
->
-> ;
Query OK, 0 rows affected (0.06 sec)
使⽤gbk创建
当存储长度为 32768 失败~
mysql>    CREATE TABLE `str_test` (
->        `id`  tinyint(1)  NOT NULL,
->        `name_chn` varchar(32768) NOT NULL
->    ) ENGINE=InnoDB AUTO_INCREMENT=62974 DEFAULT CHARSET=gbk
-> ;
ERROR 1074 (42000): Column length too big for column 'name_chn' (max = 32767); use BLOB or TEXT instead
当存储长度为 32767 失败~
mysql>    CREATE TABLE `str_test` (                                                                                                ->        `id`  tinyint(1)  NOT NULL,
->        `name_chn` varchar(32767) NOT NULL
->    ) ENGINE=InnoDB AUTO_INCREMENT=62974 DEFAULT CHARSET=gbk
-> ;
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs 当存储长度为 32766 成功~
mysql>    CREATE TABLE `str_test` (
->        `id`  tinyint(1)  NOT NULL,
->        `name_chn` varchar(32766) NOT NULL
->    ) ENGINE=InnoDB AUTO_INCREMENT=62974 DEFAULT CHARSET=gbk
-> ;
Query OK, 0 rows affected (0.03 sec)
smallint ⽤两个字节存储,所以
2[smallint] + 32766 * 2[varchar存储长度] + 2[2个字节来存长度] > 65535
所以失败~
mysql>    CREATE TABLE `str_test` (
->        `id`  smallint(1)  NOT NULL,
->        `name_chn` varchar(32766) NOT NULL
->    ) ENGINE=InnoDB AUTO_INCREMENT=62974 DEFAULT CHARSET=gbk
-> ;
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs >七、数值类型所占的字节
类型所占字节
int  4 字节
smallint2 字节
tinyint  1 字节
decimal变长
官⽅关于decimal的描述如下
Values for DECIMAL (and NUMERIC) columns are represented using a binary format that packs nine decimal (base 10) digits into four bytes.
Storage for the integer and fractional parts of each value are determined separately.
Each multiple of nine digits requires four bytes, and the “leftover” digits require some fraction of four bytes.
The storage required for excess digits is given by the following table.
翻译为中⽂
使⽤⼆进制格式将9个⼗进制(基于10)数压缩为4个字节来表⽰DECIMAL列值。
每个值的整数和分数部分的存储分别确定。
每个9位数的倍数需要4个字节,并且“剩余的”位需要4个字节的⼀部分。
下表给出了超出位数的存储需求:
Leftover Digits Number Of Bytes
00
11
21
32
42
53
63
74
84
那:decimal(10,2)占⼏个字节?
1、⾸先 10 指的是整数与⼩数部分的总长度, 2指的是⼩数部分的长度。那么整数部分就只有 10 - 2 = 8 位
2、因为整数与⼩数的存储市各⾃独⽴确定的,所以他们各⾃所占⽤空间的综合就是所占的总空间了。
3、对表可知,整数部分8位占了4个字节,⼩数部分2位占了1个字节,所以decimal(10,2)总共占了 4 + 1 = 5 个字节。
4、decimal(6,2) 整数部分(6 - 2 = 4) 位占2字节,⼩数部分2位占1字节,总共占3字节。
⼋、总结
varchar 字段是将实际内容单独存储在聚簇索引之外,内容开头⽤1到2个字节表⽰实际长度(长度超过2
55时需要2个字节),因此最⼤长度不能超过65535。
UTF-8:⼀个汉字 = 3个字节,英⽂是⼀个字节
GBK:⼀个汉字 = 2个字节,英⽂是⼀个字节
在utf-8状态下,汉字最多可以存 21844个字符串, 英⽂也为 21844个字符串。
在gbk状态下,汉字最多可以存 32766个字符串,英⽂也为 32766个字符串。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。

发表评论