PostgreSQL 除了常见的 =>< 之外,还有一大堆特殊操作符。这些操作符在处理 JSON、数组、范围类型、全文搜索时非常强大。我把它们按使用频率分成常用和不常用两类,方便快速查找。

记忆技巧

PostgreSQL 的操作符虽然多,但有规律可循:

符号规律含义
@ 开头包含、搜索相关
> < 组合方向、位置、范围
双符号 >> <<严格关系
&交集、重叠
|并集、连接
-> ->>JSON 提取(单箭头返回 JSON,双箭头返回文本)
~正则匹配
#路径、异或

重点记住这几个

  • @> / <@:包含关系(JSON、数组、范围通用)
  • -> / ->>:JSON 提取
  • ~ / ~*:正则匹配
  • &&:重叠判断(数组、范围、几何通用)
  • @@:全文搜索

常用操作符

JSON/JSONB 操作符

现在后端存储 JSON 数据太常见了,这几个操作符是高频使用的:

操作符含义例子
->按键取 JSONSELECT '{"a":1}'::json->'a'; — 1 (json)
->>按键取文本SELECT '{"a":1}'::json->>'a'; — “1” (text)
@>JSON 包含SELECT '{"a":1,"b":2}'::jsonb @> '{"a":1}'; — true
?键是否存在SELECT '{"a":1}'::jsonb ? 'a'; — true
#>按路径取 JSONSELECT '{"a":{"b":2}}'::json#>'{a,b}'; — 2 (json)
#>>按路径取文本SELECT '{"a":{"b":2}}'::json#>>'{a,b}'; — “2” (text)
?|任一键存在SELECT '{"a":1,"b":2}'::jsonb ?| array['b','c']; — true
?&所有键存在SELECT '{"a":1,"b":2}'::jsonb ?& array['a','b']; — true

使用场景:API 响应存储、配置数据、动态字段等。

字符串模式匹配

搜索和匹配文本是最基础的需求:

操作符含义例子
LIKESQL 模式匹配SELECT 'hello' LIKE 'h%'; — true
ILIKE不区分大小写 LIKESELECT 'Hello' ILIKE 'h%'; — true
~匹配正则(区分大小写)SELECT 'hello' ~ 'h.*o'; — true
~*匹配正则(不区分大小写)SELECT 'Hello' ~* 'HELLO'; — true
!~不匹配正则(区分)SELECT 'hello' !~ 'xyz'; — true
!~*不匹配正则(不区分)SELECT 'Hello' !~* 'xyz'; — true
SIMILAR TOSQL 标准正则SELECT 'hello' SIMILAR TO 'h%o'; — true

使用场景:用户搜索、日志过滤、数据清洗。

数组操作符

当数据结构是数组时,这些操作符能简化很多查询逻辑:

操作符含义例子
@>数组包含SELECT ARRAY[1,2,3] @> ARRAY[2,3]; — true
<@数组被包含SELECT ARRAY[2] <@ ARRAY[1,2,3]; — true
&&数组重叠(有共同元素)SELECT ARRAY[1,2] && ARRAY[2,3]; — true
||数组连接SELECT ARRAY[1,2] || ARRAY[3,4]; — {1,2,3,4}

使用场景:标签系统、权限判断、多选字段。

比较操作符(扩展)

这些是 SQL 标准操作符的扩展,用来简化复杂条件:

操作符含义例子
IN (...)在列表中SELECT 5 IN (1, 3, 5, 7); — true
NOT IN (...)不在列表中SELECT 5 NOT IN (1, 2, 3); — true
BETWEEN ... AND ...在范围内SELECT 5 BETWEEN 1 AND 10; — true
NOT BETWEEN不在范围内SELECT 5 NOT BETWEEN 10 AND 20; — true
ANY/SOME任满足SELECT 5 = ANY(ARRAY[1,3,5]); — true
ALL全满足SELECT 5 > ALL(ARRAY[1,2,3]); — true
EXISTS子查询有结果SELECT EXISTS(SELECT 1 FROM t WHERE id=1);
BETWEEN SYMMETRIC自动调整边界顺序SELECT 5 BETWEEN SYMMETRIC 10 AND 1; — true

使用场景:批量查询、条件过滤、子查询判断。

NULL 处理

