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
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 数据库 varchar 到底可以存多少个汉字,多少个英文呢?我们来搞搞清楚的更多相关文章
- SQL 中nvarchar和varchar到底能存多少汉字和英文
实践出真知,在SQL中,nvarchar(50)表示汉字和英文都是50,varchar(50)汉字25,英文50
- mysql varchar到底能存多少字符。
utf8编码的varchar Mysql记录行数据是有限的.大小为64k,即65535个字节,而varchar要用1-2字节来存储字段长度,小于255的1字节,大于255的2字节. Mysql 5.0 ...
- c# 操作mysql数据库的时候会出现 插入中文汉字变成问号?
场景: 在mysql ce里面执行时没有问题的. c#操作会出现问号. 原因是: 链接字符串的时候 要设置Charset=utf8; 不然就会按默认的服务器设置编码,通常会出问题. 检查: 1.创建 ...
- MySQL中varchar最大长度是多少?
一. varchar存储规则: 4.0版本以下,varchar(20),指的是20字节,如果存放UTF8汉字时,只能存6个(每个汉字3字节) 5.0版本以上,varchar(20),指的是20字符,无 ...
- MySQL中varchar最大长度是多少
一. varchar存储规则: 4.0版本以下,varchar(20),指的是20字节,如果存放UTF8汉字时,只能存6个(每个汉字3字节) 5.0版本以上,varchar(20),指的是20字符,无 ...
- MySQL数据类型varchar详解
1.varchar(N)的逻辑意义从MySQL 4.1开始,varchar(N)中的N指的是该字段最多能存储多少个字符(characters),不是字节数.不管是一个中英文字符或者数字.或者一个汉字, ...
- mysql数据库的安装步骤
Redhat6.5 1.准备工作 卸载使用rpm包安装的mysql-server.mysql软件包 安装自带的ncurses-devel包 rpm -ivh /mnt/Packages/ncurses ...
- JDBC对MySQL数据库存储过程的调用
一.MySQL数据库存储过程: 1.什么是存储过程 存储过程(英文:Stored Procedure)是在大型数据库系统中,为了完成特定功能而编写的一组的SQL语句集.存储过程经编译存储在数据库中,用 ...
- mysql中varchar(50)最多能存多少个汉字
首先要确定mysql版本4.0版本以下,varchar(50),指的是50字节,如果存放UTF8汉字时,只能存16个(每个汉字3字节) 5.0版本以上,varchar(50),指的是50字符,无论存放 ...
随机推荐
- 最NB的发现 LINUX 下玩teamviewer 命令行设置密码
cd /opt/teamviewer/tv_bin/ [root@666 tv_bin]# ls desktop script teamviewerd TVGuiSlave.32 xdg-utils ...
- angular指令中使用ngModelController
在这篇文章中 angular学习笔记(三十)-指令(10)-require和controller 说到了通过require属性和controller参数来让指令与指令之间互相交互. 本篇主要介绍的是指 ...
- git for windows 无法提交修改的处理
在git for windows里面不能commit修改,提示open shell open shell以后,使用git add [filename],会报错: fatal: Unable to cr ...
- angular学习笔记(三十)-指令(2)-restrice,replace,template
本篇主要讲解指令中的 restrict属性, replace属性, template属性 这三个属性 一. restrict: 字符串.定义指令在视图中的使用方式,一共有四种使用方式: 1. 元素: ...
- (原创)用c++11实现简洁的ScopeGuard
ScopeGuard的作用是确保资源面对异常时总能被成功释放,就算没有正常返回.惯用法让我们在构造函数里获取资源,当因为异常或者正常作用域结束,那么在析构函数里释放资源.总是能释放资源.如果没有异常抛 ...
- python使用requests时报错requests.exceptions.SSLError: HTTPSConnectionPool
报错信息 Traceback (most recent call last): File "<stdin>", line 1, in <module> Fi ...
- DIOCP开源项目-DIOCP3的重生和稳定版本发布
DIOCP3的重生 从开始写DIOCP到现在已经有一年多的时间了,最近两个月以来一直有个想法做个 30 * 24 稳定的企业服务端架构,让程序员专注于逻辑实现就好.虽然DIOCP到现在通讯层已经很稳定 ...
- java中的动态加载和热替换
https://blog.csdn.net/u010833547/article/details/54312052 ****************************************** ...
- 【Ubuntu】VirtualBox 您没有查看“sf_VirtualDisk”的内容所需的权限。
转自:https://www.cnblogs.com/laishenghao/p/5346651.html 最终解决办法: sudo adduser lqr vboxsf 这里lqr是我的用户名 然后 ...
- eclipse Maven 使用记录 ------ 建立app项目
maven 项目构建工具 , 如今已逐渐取代ant的笨拙配置方式 ,使项目管理更加简单,规范,结构更加清晰,这里记录跟eclipse集成的一些步骤 1.从apache maven项目下下载maven ...