热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

mysql7tf8,mysql数据库varchar到底可以存多少数据呢,长文慎入

一、关于UTF-8UTF-8UnicodeTransformationFormat-8bit。是用以解决国际上字符的一种多字节编码。它对英文使用8位(即一个字节),中

一、关于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个字符串,英文也为21844个字符串。

参考



推荐阅读
  • 点此学习更多SQL相关函数与字符串处理函数mysql函数一、简明总结ASCII(char)        返回字符的ASCII码值BIT_LENGTH(str)      返回字 ... [详细]
  • MySQL 数据库基础学习 一、SQL的作用及分类 二、数据类型 三、存储引擎  (建库建表、数据插入等))
    MySQL 数据库基础学习 一、SQL的作用及分类 二、数据类型 三、存储引擎 (建库建表、数据插入等)) ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • This article discusses the efficiency of using char str[] and char *str and whether there is any reason to prefer one over the other. It explains the difference between the two and provides an example to illustrate their usage. ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • 本文由编程笔记#小编整理,主要介绍了关于数论相关的知识,包括数论的算法和百度百科的链接。文章还介绍了欧几里得算法、辗转相除法、gcd、lcm和扩展欧几里得算法的使用方法。此外,文章还提到了数论在求解不定方程、模线性方程和乘法逆元方面的应用。摘要长度:184字。 ... [详细]
  • 在Oracle11g以前版本中的的DataGuard物理备用数据库,可以以只读的方式打开数据库,但此时MediaRecovery利用日志进行数据同步的过 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • 合并列值-合并为一列问题需求:createtabletab(Aint,Bint,Cint)inserttabselect1,2,3unionallsel ... [详细]
  • 本文介绍了一种在PHP中对二维数组根据某个字段进行排序的方法,以年龄字段为例,按照倒序的方式进行排序,并给出了具体的代码实现。 ... [详细]
author-avatar
润秋赋_137
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有