msyql存储数据时字段被截断
关于mysql中字段类型为text文本存储json格式数据,字段被截断的问题
背景:
字段类型 MEDIUMTEXT
确定存储内容5548个字符,换算为字节不超过16M
数据库内已经存在更长内容的存储成功,短的内容存储失败
有几率出现截断概率,
日志看入库前参数json都是完整的,入库后内容被截断,导致前端读取数据结构解析失败而报错
发生这种情况的原因有两种可能:
1. 建表时数据库字段设置长度不足
- 当输入内容的字符长度大于当前字段设置长度时,数据库会自动截断内容
字段类型以下几种:
字符串类型
类型 | 范围 | 说明 | |
---|---|---|---|
Char(N) [ binary] | N=1~255 个字节 binary :分辨大小写 | 固定长度 | std_name cahr(32) not null |
VarChar(N) [binary] | N=1~255 个字节 binary :分辨大小写 | 可变长度 | std_address varchar(256) |
TinyBlob | 最大长度255个字节(2^8-1) Blob (Binary large objects) | 储存二进位资料,且有分大小写 | memo text not null |
TinyText | 最大长度255个字节(2^8-1) | ||
Blob | 最大长度65535个字节(2^16-1) | ||
Text | 最大长度65535个字节(2^16-1) | ||
MediumBlob | 最大长度 16777215 个字节(2^24-1) | ||
MediumText | 最大长度 16777215 个字节(2^24-1 | ||
LongBlob | 最大长度4294967295个字节 (2^32-1) | ||
LongText | 最大长度4294967295个字节 (2^32-1) | ||
Enum | 集合最大数目为65535 | 列举(Enumeration),Enum单选、Set复选 | sex enum(1,0) habby set(‘玩电玩’,’睡觉’,’看电影’,’听音乐’) |
Set | 集合最大数目为64 |
- 数字/数值类型
类型 | 范围 | 说明 |
---|---|---|
TinyInt[M] [UNSIGNED] | -128~127 UNSIGNED : 0~255 | num tinyint unsigned |
SmallInt[M] [UNSIGNED] | -32768~32767 UNSIGNED :0~ 65535 | |
MediumInt[M] [UNSIGNED] | -8388608~8388607 UNSIGNED :0~16777215 | |
Int[M] [UNSIGNED] | -2^31~2^31-1 UNSIGNED : 0~2^32 | |
BigInt[M] [UNSIGNED] | -2^63~2^63-1 UNSIGNED : 0~2^64 | |
Float [(M,D)] | -3.4E+38~3.4E+38( 约 ) |
注: M 为长度, D 为小数,Float 4 bytes,Double 8 bytes Double [(M,D)] -1.79E+308~1.79E+308( 约 )Decimal [(M,D)] 辨別ZeroFill:当宣告关键字ZeroFill为自动填满0,如 000021
- 日期时间类型
类型 | 范围 |
---|---|
Date | 日期(yyyy-mm-dd) |
Time | 时间(hh:mm:ss) |
DateTime | 日期与时间組合(yyyy-mm-dd hh:mm:ss) |
TimeStamp | yyyymmddhhmmss |
Year | 年份yyyy |
- 根据计算转换字符长度可知,并没有超过长度限制,故此种原因排除
2. 字符编码格式数据库不支持
- 原数据库字符集设置为CHARSET=utf8,有些数据编码格式例如emoji的表情符号mysql 中的utf8并不支持
- 据官方文档的解释:
mysql 支持的 utf8 编码最大字符长度为 3 字节,如果遇到 4 字节的宽字符就会插入异常了。三个字节的 UTF-8 最大能编码的 Unicode 字符是 0xffff,也就是 Unicode 中的基本多文种平面(BMP)。
也就是说,任何不在基本多文本平面的 Unicode字符,都无法使用 Mysql 的 utf8 字符集存储。包括 Emoji 表情(Emoji 是一种特殊的 Unicode 编码,常见于 ios 和 android 手机上),和很多不常用的汉字,以及任何新增的 Unicode 字符等等。
观察日志数据发现linux下打印出的日志存在类似 <u+1f44d> 样式的字符,属于unicode编码的特殊字符,文本内容也是在此截断的,由此可以判断为字符编码格式问题
3. 解决方案
3.1 升级 mysql 版本,并将utf8字符集升级到utf8mb4
升级你的 mysql 到 5.5.3 之后即可,查看当前环境版本:
select version();
- MySQL在5.5.3之后增加了这个utf8mb4的编码,mb4就是most bytes 4的意思,专门用来兼容四字节的unicode。好在utf8mb4是utf8的超集,除了将编码改为utf8bp4外不需要做其他转换。当然,为了节省空间,一般情况下使用utf8也就够了。
- 所以好的技术就是,采用对当前而言最好的解决方案,然后再逐步迭代满足新的需求。
3.1.1 直接修改表结构
--修改数据库字符集
ALTER DATABASE test CHARACTER SET = utf8mb4;
--修改表字符集
alter table test convert to character set utf8mb4;
--修改字符字符集
ALTER TABLE `test` CHANGE COLUMN `name` `name` varchar(12) CHARACTER SET utf8mb4;
3.1.2 修改数据库默认配置
[client]
default-character-set = utf8mb4
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
[mysql]
default-character-set = utf8mb4
3.2 修改数据库字段类型
修改字段类型为二进制存储,通过样可以达到目的,进行兼容
--修改字符字符集
ALTER TABLE `test` CHANGE COLUMN `name` `name` MediumBlob ;
3.3 强行过滤掉生僻字符串
- 从业务和技术的角度综合考虑,可以做个折中,将生僻字符串提前过滤掉,因为这类字符串本来就使用的很少,即使存进数据库了,展示、查询的时候也会多少有其它的问题,不如直接过滤掉,mysql 不支持四字节的 utf8 一方面可能是历史包袱,另一方面估计也是为了省空间。
有意者可以进行测试
先向在数据库中建表以utf8字符集,字段设置为二进制文本类型或者
CREATE TABLE `ts_test` (
`id` int(10) NOT NULL,
`content` text NOT NULL CHARACTER SET utf8mb4, --或者 `content` BLOB NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
插入表情符号emoji
insert into ts_test ('id','content') values (1,'aaaaaaaa
msyql存储数据时字段被截断的更多相关文章
- PHPExcel导出数据时字段超过26列出错Invalid cell coordinate [1
http://blog.csdn.net/dl425134845/article/details/46650961 以下是解决方案函数 /** * 方法名: getExcel * 作用 ...
- python 大量使用json 存储数据时,格式化输出的方式
import json, pprint dic = {'name': 234, 'user_name': 'yan xia ting yu ', 'list': ['ds', 'a', 2], '你好 ...
- PlayerPrefs存储数据在本地的存储位置
PlayerPrefs存储数据时,其在windows的存储路径是注册表: HKEY_CURRENT_USER Software CompanyName ProjectName 其中的CompanyNa ...
- sql server的缺陷 将截断字符串或二进制数据 哪个字段
将截断字符串或二进制数据 哪个字段 消息 8152,级别 16,状态 14,第 2 行将截断字符串或二进制数据. sql server2000 sql server2014 也不能直接提示出哪个字段的 ...
- [MySQL]load data local infile向MySQL数据库中导入数据时,无法导入和字段不分离问题。
利用load data将文件中的数据导入数据库表中的时候,遇到了两个问题. 首先是load data命令无法执行的问题: 命令行下输入load data local infile "path ...
- MSSQL导入数据时,出现“无法截断表 因为表正由Foreign key引用”错误
* 错误 0xc002f210: 准备 SQL 任务: 执行查询“TRUNCATE TABLE [dsc100552_db].[dbo].[ALV_SalesBigClass] ”失败,错误如下:“无 ...
- 在向"带有自增字段的数据库表"中插入数据时,自定义"该自增字段"的数据
在设计数据库表的时候,经常会使用自增主键或其他自增字段.比如: DB_UserGroups表中GroupID为该表主键,并为自增字段. 但在将某字段设置自增后,想在插入数据时,人为指定自增字段的数据内 ...
- Android提供了5种方式存储数据:
--使用SharedPreferences存储数据: --文件存储数据: --SQLite数据库存储数据: --使用ContentProvider存储数据: --网络存储数据: 一:使用SharedP ...
- Android开发手记(18) 数据存储三 SQLite存储数据
Android为数据存储提供了五种方式: 1.SharedPreferences 2.文件存储 3.SQLite数据库 4.ContentProvider 5.网络存储 SQLite 是以嵌入式为目的 ...
随机推荐
- Servlet--创建和配置Servlet
在web开发中,一般由Servlet进行数据流的控制,并通过HttpServletResponse对象对请求做出响应.创建的Servlet必须继承HttpServlet类,并实现doGet()和doP ...
- 五分钟读懂UML类图(转)
平时阅读一些远吗分析类文章或是设计应用架构时没少与UML类图打交道.实际上,UML类图中最常用到的元素五分钟就能掌握,下面赶紧来一起认识一下它吧: 一.类的属性的表示方式 在UML类图中,类使用包含类 ...
- odoo12 物流 自动计算运费 ,采购销售使用不同计量单位自动换算
在物流和食品生鲜类行业,重量是很重要的因素,不仅要处理产品的数量,也要处理产品的重量.在多数行业,重量也是订单的重要数据. odoo原生包含了对重量的处理,下文中将指导如何优雅应用odoo原生模块处理 ...
- Java:配置环境(Mac)——Eclipse;修改JDK版本后,Eclipse打不开
1.官网下载 选择一个速度快的镜像 推荐东软这个 2.双击下载的安装包,下一步 其中有一步是选择Eclipse版本,SE选第一个,EE第二个.仔细审题吧. 3.配置JDK 应用.关闭 4.测试:写个H ...
- DVWA 黑客攻防演练(十三)JS 攻击 JavaScript Attacks
新版本的 DVWA 有新东西,其中一个就是这个 JavaScript 模块了. 玩法也挺特别的,如果你能提交 success 这个词,成功是算你赢了.也看得我有点懵逼. 初级 如果你改成 " ...
- LAMP动静分离安装(源码安装)
环境: 版本 IP地址 源码包版本 Centos7.5_mysql 192.168.111.3 mysql-5.7.24.tar.gz,cmake-3.13.1.tar.gz,boost_1_59_0 ...
- 关于SQL Server 数据库归档的一些思考和改进
一.需求背景 SQL Server开源的归档工具不多,DBA一般都是通过计划任务来触发执行,执行的脚本多是SP或者是SSIS包.SSIS包的性能稍好一些,但是维护更新成本高些.所以更常见的是通过SP脚 ...
- Web前端教程-HTML及标签的使用
目录 1. HTML简介 1.1. HTML文档基本结构 2. 标签 2.1. 标签语法 1.2. 标签的属性和值 1.3. 常见的标签 1. 基础标签 2. 格式标签 3. 表单标签 4. 框架标签 ...
- NOIP 2018 大翻车记
都9102年了我才想起来写游记啊 Day -1 肚子里翻江倒海,一天去了七次厕所.吃了PPA把病压下去.安慰一下自己,说这样会涨人品. Loli讲述学长们的翻车笔记.我大概像是玩笑一样听过去了.(伏笔 ...
- Linux基础学习:目录配置
Linux 目录配置标准:FHS FHS:即Filesystem Hierarchy Stabdard,文件配置标准.其主要目的是希望用户可以了解已安装软件通常放置在哪个目录下. FHS根据文件系统使 ...
- PHPExcel导出数据时字段超过26列出错Invalid cell coordinate [1