mysql int 11手机号_【mysql】我用不小心用 mysql 的int(11) 存了 手机号,数据都有问题,有办法恢复么?...
我用不小心用 mysql 的int(11) 存了用户的手机号,结果里面存的数据都是 10 位的,而且也不是单纯的被截断了一位,
比如手机号 18345231102 会被转成 4294967295
有办法恢复么,急。。。。。
问题补充:
1.数据库的存的手机号是类似这样的
511129633
437709550
947221024
1544096837
2770221786
3052396450
985251741
2147791994
1663290693
3067028521
842826454
2382976437
1811997122
2128974539
694514931
1816715878
876431887
737421250
1107794384
847325325
2.我问了下运维,是开了binlog 的,然后我跟他们要了一份。把里面所有的用户填手机号的sql的都找了出来,但是神奇的是sql里的手机号跟数据库里的是一样的,难道binlog里的sql是溢出之后的?
回答
对不起LZ了,这个答案正像Sunyanzi指出的,MySQL不是把高位字节吃掉而是转成了Int的最大值。
考虑到原先提交的答案还是花了点心思写的,就还留在这里了,也许对其他高位字节溢出的问题有所帮助。
这个有点意思,问题出在int只有4个字节,而手机号码是11位的十进制值由5个字节组成,所以转成int后最高位的第5个字节被“吃掉了”,然后就杯具了。
解决思路:
把丢失的那个字节找回来。
按照当前手机号码范围130 0000 0000到189 9999 9999经分析,丢失的高位字节可能是0x03或者0x04。
因此加上0x03或者0x04恢复后的值(Long长整型)符合手机号码范围/格式,就可以得到原始值了。
遗留问题: 有可能出现加0x03和0x04都符合手机号码范围/格式的情况,取加0x04的结果(没法子的事情)
好了,上代码(Java)代码:
/**
* 按照当前手机号码范围130 0000 0000到189 9999 9999经分析,丢失的高位字节可能是0x03或者0x04。
* 因此加上0x03或者0x04恢复后的值(Long长整型)符合手机号码范围/格式,就可以得到原始值了。
* 有可能出现加0x03和0x04都符合手机号码范围/格式的情况,取加0x04的结果(没法子的事情)
*
* @param original 溢出前的原始11位手机号码
* @return 转int之后,再重新恢复得到的11位手机号码
*/
public static long recover(long original) {
Pattern p = Pattern.compile("1[3,4,5,8]\\d{9}");
// 更精确的手机号段,但可能不是最新的,这里先不使用。参考: http://wenku.baidu.com/view/9d088df30242a8956bece435.html
// Pattern.compile("(133|153|180|181|189|134|135|136|137|138|139|150|151|152|157|158|159|182|183|187|188|130|131|132|155|156|185|186|145|147)\\d{8}");
int errorInt = (int) original;
System.out.println("溢出前的long值:" + original);
System.out.println("溢出后的int值:" + errorInt);
System.out.println("溢出前的16进制值:" + Long.toHexString(original));
String hexA = "000000000000" + Long.toHexString(errorInt);
hexA = hexA.substring(hexA.length() - 8);
System.out.println("溢出后的16进制值(左补0):" + Long.toHexString(errorInt));
String hex1 = "4" + hexA;
System.out.println("补全后的16进制值1:" + hex1);
BigInteger bi1 = new BigInteger(hex1, 16);
long rt1 = bi1.longValue();
System.out.println("补全后的Long值:" + rt1);
String hex2 = "3" + hexA;
System.out.println("补全后的16进制值2:" + hex2);
BigInteger bi2 = new BigInteger(hex2, 16);
long rt2 = bi2.longValue();
System.out.println("补全后的Long值2:" + rt2);
final boolean m1 = p.matcher(String.valueOf(rt1)).matches();
final boolean m2 = p.matcher(String.valueOf(rt2)).matches();
long rt = 0;
if (m1 && m2) {
// 加3加4都符合手机号码格式
System.err.println("加3加4都符合手机号码格式的溢出后int值:" + errorInt + ". 2个可能的恢复值为: " + rt1 + ", " + rt2);
//有可能出现加0x03和0x04都符合手机号码范围/格式的情况,取加0x04的结果(没法子的事情)
rt = rt1;
} else {
if (m1) {
rt = rt1;
}
if (m2) {
rt = rt2;
}
}
System.out.println("恢复后的符合手机号码格式的值:" + rt + "\n\n");
return rt;
}
沒辦法了,int的範圍是-2147483648~2147483647,而unsigned int也就是無符號整形的就是其兩倍0~4294967295。
你的數據超出了,計算機就自動按maxinteger來算了。舉個簡單點的比喻——U盤塞滿了,再塞不進了,但是你當時沒發現,到後來發現的時候已經沒用了。
除非你有當時存手機號的MYSQL腳本這類外界的記錄或者是LOG,想從本身恢復是不可能了。
有开bin-log吗?
根据MySQL源码里的处理逻辑,如果某个数字大于该字段的最大值(或小于最小值),则解析的时候返回的是最大值(或最小值),所以仅从数字本身是无法恢复的。但是如果你的MySQL服务开启了LOG,那么就有可能恢复。
以下是MySQL的整数解析代码Field_num::get_int(),来自 sql/field.cc +1130
/*
Conver a string to an integer then check bounds.
SYNOPSIS
Field_num::get_int
cs Character set
from String to convert
len Length of the string
rnd OUT longlong value
unsigned_max max unsigned value
signed_min min signed value
signed_max max signed value
DESCRIPTION
The function calls strntoull10rnd() to get an integer value then
check bounds and errors returned. In case of any error a warning
is raised.
RETURN
0 ok
1 error
*/
bool Field_num::get_int(CHARSET_INFO *cs, const char *from, uint len,
longlong *rnd, ulonglong unsigned_max,
longlong signed_min, longlong signed_max)
{
char *end;
int error;
*rnd= (longlong) cs->cset->strntoull10rnd(cs, from, len,
unsigned_flag, &end,
&error);
if (unsigned_flag)
{
if (((ulonglong) *rnd > unsigned_max) && (*rnd= (longlong) unsigned_max) ||
error == MY_ERRNO_ERANGE)
{
goto out_of_range;
}
}
else
{
if (*rnd < signed_min)
{
*rnd= signed_min;
goto out_of_range;
}
else if (*rnd > signed_max)
{
*rnd= signed_max;
goto out_of_range;
}
}
if (table->in_use->count_cuted_fields &&
check_int(cs, from, len, end, error))
return 1;
return 0;
out_of_range:
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
return 1;
}
应该找不回来,就算能找回也不能保证是正确的
如果是默认开的binlog,mysql默认是基于语句的binlog 也就是保存了完整的语句,可以通过binlog恢复
虽然 Po 主很悲剧,但是这是一个好问题,也引出了两个好答案。
mysql int 11手机号_【mysql】我用不小心用 mysql 的int(11) 存了 手机号,数据都有问题,有办法恢复么?...相关推荐
- jaba窗体连接mysql增删改查_知识实现——Java使用jdbc连接MySql数据库,实现增删改查...
Java使用jdbc连接MySql数据库,实现增删改查 首先,导入MySql连接数据库的jar包,我用的是 mysql连接jar包 DB类,用于获得数据库连接 import java.sql.Driv ...
- 获取mysql存储过程返回值_从强网杯随便注浅析mysql存储过程
作者:Smity 合天智汇 去年的强网杯,出了一道mysql堆叠注入叫随便注,这道题被好多比赛玩了一整年,直到现在还是有各种新姿势,但是今天我忽然想到似乎没有对这个题目有一个很认真的分析,因此这里总结 ...
- jdbc如何对mysql数据库进行查询_【转载】通过JDBC对MySQL数据库的增删改查
目录 前言:什么是JDBC 维基百科的简介: Java 数据库连接,(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接 ...
- 远程mysql用ssh连接_使用SSH密钥连接到远程MySQL服务器
远程mysql用ssh连接 In this article, it will be described how to connect to remote MySQL Server on Linux O ...
- mysql socket错误处理_解决Can’t connect to local MySQL server through socket ‘/tmp/mysql.sock’错误...
晚上清理mysql日志,强制重启了下mysql,然后mysql就登陆不上了... 以下方法来自网络,可以使用,已试. 刚安装完mysql,进行运行测试,报Can't connect to local ...
- 腾讯云mysql高可用方案_腾讯云数据库团队:MySQL数据库的高可用性分析
作者介绍:易固武,腾讯高级工程师,参与腾讯账号安全建设,腾讯数据仓库(TDW)优化改造,腾讯云数据库等项目,对大规模分布式存储和计算系统有浓厚的兴趣和经历 MySQL数据库是目前开源应用最大的关系型数 ...
- mysql in 数字类型_关于sql where id in 转换成数据类型 int 时失败
有执行sql条件语句where id in(@参数)的时候,如果处理不当,就会出现问题: 有执行sql条件语句where id in(@参数)的时候,如果处理不当,就会出现问题: 如下面这个存储过程: ...
- go 用 mysql web开发环境_简单讲解Go程序中使用MySQL的方法
go官方仅提供了database package,database package下有两个包sql,sql/driver.这两个包用来定义操作数据库的接口,这就保证了无论使用哪种数据库,他们的操作方式 ...
- Mysql排序添加名词_记面试中问到的MySQL的SQL调优问题
目录 1.场景还原 2.名词解释 3.实践情况 4.个人观点 5.引申问题 1.场景还原 面试官:小伙子,听说你会SQL调优,那我这里有一条SQL,你来帮我调优一下.SQL如下: SELECT * F ...
- mysql datetime 比较大小_【知识点】分布式事务数据库 —-MySQL 数据库开发规范(第一节)...
目录 (1)数据类型: (2)表名称与字段名称设计规则: (3)字符集: (4)字符串函数-3.1-3.5 : (5)字母大小写转换函数 : (6)数学函数 : (7)日期操作函数 : (8)类型转换 ...
最新文章
- Js面向对象和数据类型内存分配(转)
- [转]C#中使用Monitor类、Lock和Mutex类来同步多线程的执行
- Linux学习:目录操作函数
- 【搜索引擎基础知识1】搜索引擎的技术架构
- mongodb身份验证_MongoDB身份验证
- 解决window8 下连接PLSQL 报ora-12154错误
- Linux操作系统命令解释
- 截取一段字符串中,两个指定字符串中间的字符串
- 企业级 布署 vmvare Esxi 5.0.0 从零开始教程 (二) vSphere clinet 安装
- UIFont 字体族
- Multisim14仿真基本模拟电路之 10. 3. 2比例放大电路的仿真实验与分析
- 【iphone4s/ipad2回滚ios6.1.3】file:installer.cpp; line: 71; what:_assert(teams.empty()) 报错解决方法
- mac上如何提取图片上的文字?几款不错的OCR文字识别工具推荐
- 怎样用c语言编出旗子的图案,三色棋解法的C语言实现
- ftp指令及响应代码 (不能说一个不剩,只能说超详细)
- Matlab之classification learner app无法从workspace导入label (response variable)
- 【c语言】数字金字塔
- π120M31 10Mbps双通道数字隔离器兼容代替ADuM1200BR
- 企业微信批量导入用户
- 【RAC】如何修改SCAN IP的IP地址、名称、端口等信息
热门文章
- Shell脚本速查手册
- 辐射强度和辐射亮度_如何在“辐射4”中隐藏“创意俱乐部新闻”垃圾邮件
- xshell 基本操作
- 互联网快讯:微信视频号公布MCN招募计划;极米投影产品双十一持续热销;亚马逊计划再发射4538颗卫星
- CodeForces 596C Wilbur and Points
- 第二章:简单古典密码(及其五元组)
- Linux下测试SSD硬盘读写速率
- kmspico_setup.exe运行提示系统资源不足,无法完成请求的服务
- 如何实现罗克韦尔PLC AB1756的远程监控数据采集?
- 《Blender图解教程:新手入门练习》