首页 > 资讯 > > 正文

我懵了,如果要存 IP 地址,用什么数据类型比较好?_今日播报

2023-04-27 09:26:47 来源:飞天小牛肉 分享到:

提到 IP 地址(IPv4),大伙儿脑子里肯定马上能浮现类似于192.168.0.1、127.0.0.1这种常见的 IP 地址,然后结合这个问题 “MySQL 中用什么数据类型存 IP 地址?”,于是乎脱口而出用char字符串类型存。

面试官一脸冷漠,你顿时意识到情况不对,又仔细琢磨了一下。

然后发现,这个 IP 地址的长度是变化的,最短可以是0.0.0.0只需要 7 位,最长可以是255.255.255.255需要 15 位,于是自信地回答使用varchar(15)来存储 IP 地址,并为自己能够想到这一层而暗自窃喜。


(资料图片)

谁知面试官竟轻蔑一笑,问你 “确定吗?”,你觉得这是面试官在考验你,于是坚定的回答 “确定”。

然后就开始了下一题

......

人们经常使用varchar(15)列来存储 IP 地址,但事实上这并不是最优解。

IP 地址的本质是32 位无符号整数,类似于192.168.0.1这种点分十进制的字符串写法只是为了帮助人们理解和记忆,192.168.0.1对应的十进制表示是 无符号整数3232235521。

所以,说用字符串类型存 IP 地址的,其实是潜意识中以为 IP 地址是字符串,存的是点分十进制的字符串,但正确的应该是存 32 位的无符号整数

所谓有符号数其实就是将最高位作为符号位,比如 32 位的有符号 INT,最高位是符号位,剩下 31 位才是真实的数值,所以有符号 INT 的取值区间为:

无符号 INT 的取值区间为:

下表列出了 MySQL 出各个整数类型有符号和无符号的的取值范围,在定义表时,可以在数据类型后面添加关键字UNSIGNED来定义无符号整数,否则默认为有符号整数:

类型

有符号数取值范围

无符号数取值范围

TINYINT(1 字节,8 bit)

-128 〜 127

0 〜 255

SMALLINT(2 字节,16 bit)

-32768 〜 32767

0 〜 65535

MEDIUMINT(3 字节,24 bit)

-8388608 〜 8388607

0 〜 16777215

INT(4 字节,32 bit)

-2147483648 〜 2147483647

0 〜 4294967295

BIGINT(8 字节,64 bit)

-9223372036854775808 〜 9223372036854775807

0 〜 18446744073709551615

结合上表,可以看出,32 位的无符号 INT正好可以容纳 IPv4 地址,下面是INT UNSIGNED和VARCHAR(15)两种数据类型的对比:

存储空间:4 字节的INT类型 15 字节的 VARCHAR(15)更加节省存储空间。另外,VARCHAR 除了会保存需要的字符数,还会另加一个字节来记录长度(如果列声明的长度超过 255,则使用两个字节记录长度),所以VARCHAR(15)其实要占用 16 个字节。检索速度:如果我们要在 IP 地址上建立索引,那么对于字符串索引来说,整数索引的检索速度简直就是降纬打击了,因为字符串类型的比较是需要从第一位字符开始遍历依次进行的,速度较慢。

MySQL 非常贴心地提供了 IPv4 地址点分十进制和无符号整数的相互转换函数,inet_aton和inet_ntoa(底层是二进制移位操作,速度很快):

当然你更应该在业务中去执行这些转换,减轻 MySQL 的压力。

标签:

x 广告
x 广告

Copyright ©  2015-2022 时代仪表网版权所有  备案号:   联系邮箱: 514 676 113@qq.com