MySQL怎样存储IP地址 旧城等待, 2021-06-24 16:00 318阅读 0赞 2018/10/15注: 本文是转载,今天在使用过程中发现有误,在对IP进行转换并insert数据是出现错误,MySQL:Out of range value column 经查发现字段类型定义的有问题,这里用int不够大,需要改为bingint类型 **bigint** 从 -2^63 (-9223372036854775808) 到 2^63-1 (9223372036854775807) 的整型数据(所有数字)。存储大小为 8 个字节。 *P.S.* bigint已经有长度了,在mysql建表中的length,只是用于显示的位数 **int** 从 -2^31 (-2,147,483,648) 到 2^31 – 1 (2,147,483,647) 的整型数据(所有数字)。存储大小为 4 个字节。**int **的 SQL-92 同义字为 **integer**。 以下原文 ----------------------------------------------------------------------------------------------------------------- ### 为什么要问如何存储IP ### 首先就来阐明一下部分人得反问:为什么要问IP得怎样存,直接varchar类型不就得了吗? 其实做任何程序设计都要在功能实现的基础上最大限度的优化性能。而数据库设计是程序设计中不可忽略的一个重要部分,所以巧存IP地址可以一定程度获得很大提升。 ### 利用函数算法处理 ### 在MySQL中没有直接提供IP类型字段,但如果有两个函数可以把IP与最大长度为10位数字类型互转,所以使用int类型存储IP比varchar类型存储IP地址性能要提升很多,减少不少空间。因为varchar是可变长形,需要多余的一个字节存储长度。另外int型在逻辑运算上要比varchar速度快。 ### IP转数字函数inet\_aton() ### 我们转换下几个常用的IP地址 <table> <tbody> <tr> <td><code>01</code></td> <td><code>mysql> </code><code>select</code> <code>inet_aton(</code><code>'255.255.255.255'</code><code>);</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>02</code></td> <td><code>+------------------------------+</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>03</code></td> <td><code>| inet_aton(</code><code>'255.255.255.255'</code><code>) |</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>04</code></td> <td><code>+------------------------------+</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>05</code></td> <td><code>| 4294967295 |</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>06</code></td> <td><code>+------------------------------+</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>07</code></td> <td><code>1 row </code><code>in</code> <code>set</code> <code>(0.00 sec)</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>08</code></td> <td> </td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>09</code></td> <td><code>mysql> </code><code>select</code> <code>inet_aton(</code><code>'192.168.1.1'</code><code>); </code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>10</code></td> <td><code>+--------------------------+</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>11</code></td> <td><code>| inet_aton(</code><code>'192.168.1.1'</code><code>) |</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>12</code></td> <td><code>+--------------------------+</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>13</code></td> <td><code>| 3232235777 |</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>14</code></td> <td><code>+--------------------------+</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>15</code></td> <td><code>1 row </code><code>in</code> <code>set</code> <code>(0.00 sec)</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>16</code></td> <td> </td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>17</code></td> <td><code>mysql> </code><code>select</code> <code>inet_aton(</code><code>'10.10.10.10'</code><code>);</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>18</code></td> <td><code>+--------------------------+</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>19</code></td> <td><code>| inet_aton(</code><code>'10.10.10.10'</code><code>) |</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>20</code></td> <td><code>+--------------------------+</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>21</code></td> <td><code>| 168430090 |</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>22</code></td> <td><code>+--------------------------+</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>23</code></td> <td><code>1 row </code><code>in</code> <code>set</code> <code>(0.00 sec)</code></td> </tr> </tbody> </table> 所以IP的表字段可以设置为INT(10)就好,如果IP获取不到可以直接存0代表获取不到IP的意思 ### 数字转IP函数inet\_ntoa() ### <table> <tbody> <tr> <td><code>01</code></td> <td><code>mysql> </code><code>select</code> <code>inet_ntoa(4294967295);</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>02</code></td> <td><code>+-----------------------+</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>03</code></td> <td><code>| inet_ntoa(4294967295) |</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>04</code></td> <td><code>+-----------------------+</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>05</code></td> <td><code>| 255.255.255.255 |</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>06</code></td> <td><code>+-----------------------+</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>07</code></td> <td><code>1 row </code><code>in</code> <code>set</code> <code>(0.00 sec)</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>08</code></td> <td> </td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>09</code></td> <td><code>mysql> </code><code>select</code> <code>inet_ntoa(3232235777);</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>10</code></td> <td><code>+-----------------------+</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>11</code></td> <td><code>| inet_ntoa(3232235777) |</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>12</code></td> <td><code>+-----------------------+</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>13</code></td> <td><code>| 192.168.1.1 |</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>14</code></td> <td><code>+-----------------------+</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>15</code></td> <td><code>1 row </code><code>in</code> <code>set</code> <code>(0.00 sec)</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>16</code></td> <td> </td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>17</code></td> <td><code>mysql> </code><code>select</code> <code>inet_ntoa(168430090);</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>18</code></td> <td><code>+----------------------+</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>19</code></td> <td><code>| inet_ntoa(168430090) |</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>20</code></td> <td><code>+----------------------+</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>21</code></td> <td><code>| 10.10.10.10 |</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>22</code></td> <td><code>+----------------------+</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>23</code></td> <td><code>1 row </code><code>in</code> <code>set</code> <code>(0.00 sec)</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>24</code></td> <td> </td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>25</code></td> <td><code>mysql> </code><code>select</code> <code>inet_ntoa(0); </code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>26</code></td> <td><code>+--------------+</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>27</code></td> <td><code>| inet_ntoa(0) |</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>28</code></td> <td><code>+--------------+</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>29</code></td> <td><code>| 0.0.0.0 |</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>30</code></td> <td><code>+--------------+</code></td> </tr> </tbody> </table> <table> <tbody> <tr> <td><code>31</code></td> <td><code>1 row </code><code>in</code> <code>set</code> <code>(0.00 sec)</code></td> </tr> </tbody> </table> 注意,0转换为 0.0.0.0 整型字段的比较比字符串效率高很多,这也符合一项优化原则:字段类型定义使用最合适(最小),最简单的数据类型。 inet\_aton()算法,其实借用了国际上对各国IP地址的区分中使用的ip number。 a.b.c.d 的ip number是: a \* 256的3次方 + b \* 256的2次方 + c \* 256的1次方 + d \* 256的0次方。
还没有评论,来说两句吧...