我用不小心用 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)代碼:
沒辦法了,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
應該找不回來,就算能找回也不能保證是正確的
如果是默認開的binlog,mysql默認是基於語句的binlog 也就是保存了完整的語句,可以通過binlog恢複
雖然 Po 主很悲劇,但是這是一個好問題,也引出了兩個好答案。