PostgreSQL 实战:数组的增删改查与索引优化详解
文章目录一、数组基础1.1 创建含数组的表1.2 插入数组数据1.3 性能对比与选择建议1.4 使用建议二、数组查询SELECT2.1 基本访问2.2 条件查询判断元素是否存在2.3 数组长度与空值判断2.4 展开数组为行UNNEST三、数组更新UPDATE3.1 替换整个数组3.2 追加元素3.3 删除指定元素3.4 更新特定位置元素四、数组索引优化4.1 GIN 索引通用倒排索引4.2 GiST 索引空间/近似匹配4.3 表达式索引针对特定模式4.4 部分索引过滤空数组五、数组常见应用场景场景1商品标签系统场景2用户角色权限场景3多值过滤前端筛选六、避坑指南与限制6.1 数组 vs 关联表何时使用6.2 空数组 vs NULL6.3 下标从1开始6.4 写入性能6.5 JSONB 替代方案七、高级技巧7.1 数组合并去重7.2 数组转字符串用于展示7.3 初始化空数组在 PostgreSQL 中数组Array是一种强大而灵活的内置数据类型允许单个字段存储多个同类型元素。它广泛应用于标签系统、权限列表、多值属性等场景。然而不当使用可能导致性能下降或查询复杂化。一、数组基础1.1 创建含数组的表CREATETABLEproducts(idSERIALPRIMARYKEY,nameTEXT,tagsTEXT[],-- 文本数组scoresINTEGER[],-- 整数数组dimensionsFLOAT[3]-- 固定长度为3的浮点数组可选);注意TEXT[]表示一维文本数组TEXT[][]为二维数组。固定长度如[3]仅为文档提示PostgreSQL 不强制限制实际长度。1.2 插入数组数据-- 方式1使用花括号字面量推荐INSERTINTOproducts(name,tags,scores)VALUES(Laptop,{electronics, portable, high-end},{95, 88, 92});-- 方式2使用 ARRAY 构造器INSERTINTOproducts(name,tags,scores)VALUES(Phone,ARRAY[mobile,android],ARRAY[85,90]);字符串元素若含逗号、空格或特殊字符需用双引号包裹{ wireless, bluetooth, water-resistant }1.3 性能对比与选择建议查询模式推荐操作符是否走 GIN 索引元素存在单值val ANY(col)是包含子集col ARRAY[...]是交集非空col ARRAY[...]是精确相等col ARRAY[...]否需 B-tree 索引长度判断array_length(col,1) N否需表达式索引注意col ARRAY[...]无法使用 GIN 索引若需频繁精确匹配可考虑CREATEINDEXidx_tags_exactONproducts(tags);-- B-tree 索引1.4 使用建议优先使用 GIN 索引加速ANY,,查询。单元素存在性检查用 ANY(col)多元素用。追加用||删除用array_remove()。明确区分空数组{}和 NULL。避免在高写入场景滥用数组评估关联表方案。简单同类型列表用数组复杂结构用 JSONB。下标从1开始切片语法[start:end]。用unnest()展开分析用array_agg()聚合生成。通过合理设计与索引优化PostgreSQL 数组能显著简化数据模型并提升查询效率。但在关系型数据库中规范化仍是默认准则——仅在明确收益时才引入数组。二、数组查询SELECT2.1 基本访问-- 获取整个数组SELECTtagsFROMproducts;-- 访问第1个元素PostgreSQL 数组下标从1开始SELECTtags[1]FROMproducts;-- 访问切片第2到第3个元素SELECTscores[2:3]FROMproducts;2.2 条件查询判断元素是否存在-- 方法1使用 ANY()SELECT*FROMproductsWHEREelectronicsANY(tags);-- 方法2使用 操作符包含SELECT*FROMproductsWHEREtags ARRAY[electronics];-- 方法3使用 操作符重叠至少一个公共元素SELECT*FROMproductsWHEREtagsARRAY[electronics,gaming];推荐单元素存在性检查 → ANY(array_col)多元素子集检查 →array_col ARRAY[...]2.3 数组长度与空值判断-- 数组长度SELECTarray_length(tags,1)AStag_countFROMproducts;-- 判断是否为空数组SELECT*FROMproductsWHEREtags{};-- 判断是否为 NULL注意空数组 ≠ NULLSELECT*FROMproductsWHEREtagsISNULL;2.4 展开数组为行UNNEST-- 将每个标签展开为独立行SELECTid,name,unnest(tags)AStagFROMproducts;-- 保留空数组使用 LEFT JOIN LATERALSELECTp.id,p.name,t.tagFROMproducts pLEFTJOINLATERAL unnest(p.tags)ASt(tag)ONtrue;三、数组更新UPDATE3.1 替换整个数组UPDATEproductsSETtags{updated, tag}WHEREid1;3.2 追加元素-- 追加到末尾使用 || 操作符UPDATEproductsSETtagstags||new_tagWHEREid1;-- 追加数组UPDATEproductsSETtagstags||ARRAY[tag1,tag2]WHEREid1;注意||对数组是连接操作对字符串是拼接上下文自动区分。3.3 删除指定元素PostgreSQL无直接删除函数需通过数组构造实现-- 删除所有值为 old_tag 的元素UPDATEproductsSETtagsarray_remove(tags,old_tag)WHEREid1;-- 删除第一个匹配的元素PostgreSQL 13UPDATEproductsSETtagsarray_replace(tags,old_tag,NULL)WHEREid1;-- 然后移除 NULL需额外步骤不推荐推荐使用array_remove()移除所有匹配项。3.4 更新特定位置元素-- 将第2个标签改为 replacedUPDATEproductsSETtags[2]replacedWHEREid1ANDarray_length(tags,1)2;注意若下标超出范围会插入 NULL 填充需谨慎。四、数组索引优化数组查询若无索引将导致全表扫描。以下是关键优化策略。4.1 GIN 索引通用倒排索引适用于ANY(),,等操作。-- 创建 GIN 索引CREATEINDEXidx_products_tags_ginONproductsUSINGGIN(tags);-- 查询可走索引SELECT*FROMproductsWHEREtags ARRAY[electronics];SELECT*FROMproductsWHEREgamingANY(tags);优势支持任意元素查询、子集、交集。劣势写入开销较大索引体积大。4.2 GiST 索引空间/近似匹配较少用于普通数组多用于几何、全文搜索。4.3 表达式索引针对特定模式若常查询数组长度CREATEINDEXidx_products_tag_countONproducts((array_length(tags,1)));4.4 部分索引过滤空数组CREATEINDEXidx_products_nonempty_tagsONproductsUSINGGIN(tags)WHEREtags!{}ANDtagsISNOTNULL;五、数组常见应用场景场景1商品标签系统-- 快速查找带“sale”和“electronics”标签的商品SELECT*FROMproductsWHEREtags ARRAY[sale,electronics];-- GIN 索引高效支持场景2用户角色权限-- 用户拥有 admin 或 moderator 角色SELECT*FROMusersWHERErolesARRAY[admin,moderator];场景3多值过滤前端筛选-- 用户选择颜色 [red, blue]查找包含任一颜色的商品SELECT*FROMitemsWHEREcolorsARRAY[red,blue];六、避坑指南与限制6.1 数组 vs 关联表何时使用使用数组当数据简单、无独立属性查询模式固定如仅存在性检查写少读多使用关联表当需要独立管理元素如标签有创建时间、状态元素需被多个主记录共享需要外键约束或复杂查询反例若标签需统计使用次数、支持层级应建tags表 product_tags关联表。6.2 空数组 vs NULL{}是空数组有效值NULL表示未知/未设置查询时需明确区分WHEREtagsISNOTNULLANDtags!{}6.3 下标从1开始这是 SQL 标准但易与编程语言0起始混淆tags[1]-- 第一个元素6.4 写入性能GIN 索引在高并发写入场景下可能成为瓶颈。若写多读少评估是否值得用数组。6.5 JSONB 替代方案对于结构更复杂或多类型的多值字段可考虑JSONBALTERTABLEproductsADDCOLUMNmetadata JSONB;-- 支持更灵活查询且有专用 GIN 索引但若仅为同类型列表数组更轻量、高效。七、高级技巧7.1 数组合并去重-- 合并两个数组并去重SELECTARRAY(SELECTDISTINCTUNNEST(tags||ARRAY[new,tag])ORDERBY1);7.2 数组转字符串用于展示SELECTarray_to_string(tags,, )AStag_listFROMproducts;7.3 初始化空数组-- 避免 NULL初始化为空数组INSERTINTOproducts(name,tags)VALUES(New Product,{});

