大量IP数据比对,用什么方法效率高呢?

时间:2021-10-19 07:58:59
主要是要比对拿到的IP数据之间,比如国家,经纬度之类的信息是否一致,不一样则取多数为正确值。

有的数据是这样记录的:

第一个文件:
startIpNum endIpNum locId
16777216 16777471 17
第二个文件:
locId country region city postalCode latitude longitude metroCode areaCode
1 O1 0 0
2 AP 35 105
这样

有的是
IPNUM           city    latitude longitude
23986432 Milano 45.45 9.16667
16843008 Sexau 48.1 7.9167
26778880 Marseille 43.3 5.4
33523968 Milan 45.45 9.16667
这样

即有按段的也有按单个IP的。
我把它们都导入到了SQL SERVER里,然后
SELECT A.startIpNum,A.endIpNum,B.startIpNum,B.endIpNum,A.country,B.country
FROM A INNER JOIN a ON A.locId=a.locId,IPligence
WHERE B.startIpNum>=A.startIpNum
AND B.endIpNum<=A.endIpNum
AND a.country != B.country;

(因为A数据有两部分,一部分是IP段,另一部分是实际地理数据,所以又用到了a即地理数据)
也就是单就A的段包含B的情况,判断国家不一样的拿出来,然后跑了蛮久没结果。

数据库是我这个学期才学的,有学长建议我直接用语言文本处理的方式比对,灵活、效率可控。但是我觉得这么大量的数据应该可以用数据库吧?
只是简单的这么写查询语句似乎不太实际,是否有优化方法呢?
其实IP都是从小到大的,比对不需要从都到尾都找一遍。但是我不知道怎么写。用程序语言文本处理我也想不太明白怎么写比较可行。

9 个解决方案

#1


--连接不是这样写的.
--试试:
select t1.startIpNum,t1.endIpNum,t2.startIpNum,t2.endIpNum,t1.country,t2.country
from a t1 inner join a t2 on t1.locid=t2.locid
where t1.startipnum>=t1.startipnum
and t1.endipnum<=t2.endipnum
and t1.country<>t2.country

#2


能不能将完整的测试数据给出来?

#3


有这种IP地址? 45.45 9.16667

怎么有的文件字段多,有的字段少?

问题关键在于解决算法问题.

#4


呃不好意思没看懂有什么区别呢,我其实是把拿到的几个数据都导入了一个数据库中,不同的表。

引用 1 楼 qianjin036a 的回复:
SQL code
--连接不是这样写的.
--试试:
select t1.startIpNum,t1.endIpNum,t2.startIpNum,t2.endIpNum,t1.country,t2.country
from a t1 inner join a t2 on t1.locid=t2.locid
where t1.startipnum>=t1.startipnum
and t1.e……

#5


完整的是指的我用的所有文本文件么?那个很大呃
引用 2 楼 fredrickhu 的回复:
能不能将完整的测试数据给出来?

#6


那个是经纬度
IP是以一个长整型存储的,32位的二进制化成十进制的。
比如23986432
算法……就是就是不太懂唉
引用 3 楼 ap0405140 的回复:
有这种IP地址? 45.45 9.16667

怎么有的文件字段多,有的字段少?

问题关键在于解决算法问题.

#7


其实我还没看懂,楼主能简化一下问题吗?

例如输入是什么(尽量简单), 要什么输出.

#8


是这样,简化一下:比如就有三个字段
起始IP          终止IP           国家代码
16777216 16777471         AD

每张表都是这个情况,不过数据量不同。有的有三百多万条,有的就几万条。
但是算IP总量的话(就是把段里包含的单独数出来)都要几亿甚至30多亿个。
现在我要对比它们各个IP的国家代码是不是一致,并把不一致的挑出来。

我例子当中就写了一个段包含情况,都跑了11个小时没完。感觉这个死方法是不行的。但是又不知道怎么弄。
就算用其他语言处理这些数据也得有个算法吧。

不好意思,不知道我说清楚了没有?

引用 7 楼 ap0405140 的回复:
其实我还没看懂,楼主能简化一下问题吗?

例如输入是什么(尽量简单), 要什么输出.

#9



-- 假设总共有3个表:tab1,tab2,tab3

with t as
(select * from tab1 union all
 select * from tab2 union all
 select * from tab3

select * 
from t a
inner join t b 
on (a.起始IP between b.起始IP and b.终止IP
or a.终止IP between b.起始IP and b.终止IP
or b.起始IP between a.起始IP and a.终止IP
or b.终止IP between a.起始IP and a.终止IP)
and a.国家代码<>b.国家代码

#1


--连接不是这样写的.
--试试:
select t1.startIpNum,t1.endIpNum,t2.startIpNum,t2.endIpNum,t1.country,t2.country
from a t1 inner join a t2 on t1.locid=t2.locid
where t1.startipnum>=t1.startipnum
and t1.endipnum<=t2.endipnum
and t1.country<>t2.country

#2


能不能将完整的测试数据给出来?

#3


有这种IP地址? 45.45 9.16667

怎么有的文件字段多,有的字段少?

问题关键在于解决算法问题.

#4


呃不好意思没看懂有什么区别呢,我其实是把拿到的几个数据都导入了一个数据库中,不同的表。

引用 1 楼 qianjin036a 的回复:
SQL code
--连接不是这样写的.
--试试:
select t1.startIpNum,t1.endIpNum,t2.startIpNum,t2.endIpNum,t1.country,t2.country
from a t1 inner join a t2 on t1.locid=t2.locid
where t1.startipnum>=t1.startipnum
and t1.e……

#5


完整的是指的我用的所有文本文件么?那个很大呃
引用 2 楼 fredrickhu 的回复:
能不能将完整的测试数据给出来?

#6


那个是经纬度
IP是以一个长整型存储的,32位的二进制化成十进制的。
比如23986432
算法……就是就是不太懂唉
引用 3 楼 ap0405140 的回复:
有这种IP地址? 45.45 9.16667

怎么有的文件字段多,有的字段少?

问题关键在于解决算法问题.

#7


其实我还没看懂,楼主能简化一下问题吗?

例如输入是什么(尽量简单), 要什么输出.

#8


是这样,简化一下:比如就有三个字段
起始IP          终止IP           国家代码
16777216 16777471         AD

每张表都是这个情况,不过数据量不同。有的有三百多万条,有的就几万条。
但是算IP总量的话(就是把段里包含的单独数出来)都要几亿甚至30多亿个。
现在我要对比它们各个IP的国家代码是不是一致,并把不一致的挑出来。

我例子当中就写了一个段包含情况,都跑了11个小时没完。感觉这个死方法是不行的。但是又不知道怎么弄。
就算用其他语言处理这些数据也得有个算法吧。

不好意思,不知道我说清楚了没有?

引用 7 楼 ap0405140 的回复:
其实我还没看懂,楼主能简化一下问题吗?

例如输入是什么(尽量简单), 要什么输出.

#9



-- 假设总共有3个表:tab1,tab2,tab3

with t as
(select * from tab1 union all
 select * from tab2 union all
 select * from tab3

select * 
from t a
inner join t b 
on (a.起始IP between b.起始IP and b.终止IP
or a.终止IP between b.起始IP and b.终止IP
or b.起始IP between a.起始IP and a.终止IP
or b.终止IP between a.起始IP and a.终止IP)
and a.国家代码<>b.国家代码