背景

编程过程中在存储用户数据的时候,会遇到数据存储大小的限制。经常遇到的限制可以分为:用户侧、服务端、数据库三个方面,按照流程可以划分为5个阶段,如图所示。作为开发人员,需要了解这些限制,避免撞墙。

第一道墙-client:浏览器限制

用户通过http请求提交数据,http请求本身是没有数据大小的限制,但是浏览器对URI的长度进行了限制。

浏览器限制的是URI长度,而不是你的请求参数
浏览器限制大小(字符)
IE2083
Chrome8182
curl8167
汉字字符:在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

服务器限制大小(字符)
apache8192
IIS16384
nginx8kb

附加:
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类型

数字类型

类型存储(位)无符号范围有符号范围默认值
TINYINT1-128~1270~255
SMALLINT2-32768~327670~65535
MEDIUMINT3-8388608~83886070~16777215
INT4-2147483648~21474836470~4294967295
BIGINT8-2的63方~2的63方-10~2的64方-1

注意⚠️:超过范围怎么处理?

  • 在严格模式下,会直接报错
  • 在非严格模式下,会显示范围的边界,比如要存储9223372036854775808的值,会显示9223372036854775807,因为有符号整数最大值为9223372036854775807

假如就是想显示这样的值怎么办?

将值变为有符号的,或者使用字符串。

其他基本的数据类型和大小,在这里就不赘述了查看详情

JSON类型

对于JSON数据类型,可以通过JSON_STORAGE_SIZE,获取可以存储的JSON数据的大小

总结

本文目的不是让你记住这些限制,而是让你知道哪里有数据存储的限制,当出现问题的时候,知道去哪里排查。

参考文献

JSON MERGE FUNCTION
对GET和POST的理解很形象
url长度限制
如何选择合适的数据库代理
美团点评的DBProxy
常见的Mysql数据库类型
长度限制
推荐一个面试
JSON_STORAGE_SIZE()