相关新闻

mindie部署qwen3-8b

mindie部署qwen3-8b

参考: https://www.hiascend.com/document/detail/zh/mindie/230/quickstart/mindie_quickstart_0004.html https://www.hiascend.com/document/detail/zh/mindie/230/mindiellm/llmdev/mindie_service0285.html mkdir /root/tmp modelscope download --model Qwen/Qwen3-8B -…

2026/7/8 8:01:22 阅读更多 →
宏智树 AI:解码教育类毕业论文生成逻辑,从 “机械拼凑” 到 “学术表达”

宏智树 AI:解码教育类毕业论文生成逻辑,从 “机械拼凑” 到 “学术表达”

作为深耕教育论文写作科普的博主,每年都要见证无数同学在毕业论文写作中陷入困境:选题跟风导致研究价值不足,文献综述写成流水账缺乏深度,实证分析因操作不规范数据失效,甚至生成初稿后满是机械感的 AI 痕迹。 教育类…

2026/7/8 8:01:23 阅读更多 →
科普|开题报告怎么写不被驳回?宏智树 AI 精准适配全学科逻辑

科普|开题报告怎么写不被驳回?宏智树 AI 精准适配全学科逻辑

大家好,我是专注论文写作科普的博主。开题报告作为学术研究的 “第一份蓝图”,不仅要搭建清晰的研究框架,还得贴合不同学科的学术规范 —— 理工科重实验设计,文科强理论支撑,经管类需实证落地,稍有偏差就会…