NULL 处理不当会导致 Bug,这些操作符能让逻辑更清晰:

操作符含义例子
IS NULL是 NULLSELECT * FROM t WHERE col IS NULL;
IS NOT NULL不是 NULLSELECT * FROM t WHERE col IS NOT NULL;
IS DISTINCT FROM不同(把 NULL 当值)SELECT NULL IS DISTINCT FROM NULL; — false
IS NOT DISTINCT FROM相同(把 NULL 当值)SELECT NULL IS NOT DISTINCT FROM NULL; — true

使用场景:数据校验、兼容性处理、防止三值逻辑陷阱。

范围类型操作符

时间段、价格区间、IP 段等场景会用到范围类型:

操作符含义例子
@>包含元素SELECT int4range(1,10) @> 5; — true
<@被包含SELECT 5 <@ int4range(1,10); — true
&&范围重叠SELECT int4range(1,5) && int4range(3,8); — true
-&#124;-相邻SELECT int4range(1,5) -&#124;- int4range(5,10); — true
<<严格在左SELECT int4range(1,3) << int4range(5,10); — true
>>严格在右SELECT int4range(5,10) >> int4range(1,3); — true
+范围并集SELECT int4range(1,5) + int4range(5,10); — [1,10)

使用场景:预订系统、时间段查询、区间统计。

全文搜索操作符

做站内搜索时,全文搜索比 LIKE 性能好太多:

操作符含义例子
@@匹配查询SELECT to_tsvector('cat') @@ to_tsquery('cat'); — true
||连接SELECT to_tsvector('cat') || to_tsvector('dog');

使用场景:文章搜索、关键词匹配、内容推荐。

不常用操作符

这些操作符在特定场景下很有用,但日常开发中不常碰到。

几何类型操作符

地理位置、图形计算、空间数据库会用到:

操作符含义例子
<->距离SELECT point(0,0) <-> point(3,4); — 5
&&重叠SELECT box '(0,0),(2,2)' && box '(1,1),(3,3)'; — true
<<严格在左SELECT point(1,2) << point(3,4); — true
>>严格在右SELECT point(3,4) >> point(1,2); — true
<^严格在下SELECT point(1,2) <^ point(1,5); — true
>^严格在上SELECT point(1,5) >^ point(1,2); — true
~=相同位置SELECT point(1,2) ~= point(1,2); — true
@面积/长度SELECT @ circle '<(0,0),1>'; — 3.14159…
##交点SELECT box '(0,0),(2,2)' ## box '(1,1),(3,3)';
>>=包含或在上SELECT polygon '((0,0),(2,0),(2,2),(0,2))' >>= point(1,1);
<<&#124;在左或在边界SELECT point(0,0) <<&#124; point(2,2);

使用场景:GIS 应用、地图服务、附近的人。

网络地址操作符

网络安全、IP 管理、防火墙规则会用到:

操作符含义例子
<<包含于网络SELECT '192.168.1.5'::inet << '192.168.1.0/24'::inet; — true
>>包含网络SELECT '192.168.1.0/24'::inet >> '192.168.1.5'::inet; — true
&&重叠SELECT '192.168.1.0/24'::inet && '192.168.1.128/25'::inet; — true
<<=包含于或等于SELECT '192.168.1.0/24'::inet <<= '192.168.1.0/24'::inet; — true
>>=包含或等于同上

使用场景:IP 白名单、子网计算、网络监控。

位运算操作符

底层开发、权限系统、状态机会用到:

操作符含义例子
&SELECT B'1010' & B'1100'; — 1000
|SELECT B'1010' | B'1100'; — 1110
#异或SELECT B'1010' # B'1100'; — 0110
~SELECT ~ B'1010'; — 0101
<<左移SELECT B'1010' << 2; — 101000
>>右移SELECT B'1010' >> 1; — 0101

使用场景:位标记、权限位运算、状态压缩。

其他特殊操作符

一些非常特定场景下的操作符:

操作符含义例子
=UUID 相等SELECT 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid = ...
IS DOCUMENTXML 是完整文档SELECT xmlcol IS DOCUMENT FROM t;
IS NOT DOCUMENTXML 不是完整文档SELECT xmlcol IS NOT DOCUMENT FROM t;

使用场景:UUID 主键、XML 解析。