背景
编程过程中在存储用户数据的时候,会遇到数据存储大小的限制。经常遇到的限制可以分为:用户侧、服务端、数据库三个方面,按照流程可以划分为5个阶段,如图所示。作为开发人员,需要了解这些限制,避免撞墙。
第一道墙-client:浏览器限制
用户通过http请求提交数据,http请求本身是没有数据大小的限制,但是浏览器对URI的长度进行了限制。
浏览器限制的是URI长度,而不是你的请求参数
浏览器 | 限制大小(字符) |
---|---|
IE | 2083 |
Chrome | 8182 |
curl | 8167 |
汉字字符:在utf-8编码格式中,3个字节,在gbk编码中,2个字节,英文就一个字符一个字节
超过限制长度就会返回错误码414
第二道墙-server:服务端限制
服务端对于数据的处理能力不同,对于提交的数据限制能力也不同,不同服务器对请求的限制不同,会存在两个方面的限制:
- URI长度限制(以Node为例)
- 数据包大小限制(以post请求为例)
Node
Node对URI的大小有一定的大小限制, 最大值8kb(8 * 1024),
一般情况下,不会触发这个限制,如果程序想单独限制一个大小,通过中间件限制下就行了
req.on('data', function(chunk){
received += chunk.length;
if (received > bytes) req.destroy();
});
如果想修改最大的大小,只能去改变源码文件 http_parser.h
了
POST
服务器 | 限制大小(字符) |
---|---|
apache | 8192 |
IIS | 16384 |
nginx | 8kb |
附加:
get请求是幂等操作,所以可以用缓存来处理,post请求不是幂等的,所以无法应用缓存
第二道墙-数据库代理:DBProxy
线上环境会部署几个数据库,通常情况下,会使用DBProxy进行代理,实现负载均衡、IP地址过滤、数据库分表等操作。常见的数据库代理mycat/mybuh/dbproxy等。不同的数据库代理默认的数据大小不同,比如有的公司,DBProxy的代理设置大小最大为150kb。
第三道墙-max_allowed_packet
在实际读写数据库的时候,数据库本身会有容量限制,mysql中max_allow_packet,就是第三道墙。max_allow_pocket是数据库对于单个数据包的大小限制。
参数 | 大小 |
---|---|
默认大小 | 64M(v >= 8.0.3)/4M |
最大值 | 1G |
第四道墙-数据库本身大小限制
每一条数据在数据库中都有对应的字段对应,而每一个字段会有对应的大小限制,所以在写入数据库的时候就有对应的大小限制。下面以mysql数据库为例说明一下:
mysql的数据库类型分为五类:数字类型、日期类型、字符串类型,特殊类型、JSON类型
数字类型
类型 | 存储(位) | 无符号范围 | 有符号范围 | 默认值 |
---|---|---|---|---|
TINYINT | 1 | -128~127 | 0~255 | |
SMALLINT | 2 | -32768~32767 | 0~65535 | |
MEDIUMINT | 3 | -8388608~8388607 | 0~16777215 | |
INT | 4 | -2147483648~2147483647 | 0~4294967295 | |
BIGINT | 8 | -2的63方~2的63方-1 | 0~2的64方-1 |
注意⚠️:超过范围怎么处理?
- 在严格模式下,会直接报错
- 在非严格模式下,会显示范围的边界,比如要存储9223372036854775808的值,会显示9223372036854775807,因为有符号整数最大值为9223372036854775807
假如就是想显示这样的值怎么办?
将值变为有符号的,或者使用字符串。
其他基本的数据类型和大小,在这里就不赘述了查看详情
JSON类型
对于JSON数据类型,可以通过JSON_STORAGE_SIZE
,获取可以存储的JSON数据的大小
总结
本文目的不是让你记住这些限制,而是让你知道哪里有数据存储的限制,当出现问题的时候,知道去哪里排查。
参考文献
JSON MERGE FUNCTION
对GET和POST的理解很形象
url长度限制
如何选择合适的数据库代理
美团点评的DBProxy
常见的Mysql数据库类型
长度限制
推荐一个面试
JSON_STORAGE_SIZE()