对于一个保存了 ip 起止地址的巨型文本数据库,怎么优化才能既方便查找又节约空间?

2016-01-12 15:16:54 +08:00
 xuboying
数据格式如下
0.0.0.0,1.1.1.0, 信息 0
1.1.1.1,2.2.2.2, 信息 1
2.2.2.3,2.5.5.5, 信息 3
2.5.5.6,...
文本数据量非常大,不方便一次全读入内存,如果 grep 一个 ip 地址也可能落在区间找不到
有什么方法可以既压缩数据,又方便查找么
sqlite 可以么,能否支持查询 ip 区间
(程序语言希望用 python 实现)
4691 次点击
所在节点    程序员
24 条回复
sunchen
2016-01-12 15:23:46 +08:00
ip 地址转化成 32 位数字, 然后经典的 bitmap 查找
popu111
2016-01-12 15:32:35 +08:00
跑一遍存到 MySQL 里面去,然后就好多啦⊙▽⊙
luban
2016-01-12 15:34:41 +08:00
@popu111 存到 mysql 也是不小的
推荐看这个, ip 数据有 txt 和作者自己封装的格式,比较准确,多种语言客户端都有代码
http://git.oschina.net/lionsoul/ip2region
paw
2016-01-12 15:35:36 +08:00
参考 纯真 IP 库 的实现,。,
https://github.com/gwind/ylinux/tree/master/tools/IP/QQWry
一个 py 实现
picasso250
2016-01-12 15:42:15 +08:00
新建一个 table ipt
有 3 列,如下:
ip_start int
ip_end int
info varchar

在 ip_start 和 ip_end 上各建一个索引

将这个 txt 跑一遍,存下来

select * from ipt where ip_start <= ? and ip_end >= ?
0987363
2016-01-12 15:43:59 +08:00
转 32 位然后筛选吧
xuboying
2016-01-12 15:49:44 +08:00
@0987363 @luban @paw @picasso250 @popu111 @sunchen
感谢建议,我大概有思路了,可以造一个小的索引文件,类似 startdict 的格式
数据库我不是很熟悉,可能最终做不出我要的效果
congeec
2016-01-12 16:00:51 +08:00
转 32bit 数字然后存到数据库
实在要文本的话用 btree 建立索引吧
最后别忘了加缓存
congeec
2016-01-12 16:03:06 +08:00
文本只读不写的话可以分段多进程搜索,毕竟没有数据竞争,安全
lululau
2016-01-12 16:10:27 +08:00
我怎么记得一个国内的 IP 库也就几十 MB
xuboying
2016-01-12 16:20:23 +08:00
Livid
2016-01-12 16:26:40 +08:00
用 Redis 的 Sorted Sets :

http://redis.io/commands#sorted_set
TaMud
2016-01-12 16:28:13 +08:00
ip 数据库都能卖钱〜〜〜〜〜
ryd994
2016-01-12 20:14:01 +08:00
用 CIDR ,查询的时候按 prefix 长度顺序查
mlhadoop
2016-01-12 21:21:00 +08:00
字典树可以吗?
wbsdty331
2016-01-12 21:49:09 +08:00
纯真 IP 看 i
skydiver
2016-01-12 21:52:56 +08:00
有多巨型?
raysonx
2016-01-12 22:05:16 +08:00
IP 地址轉為 32 位二進制存儲,建立索引使用二分查找
h4x3rotab
2016-01-12 22:13:32 +08:00
数据和 key 分离是必须的,你肯定要一个索引。

首先 ipv4 地址就是一个 int32 ,所以 key 很好处理。其次要看你的区间会不会重叠,没有交集自然随便搞,是排序之后二分查找,还是丢进什么可以查找的树结构都没问题。但是如果区间会重合,上面大多数人的答案都是错的。

对于重合的区间查找,要用区间树或者线段树才能有效保证查询效率,其他所有的做法都不靠谱, bitmap 只适用于分布均匀的小量数据,只支持一个 key 的各种容器或者数据库就更不用考虑了,最坏情况要遍历大半个索引。
strwei
2016-01-12 22:45:57 +08:00
碎片化

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/250155

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX