一、关于 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

MySql 5.5 之前,UTF8 编码只支持 1-3 个字节,只支持 BMP 这部分的 unicode 编码区,BMP 是从哪到哪?

戳这里 基本就是 0000 ~ FFFF 这一区。

从 MySQL 5.5 开始,可支持 4 个字节 UTF 编码 utf8mb4,一个字符最多能有 4 字节,所以能支持更多的字符集。

utf8mb4 is a superset of utf8

tf8mb4 兼容 utf8,且比 utf8 能表示更多的字符。

至于什么时候用,看你做的什么项目了。。。

在做移动应用时,会遇到IOS用户在文本的区域输入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.02 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 |

+-----------------+

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 字节

smallint

2 字节

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

0

0

1

1

2

1

3

2

4

2

5

3

6

3

7

4

8

4

那: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 个字节表示实际长度(长度超过 255 时需要 2 个字节),因此最大长度不能超过 65535。

UTF-8:一个汉字 = 3 个字节,英文是一个字节

GBK: 一个汉字 = 2 个字节,英文是一个字节

在utf-8状态下,汉字最多可以存 21844个字符串, 英文也为 21844个字符串。

在gbk状态下,汉字最多可以存 32766个字符串,英文也为 32766个字符串。

参考

mysql 英文占几个字符_MySQL 数据库 varchar 到底可以存多少个汉字,多少个英文呢?我们来搞搞清楚...相关推荐

  1. MySQL 数据库 varchar 到底可以存多少个汉字,多少个英文呢?我们来搞搞清楚

    MySQL 数据库 varchar 到底可以存多少个汉字,多少个英文呢?我们来搞搞清楚 一.关于UTF-8 UTF-8 Unicode Transformation Format-8bit.是用以解决 ...

  2. mysql varchar 2000能存_mysql 数据库 varchar 到底可以存多少数据呢,长文慎入

    一.关于UTF-8 UTF-8 Unicode Transformation Format-8bit.是用以解决国际上字符的一种多字节编码. 它对英文使用8位(即一个字节),中文使用24位(三个字节) ...

  3. 英文、数字和汉字、日文的字符判断 英文占1个字符,中文汉字占2个字符 el-form表单验证规则

    需求:输入框输入如果是中文或者日文,表单验证长度需要除以2,如果是英文或者数字,则正常 需求奇葩,还要国际化可烦死我了,菜鸟又不敢跟产品顶嘴,哭了 捣鼓捣鼓总算好了,对字符限制做了一个封装 1.第一步 ...

  4. html表单判断字符数,JS判断字符串长度,结合element el-input el-form 表单验证(英文占1个字符,中文汉字占2个字符)...

    首先看看判断字符串长度的几种方法(英文占1个字符,中文汉字占2个字符) 方法一: function strlen(str) { var len = 0; for (var i = 0; i < ...

  5. JS判断字符串长度(英文占1个字符,中文汉字占2个字符)

    //计算字符串长度(英文占1个字符,中文汉字占2个字符) 方法一: String.prototype.gblen = function() { var len = 0; for (var i=0; i ...

  6. mysql中的字符是多长_mysql中的varchar到底能存多长的字符

    这个问题真的不简单. 我本地的数据库是mysql5.5 先看一下建表语句: CREATE TABLE `shop` ( `id` int(11) NOT NULL AUTO_INCREMENT COM ...

  7. mysql utf8占几个字节_数据库表字段缓存_一个汉字在数据库占几个字节?

    1.oracle10g数据库表字段为varchar(n)类型,存英文很简单,只要字母个数不大于n即可. 但是对于汉字,按照同样的方法就不行了.因为对于汉字不同的字符集, 在数据库占用的字节是不一样的. ...

  8. c 添加mysql表单的一行数据类型_MySQL数据库基础

    安装mysql [root@ultraera ~]# yum install mysql mysql-server mysql-devel 2.启动mysql,并设置开机自启动 [root@ultra ...

  9. mysql 修改库的校对集_mysql数据库的基本操作(增删改查、字符集、校对集)

    MySQL数据库概述 MySQL数据库是经典的关系型数据库管理系统,MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Dat ...

最新文章

  1. 查看oralce的版本及安装了哪些选项
  2. 对NUnitAddIn做了下修改
  3. 数据产品必知的4层技术知识
  4. SSM-网站后台管理系统制作(2)---SSM基本工作原理
  5. 逻辑漏洞之任意用户登陆漏洞
  6. 跟我一起学.NetCore之Swagger让前后端不再烦恼及界面自定义
  7. 数据结构之二叉树:折纸问题——11
  8. 信息学奥赛一本通(1197:山区建小学)
  9. 基于GEE平台分析湖北省近35年地表水变化特征
  10. springboot+vue3+微信小程序活动报名系统源码
  11. 计算机中¥符号按哪个键,人民币键盘符号怎么打 电脑怎么打人民币符号
  12. 【Linux】域名解析
  13. 本地用户和组 无法访问计算机 远程过程调用失败,如何解决远程过程调用失败?怎样使用向日葵远程控制?...
  14. mysql ansi unicode_ANSI与Unicode编码
  15. 深圳-数据岗位面试不完全记录(回忆版)
  16. 工厂仪表定时拍照智能AI算法识别内网部署方案
  17. LaTex 表示 波浪线
  18. 视频营销(Video Marketing)1-视频营销基础
  19. 如何快速高效学习技术
  20. 库存量说明(可用量、现存量、预计入库量、冻结量、预计出库)

热门文章

  1. SQL Server pivot行列转换案例分析
  2. Python操作MySQL数据库的三种方法
  3. 【python 图像处理】skimage的子模块介绍
  4. vue Cli 脚手架的搭建
  5. 关于Exchange邮箱服务器角色故障排查及解决思路分享
  6. 泰一指尚大数据应用成为第一批省级重点企业研究院
  7. Centos7单用户模式修改root密码
  8. 《C++编程风格(修订版)》——2.5 动态内存的一致性
  9. 线性时间排序--桶排
  10. 【C++】函数缺省参数的作用