我用不小心用 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) 存了 手机号,数据都有问题,有办法恢复么?...相关推荐

  1. jaba窗体连接mysql增删改查_知识实现——Java使用jdbc连接MySql数据库,实现增删改查...

    Java使用jdbc连接MySql数据库,实现增删改查 首先,导入MySql连接数据库的jar包,我用的是 mysql连接jar包 DB类,用于获得数据库连接 import java.sql.Driv ...

  2. 获取mysql存储过程返回值_从强网杯随便注浅析mysql存储过程

    作者:Smity 合天智汇 去年的强网杯,出了一道mysql堆叠注入叫随便注,这道题被好多比赛玩了一整年,直到现在还是有各种新姿势,但是今天我忽然想到似乎没有对这个题目有一个很认真的分析,因此这里总结 ...

  3. jdbc如何对mysql数据库进行查询_【转载】通过JDBC对MySQL数据库的增删改查

    目录 前言:什么是JDBC 维基百科的简介: Java 数据库连接,(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接 ...

  4. 远程mysql用ssh连接_使用SSH密钥连接到远程MySQL服务器

    远程mysql用ssh连接 In this article, it will be described how to connect to remote MySQL Server on Linux O ...

  5. mysql socket错误处理_解决Can’t connect to local MySQL server through socket ‘/tmp/mysql.sock’错误...

    晚上清理mysql日志,强制重启了下mysql,然后mysql就登陆不上了... 以下方法来自网络,可以使用,已试. 刚安装完mysql,进行运行测试,报Can't connect to local ...

  6. 腾讯云mysql高可用方案_腾讯云数据库团队:MySQL数据库的高可用性分析

    作者介绍:易固武,腾讯高级工程师,参与腾讯账号安全建设,腾讯数据仓库(TDW)优化改造,腾讯云数据库等项目,对大规模分布式存储和计算系统有浓厚的兴趣和经历 MySQL数据库是目前开源应用最大的关系型数 ...

  7. mysql in 数字类型_关于sql where id in 转换成数据类型 int 时失败

    有执行sql条件语句where id in(@参数)的时候,如果处理不当,就会出现问题: 有执行sql条件语句where id in(@参数)的时候,如果处理不当,就会出现问题: 如下面这个存储过程: ...

  8. go 用 mysql web开发环境_简单讲解Go程序中使用MySQL的方法

    go官方仅提供了database package,database package下有两个包sql,sql/driver.这两个包用来定义操作数据库的接口,这就保证了无论使用哪种数据库,他们的操作方式 ...

  9. Mysql排序添加名词_记面试中问到的MySQL的SQL调优问题

    目录 1.场景还原 2.名词解释 3.实践情况 4.个人观点 5.引申问题 1.场景还原 面试官:小伙子,听说你会SQL调优,那我这里有一条SQL,你来帮我调优一下.SQL如下: SELECT * F ...

  10. mysql datetime 比较大小_【知识点】分布式事务数据库 —-MySQL 数据库开发规范(第一节)...

    目录 (1)数据类型: (2)表名称与字段名称设计规则: (3)字符集: (4)字符串函数-3.1-3.5 : (5)字母大小写转换函数 : (6)数学函数 : (7)日期操作函数 : (8)类型转换 ...

最新文章

  1. Js面向对象和数据类型内存分配(转)
  2. [转]C#中使用Monitor类、Lock和Mutex类来同步多线程的执行
  3. Linux学习:目录操作函数
  4. 【搜索引擎基础知识1】搜索引擎的技术架构
  5. mongodb身份验证_MongoDB身份验证
  6. 解决window8 下连接PLSQL 报ora-12154错误
  7. Linux操作系统命令解释
  8. 截取一段字符串中,两个指定字符串中间的字符串
  9. 企业级 布署 vmvare Esxi 5.0.0 从零开始教程 (二) vSphere clinet 安装
  10. UIFont 字体族
  11. Multisim14仿真基本模拟电路之 10. 3. 2比例放大电路的仿真实验与分析
  12. 【iphone4s/ipad2回滚ios6.1.3】file:installer.cpp; line: 71; what:_assert(teams.empty()) 报错解决方法
  13. mac上如何提取图片上的文字?几款不错的OCR文字识别工具推荐
  14. 怎样用c语言编出旗子的图案,三色棋解法的C语言实现
  15. ftp指令及响应代码 (不能说一个不剩,只能说超详细)
  16. Matlab之classification learner app无法从workspace导入label (response variable)
  17. 【c语言】数字金字塔
  18. π120M31 10Mbps双通道数字隔离器兼容代替ADuM1200BR
  19. 企业微信批量导入用户
  20. 【RAC】如何修改SCAN IP的IP地址、名称、端口等信息

热门文章

  1. Shell脚本速查手册
  2. 辐射强度和辐射亮度_如何在“辐射4”中隐藏“创意俱乐部新闻”垃圾邮件
  3. xshell 基本操作
  4. 互联网快讯:微信视频号公布MCN招募计划;极米投影产品双十一持续热销;亚马逊计划再发射4538颗卫星
  5. CodeForces 596C Wilbur and Points
  6. 第二章:简单古典密码(及其五元组)
  7. Linux下测试SSD硬盘读写速率
  8. kmspico_setup.exe运行提示系统资源不足,无法完成请求的服务
  9. 如何实现罗克韦尔PLC AB1756的远程监控数据采集?
  10. 《Blender图解教程:新手入门练习》