Postgres inet 数组包含单个 ip

Rad*_*ive 5 postgresql address

要求:用户可以将单个 ips 或 ip 地址范围添加到数据库表(例如具有 ipAddressesinet[]类型的权限表)。我需要查询单个 ip 是否包含在 ipAddresses 字段数组中,该数组可以是 ip 地址数组或 ip 地址范围数组,也可以是两者。我试图添加这样的查询:

WHERE "ipAddresses" @> '192.168.1.5'::inet
Run Code Online (Sandbox Code Playgroud)

也喜欢这个

WHERE "ipAddresses" >> '192.168.1.5'::inet
Run Code Online (Sandbox Code Playgroud)

但没有运气。提前致谢。

id          uuid      NOT NULL  gen_random_uuid()
permissions uuid[]      
ipAddresses inet[]      
createdAt   timestamp with time zone        now()
updatedAt   timestamp with time zone        now()
Run Code Online (Sandbox Code Playgroud)

来源:pg 数组函数pg 网络地址函数

dez*_*zso 7

虽然McNets 的解决方案也适用,但它可能最容易ANY与运算符一起使用,在这种情况下是等式:

SELECT '10.10.10.10' = ANY ('{10.10.10.10, 10.10.10.20}'::inet[]);
Run Code Online (Sandbox Code Playgroud)

背景是inet数组在这方面与任何其他数组类型没有区别 -ANY将与在基本类型上定义的任何布尔返回运算符一起使用。

以上适用于单个 IP 地址的相等性。如果您需要将单个 IP 与范围匹配,则需要<<=运算符而不是=

SELECT '10.10.10.10'::inet <<= ANY ('{10.10.10.10, 10.10.10.20}'::inet[]);

 ?column? 
??????????
 t

SELECT '10.10.10.10'::inet <<= ANY ('{10.10.10.0/28, 10.10.10.20}'::inet[]);

 ?column? 
??????????
 t
Run Code Online (Sandbox Code Playgroud)

在你的情况下,解决方案看起来像

WHERE '192.168.1.5' <<= ANY ("ipAddresses")
Run Code Online (Sandbox Code Playgroud)

由于缺乏真正有效的索引,它的性能可能很差。要解决此问题,请参阅 McNets 的回答中的建议。