IP 存储为整数时的 IP 子串搜索
IP substring search when IP is stored as an integer
假设我有很多 IPv4 存储为整数(具体来说,在关系数据库中),我想在给定 IP 的字符串表示形式的情况下对它们进行子字符串搜索。
例如,用户键入 12.3
并希望他们返回 12.30.45.67
、192.168.12.3
、1.12.34.5
、9.212.34.5
等结果。
如果 IP 是一个字符串,我可以只进行普通的子字符串搜索。它可能效率不高,但至少易于实施和理解。但是因为目前我不能轻易地将它更改为字符串,所以我看不到任何有效的方法(就 CPU 周期、内存以及我的 development/implementation 时间而言) ,但也许我只是遗漏了一些东西。
你没有遗漏任何东西。
例如尝试将 12.3
变成一系列范围。无论 12
在哪个八位组中,都会有 3 个选项(12
、112
、212
)。无论 3
在哪个八位字节中,都会有 2 个选项(3
和 30-39
)。这是前面八位字节的每个组合的 6 个范围。
但是前面的八位字节呢?我们有 1 + 256 + 256*256
取决于您开始之前是 0、1 还是 2 个八位字节。
这是您必须搜索的 3 * 2 * (1 + 256 + 256*256) = 394758
个数字范围的总和。执行这么多索引搜索不太可能比扫描所有内容更快。
顺便说一下,最坏的情况是 1.2
。在那种情况下,您需要进行 17 * 3 * (1 + 256 + 256*256) = 3355443
范围查找!
如果他们非常想要这个,您需要对字符串进行全文搜索。
在那种情况下,除了一些预处理、索引、缓存之外的任何事情对我来说都太低效了(而且很难实现)。
这里有一些想法:
- 考虑创建自定义索引(如果可能),以便您进行字符串搜索。
- 向 table 添加一个自动字段,将 ip 表示为字符串,使您能够进行字符串搜索。当然要加上相应的索引。
- 如果您不能或不想更改 table 的模式,请使用您的 ip table 中的行的字符串表示和映射的相应外键创建另一个模式到 ip table.
的主键
- 如果您不想或根本无法编辑该数据库,请创建一个外部 key/value store/database,其中键是 ips 的字符串表示,值保存相应的记录(现在)外部数据库中的 ip table 或指向它。
无论如何,考虑到您的要求,我认为使用其当前形式(整数)搜索 table 是不可行的(性能方面和实现复杂性方面)。
假设我有很多 IPv4 存储为整数(具体来说,在关系数据库中),我想在给定 IP 的字符串表示形式的情况下对它们进行子字符串搜索。
例如,用户键入 12.3
并希望他们返回 12.30.45.67
、192.168.12.3
、1.12.34.5
、9.212.34.5
等结果。
如果 IP 是一个字符串,我可以只进行普通的子字符串搜索。它可能效率不高,但至少易于实施和理解。但是因为目前我不能轻易地将它更改为字符串,所以我看不到任何有效的方法(就 CPU 周期、内存以及我的 development/implementation 时间而言) ,但也许我只是遗漏了一些东西。
你没有遗漏任何东西。
例如尝试将 12.3
变成一系列范围。无论 12
在哪个八位组中,都会有 3 个选项(12
、112
、212
)。无论 3
在哪个八位字节中,都会有 2 个选项(3
和 30-39
)。这是前面八位字节的每个组合的 6 个范围。
但是前面的八位字节呢?我们有 1 + 256 + 256*256
取决于您开始之前是 0、1 还是 2 个八位字节。
这是您必须搜索的 3 * 2 * (1 + 256 + 256*256) = 394758
个数字范围的总和。执行这么多索引搜索不太可能比扫描所有内容更快。
顺便说一下,最坏的情况是 1.2
。在那种情况下,您需要进行 17 * 3 * (1 + 256 + 256*256) = 3355443
范围查找!
如果他们非常想要这个,您需要对字符串进行全文搜索。
在那种情况下,除了一些预处理、索引、缓存之外的任何事情对我来说都太低效了(而且很难实现)。
这里有一些想法:
- 考虑创建自定义索引(如果可能),以便您进行字符串搜索。
- 向 table 添加一个自动字段,将 ip 表示为字符串,使您能够进行字符串搜索。当然要加上相应的索引。
- 如果您不能或不想更改 table 的模式,请使用您的 ip table 中的行的字符串表示和映射的相应外键创建另一个模式到 ip table. 的主键
- 如果您不想或根本无法编辑该数据库,请创建一个外部 key/value store/database,其中键是 ips 的字符串表示,值保存相应的记录(现在)外部数据库中的 ip table 或指向它。
无论如何,考虑到您的要求,我认为使用其当前形式(整数)搜索 table 是不可行的(性能方面和实现复杂性方面)。