如何在数据库中存储IP地址

  最近改一个比较老的web系统,该系统是通过账号或者ip地址(白名单)验证限制访问权限的。

由于运营的时间比较长了,发现进入网站巨卡...

  原因就是:之前的数据库(sqlserver)存储ip地址是用的字符串类型,而且ip段被分解成了单个的ip存储起来,这样导致了巨大的数据量,比如(192.168.0.1-192.168.0.100),这样分解后存储会产生100条数据,导致在验证用户的时候查询超慢。

 

  解决方法:

  1:将ip地址存储类型改为varbinary(4)类型(未考虑ipv6),因为ip地址正好可以转换成长度为4的十六进制字节数组。

    varbinary对应c#类型为byte[],下面是string byte[]互转的简单方法:

  

        /// <summary>
        /// IP转换字节
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        public static byte[] ParseByte(string ip)
        {
            return System.Net.IPAddress.Parse(ip).GetAddressBytes();
        }    
        /// <summary>
        /// 字节转换IP字符串(未检查是否合法)
        /// </summary>
        /// <param name="b"></param>
        /// <returns></returns>
        public static string ParseIp(byte[] b)
        {
            if (b == null || b.Length < 0)
                return "";
            string ipstr = "";
            foreach (var _b in b)
            {
                ipstr += _b.ToString() + ".";
            }
            return ipstr.TrimEnd('.');
        }

  如此将字符串ip转换后可以直接当参数传递给sql语句进行查询。

 

2:ip段不再分解,而是用起始ip和结束ip两个字段来存储。

 

  

  字节类型可以直接用来比较:

  select * from Ip where IpStart <= @ip and IpEnd >= @ip

  这样问题就都解决了。

posted on 2013-11-13 16:25  阿蛆  阅读(2449)  评论(0编辑  收藏  举报