2026/7/7 12:05:26 阅读更多 →

最新新闻

如何彻底解决网盘下载限速问题:9大平台直链解析工具完全指南

如何彻底解决网盘下载限速问题:9大平台直链解析工具完全指南

如何彻底解决网盘下载限速问题:9大平台直链解析工具完全指南 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动云盘 …

2026/7/8 7:59:29 阅读更多 →
9大主流网盘直链解析工具:告别限速困扰的高效下载解决方案

9大主流网盘直链解析工具:告别限速困扰的高效下载解决方案

9大主流网盘直链解析工具:告别限速困扰的高效下载解决方案 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动云盘 / …

2026/7/8 7:57:29 阅读更多 →
D3KeyHelper:5分钟打造你的暗黑3专属鼠标宏,彻底告别手酸烦恼

D3KeyHelper:5分钟打造你的暗黑3专属鼠标宏,彻底告别手酸烦恼

D3KeyHelper:5分钟打造你的暗黑3专属鼠标宏,彻底告别手酸烦恼 【免费下载链接】D3keyHelper D3KeyHelper是一个有图形界面,可自定义配置的暗黑3鼠标宏工具。 项目地址: https://gitcode.com/gh_mirrors/d3/D3keyHelper 还在为暗黑破坏…

2026/7/8 7:57:29 阅读更多 →
.NET 项目集成可观测性:从架构思考到落地实践

.NET 项目集成可观测性:从架构思考到落地实践

本文基于一个真实的.NET 9项目集成可观测性栈的经历,分享从"为什么做"到"怎么落地"的完整过程。一、为什么需要集成可观测性? 1.1 触发点:一个"慢"接口 项目中有一个业务接口,涉及多表关联、缓存查…

2026/7/8 7:51:28 阅读更多 →
终极AI换脸指南:如何用roop-unleashed实现电影级面部替换效果

终极AI换脸指南:如何用roop-unleashed实现电影级面部替换效果

终极AI换脸指南:如何用roop-unleashed实现电影级面部替换效果 【免费下载链接】roop-unleashed Evolved Fork of roop with Web Server and lots of additions 项目地址: https://gitcode.com/gh_mirrors/ro/roop-unleashed 在数字创意领域,AI换脸…

2026/7/8 7:49:27 阅读更多 →
腾讯混元Hy3技术拆解:295B MoE架构、定价策略与Benchmark实测对比

腾讯混元Hy3技术拆解:295B MoE架构、定价策略与Benchmark实测对比

核心结论 腾讯于2026年7月6日正式发布混元Hy3,这是一个总参数295B、激活参数21B的MoE架构模型(192专家、每次激活Top-8),支持256K上下文窗口。本文从架构设计、定价策略、Benchmark实测三个维度进行技术拆解,并与GPT-5…

2026/7/8 7:49:27 阅读更多 →

日新闻

3大核心能力重塑《明日方舟》游戏体验:MAA自动化助手的革命性突破

3大核心能力重塑《明日方舟》游戏体验:MAA自动化助手的革命性突破

3大核心能力重塑《明日方舟》游戏体验:MAA自动化助手的革命性突破 【免费下载链接】MaaAssistantArknights 《明日方舟》小助手,全日常一键长草!| A one-click tool for the daily tasks of Arknights, supporting all clients. 项目地址: …

2026/7/8 0:00:48 阅读更多 →
MyBatis 批量操作深度优化——从 N+1 到批处理的全路径

MyBatis 批量操作深度优化——从 N+1 到批处理的全路径

MyBatis 批量操作深度优化——从 N1 到批处理的全路径 一、从"功能正确"到"性能可接受"——MyBatis 批量操作的三段式进化 MyBatis 在日常增删改查场景中几乎是无感的——实体映射直观、SQL 控制灵活。但当数据量从千级上升到十万级、百万级,许…

2026/7/8 0:00:48 阅读更多 →
工业负载控制方案:TPD2015FN与PIC18F45K22应用解析

工业负载控制方案:TPD2015FN与PIC18F45K22应用解析

1. 工业负载控制方案概述在工业自动化、电机驱动和照明控制等高需求场景中,可靠地控制电感和电阻负载是核心挑战之一。TPD2015FN作为东芝的8通道高端智能功率开关IC,配合PIC18F45K22微控制器,能够构建一套稳定、高效的负载控制系统。这套组合…

2026/7/8 0:02:48 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/7 14:24:45 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/7 12:34:47 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/7 15:59:06 阅读更多 →

月新闻