【Mysql】不要用int类型存储11位手机号

发布时间 2023-10-08 10:06:23作者: 小阳睡不醒啊

一、遇到问题

今天在做添加数据的时候,发现手机号存储错误,报错信息是:

Cause: com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Out of range value for column 'f_phone' at row 1
; Data truncation: Out of range value for column 'f_phone' at row 1; nested exception is com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Out of range value for column 'f_phone' at row 1] with root cause
com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Out of range value for column 'f_phone' at row 1

二、尝试解决

2.1直接复制这个结果去找chatgpt,它告诉我的是:

这个异常的意思是插入或更新语句中有一个字段(在这个错误信息中是f_phone)的值超出了该列在数据库中定义的范围。

通常,字段值超出范围的原因有两种:一是字段值太长,导致无法存储在数据库中;二是字段值太大(或太小),超出了该列的数据类型和定义范围。

因此,您需要检查以下几点:

1.确认 f_phone 列的数据类型和长度是否与实际需要一致。如果该列的长度定义得太小,则可能会导致插入或更新时数据被截断。

2.检查插入或更新语句中 f_phone 列所对应的值是否符合数据库定义的类型和长度范围。

3.如果该字段是从表单传递过来的,请检查提交的表单中该字段的值是否正确,是否符合数据库定义的类型和长度限制。

同时,建议您在代码中添加一些正确性检查的函数,防止出现类似上述错误。例如,对于电话号码,可以编写一个验证函数,确保输入的电话号码符合规定的长度和格式等。

2.2搜索其他网络资料整理得:

1)int是一种32位有符号整数类型,可以存储的范围是-2,147,483,648 ~ 2,147,483,647。因为int类型只有32位,所以能够表示的二进制数最大值为:231-1(在二进制下所有位均为1的情况下,对应的十进制数为231-1,
也就是2147483647)。

2)11位手机号码的十进制表示的最大值是1011-1=99999999999。用二进制表示的话需要超过32位。因此,不能够用int类型来存储11位手机号码。

99999999999的二进制表示需要超过36位。具体计算可以使用对数函数log2来得到。

可以使用以下公式来计算所需的位数:
位数 = log2(数值) + 1。在这里,数值是指要转换为二进制的十进制数。

对于99999999999,计算过程如下:

位数 = log2(99999999999) + 1 ≈ 36.55

因此,99999999999的二进制表示需要超过36位。

2.3综上所述,如果要存储一个11位的十进制数,我们需要使用更大的数据类型。

三、总结反思

我们在考虑mysql存手机号用什么类型的时候,需要考虑以下几个方面:

手机号码都是数字吗?

都是中国的手机号码吗?

会按照手机号等值查询吗?

会按照手机号范围查询吗?

需要手机号列唯一约束吗?

如果是最简单的情况(中国手机号,11位数字),就用数值类型bigint存储即可,建索引。

其他情况下,我们考虑三种类型存储手机号,BigInt,Char,Varchar,下面是它们各自的优劣势:

1.BigInt可以存储非常大的整数,适用于超出其他整数类型范围的手机号码。它提供了准确且精确的存储。可以用来保存那些不包含小数点的数字。
但是对于一些操作(如计算、排序等),BigInt相较于其他类型可能会稍慢。

2.Char类型是固定长度的字符类型,适用于长度固定的手机号码。存储在Char类型中的数据在数据库中占用固定的存储空间,不会浪费空间。

但是如果使用Char类型存储长度可变的手机号码,则会浪费存储空间。此外,对于可变长度的手机号码,插入和更新操作可能会变得复杂,需要手动控制长度。

3.VARCHAR通常用来表示最多为255个字符的变量长度字符串。如果你要储存和处理字母数字类的数据,这种数据类型是最合适的。适用于这类数据的典型例子包括人名,邮政编码,电话号码和不超过255个字符长度的任意字母数字组合。
但是那些要用来计算的数字不要用VARCHAR类型保存,因为可能会导致一些与 计算相关的问题。换句话说,可能影响到计算的准确性和完整性。