当前位置:网站首页>MySQL数据库字段超长问题
MySQL数据库字段超长问题
2022-07-30 20:00:00 【adrninistrat0r】
1. 存在的问题
在向MySQL数据库表中插入或更新记录时,有时会出现字段超长的问题,包括但不限于以下场景:
处理上游系统发送的交易信息,将多个字段拼成一个JSON或其他格式的字符串;在增加字段,或数据较长时,写入或更新数据库时可能超长;
调用下游系统的服务,返回的部分字段(如错误信息等)较长时,导致更新数据库记录失败。
2. 问题解决与优化建议
2.1. JSON等格式的字段
有业务含义的重要字段,不建议通过JSON字符串格式保存在一个数据库字段中。
假如需要将字段以JSON字符串格式保存在一个数据库字段中,建议只保存相对不重要,且不需要作为唯一的查询条件的字段,在进行保存时也需要考虑字段超长问题,及新旧数据与新旧代码相互之间的兼容问题。
2.1.1. MySQL字符串字段长度
半角英文字母、数字、符号等常见字符,1个字符占用1个字节;1个汉字字符占用3个字节。
在utf8字符集下,1个字符最多占用3个字节,不支持占用4个字节的字符。
在utf8mb4字符集下,1个字符最多占用4个字节,可以保存emoji表情等占用4个字节的字符。
MySQL字符串字段的最大长度如下所示:
类型 | 最大长度 | 单位 |
---|---|---|
CHAR(n) | 255 | 字符数 |
VARCHAR(n) | 65535 | 字符数 |
TINYTEXT | 255 | 字节数 |
TEXT | 65535 | 字节数 |
MEDIUMTEXT | 16777215 | 字节数 |
LONGTEXT | 4294967295 | 字节数 |
需要注意,CHAR、VARCHAR类型字段的最大长度的单位为字符数,能够保存的汉字数量等于最大支持字符数
;
TEXT等类型字段的最大长度的单位为字节数,能够保存的汉字数量不超过最大支持字节数的1/3
。
2.1.2. MySQL使用较长的字符串类型字段影响
MySQL、MariaDB较新版本支持JSON类型字段,其他版本需要使用字符串类型字段保存。
MySQL中长度超过768字节的固定长度字段被编码为变长字段,例如VARCHAR(超过768字节)、TEXT等,变长字段被称为页外列(off-page),不是保存在InnoDB的B+树索引中,而是保存在溢出页(overflow page)中。在溢出页中,变长字段的值以单链表形式存储。
对于保存JSON形式的字符串类型字段,由于需要保存较多内容,很可能属于变长字段。保存JSON形式的字符串类型字段不适合在查询时作为唯一的查询条件,原因如下:
保存JSON形式的字符串类型字段不适合创建索引:一是JSON字符串中的字段顺序不固定,通过like进行最左匹配查询,很难从保存JSON形式的字段中查询到需要的数据;二是因为InnoDB索引支持的长度有限(在MySQL InnoDB默认配置下,索引支持的最大长度为768字节);
仅通过变长字段进行查询时,无法通过B+树结构的索引进行查询,而是需要在单链表形式的溢出页中逐条进行查询,查询效率会非常低。
查询变长字段,与不查询变长字段相比,开销会更大,耗时会更长。因为查询变长字段时,会增加从溢出页中查询数据的步骤;且需要返回的数据量可能较大,数据返回耗时会增加。
在查询包含变长字段的数据库表时,假如不需要获取变长字段,则不应该在SQL语句中指定查询变长字段。
2.2. 可以截断的字段
对于截断后不影响使用的字段,在写入或更新数据库时,可对存在超长风险的字段按照数据库字段长度进行截断;
JDK中的String.substring()方法,commons-lang3中的StringUtils.substring()、StringUtils.truncate()方法,参数中的数字单位都是字符数,不是字节数。
在Java中对字符串进行截取时,建议使用StringUtils.truncate()方法。
MySQL中的CHAR、VARCHAR类型的最大长度,也是字符数,不是字节数。
因此在Java中对字符串根据MySQL的字符串类型字段长度进行截取时,两者的长度是一致的。
例如MySQL中的字段为VARCHAR(200),则可使用以下方式进行截取,将截取结果写入数据库。
StringUtils.truncate("xxx", 200);
边栏推荐
- OSS简单上传图片
- KEIL问题:【keil Error: failed to execute ‘C:\Keil\ARM\ARMCC‘】
- Database indexes: indexes are not a panacea
- 【Node实现数据加密】
- Ordinary int main(){} does not write return 0; what will happen?
- 多线程的互斥锁应用RAII机制
- Cesium加载离线地图和离线地形
- VBA runtime error '-2147217900 (80040e14): Automation error
- LeetCode 0952. Calculate Maximum Component Size by Common Factor: Mapping / Union Search
- HarmonyOS笔记-----------(三)
猜你喜欢
[PyTorchVideo Tutorial 01] Quickly implement video action recognition
历史上的今天:Win10 七周年;微软和雅虎的搜索协议;微软发行 NT 4.0
HCIP --- 企业网的三层架构
Difference Between Concurrency and Parallelism
Centos7 install mysql8
centos7安装mysql8
Install Mysql5.7 under Linux, super detailed and complete tutorial, and cloud mysql connection
MySQL数据库 ---MySQL表的增删改查(进阶)
推荐系统:评估指标【离线评估指标:RMSE(均方根误差)、AUC、准确率、召回率、F1】【在线评估:A/B测试】【一般要求响应时间<0.5s】
阿里面试官:给我描述一下缓存击穿的现象,并说说你的解决思路?
随机推荐
英文字母间隔突然增大(全角与半角转换)
M3SDA: Moment matching for multi-source domain adaptation
TensorFlow2: Overview
推荐系统:AB测试(AB Test)
18.客户端会话技术Cookie
The 17th "Revitalization Cup" National Youth Vocational Skills Competition - Computer Programmers (Cloud Computing Platform and Operation and Maintenance) Participation Review and Summary
After MySQL grouping, take the largest piece of data [optimal solution]
Linux下安装Mysql5.7,超详细完整教程,以及云mysql连接
MySQL mass production of data
【私人系列】日常PHP遇到的各种稀奇古怪的问题
一文2500字手把手教你配置Jenkins自动化邮件通知
MySQL性能优化(硬件,系统配置,表结构,SQL语句)
MySQL八股文背诵版
mysql8 installation under linux
Zabbix 5.0 监控教程(一)
【请教】SQL语句按列1去重来计算列2之和?
明解C语言第七章习题
Start foreground Activity
Based on the face of the common expression recognition - model building, training and testing
Linux下载安装mysql5.7版本教程最全详解