1. PostgreSQL CRUD操作基础与实战PostgreSQL作为一款功能强大的开源关系型数据库在企业级应用中扮演着重要角色。我使用PostgreSQL已有7年时间从简单的增删改查(CRUD)到复杂的性能调优都积累了不少实战经验。今天我们就从最基础的CRUD操作开始逐步深入到性能优化层面。1.1 创建示例数据表在开始CRUD操作前我们先建立一个典型的用户信息表作为示例CREATE TABLE users ( id SERIAL PRIMARY KEY, username VARCHAR(50) UNIQUE NOT NULL, email VARCHAR(100) UNIQUE NOT NULL, password_hash VARCHAR(128) NOT NULL, created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, is_active BOOLEAN DEFAULT TRUE ); -- 创建索引 CREATE INDEX idx_users_username ON users(username); CREATE INDEX idx_users_email ON users(email);这个表设计考虑了以下几个关键点使用SERIAL自增主键对username和email字段添加UNIQUE约束记录创建和更新时间为常用查询字段建立索引1.2 插入(Create)操作详解插入数据是最基础的操作但PostgreSQL提供了多种插入方式-- 基础插入 INSERT INTO users (username, email, password_hash) VALUES (john_doe, johnexample.com, hashed_password_123); -- 多行插入性能更优 INSERT INTO users (username, email, password_hash) VALUES (jane_smith, janeexample.com, hashed_password_456), (bob_johnson, bobexample.com, hashed_password_789); -- 带返回值的插入常用于获取生成的ID INSERT INTO users (username, email, password_hash) VALUES (alice_wonder, aliceexample.com, hashed_password_abc) RETURNING id, username; -- 从查询结果插入 INSERT INTO users (username, email, password_hash) SELECT lower(first_name || _ || last_name), lower(first_name || . || last_name || company.com), md5(random()::text) FROM employees WHERE department IT;提示对于大批量插入考虑使用COPY命令它比INSERT快10-100倍COPY users (username, email, password_hash) FROM /path/to/data.csv DELIMITER , CSV;1.3 查询(Read)操作进阶PostgreSQL的查询功能非常强大以下是一些实用技巧-- 基础查询 SELECT * FROM users WHERE is_active TRUE; -- 分页查询注意OFFSET在大数据量时的性能问题 SELECT * FROM users ORDER BY created_at DESC LIMIT 10 OFFSET 20; -- 使用窗口函数进行高级分析 SELECT username, email, created_at, RANK() OVER (ORDER BY created_at DESC) AS join_rank FROM users; -- JSON格式返回适合API开发 SELECT json_build_object( id, id, username, username, email, email ) AS user_json FROM users WHERE id 1; -- 全文搜索需要先创建GIN索引 SELECT * FROM users WHERE to_tsvector(english, username || || email) to_tsquery(john doe);1.4 更新(Update)操作最佳实践更新操作需要考虑并发和数据一致性问题-- 基础更新 UPDATE users SET password_hash new_hashed_password, updated_at CURRENT_TIMESTAMP WHERE id 1; -- 条件更新避免全表扫描 UPDATE users SET is_active FALSE WHERE last_login_at CURRENT_DATE - INTERVAL 1 year RETURNING id, username; -- 基于当前值的更新 UPDATE products SET stock stock - 1 WHERE id 100 AND stock 0; -- 使用CTE进行复杂更新 WITH inactive_users AS ( SELECT id FROM users WHERE last_login_at CURRENT_DATE - INTERVAL 6 months ) UPDATE user_sessions SET is_valid FALSE WHERE user_id IN (SELECT id FROM inactive_users);注意大批量更新时考虑分批处理如每次更新1000条避免长时间锁表。1.5 删除(Delete)操作安全策略删除操作需要格外谨慎-- 基础删除 DELETE FROM users WHERE id 1; -- 软删除模式推荐 UPDATE users SET is_active FALSE, deleted_at CURRENT_TIMESTAMP WHERE id 1; -- 级联删除需外键约束定义时设置ON DELETE CASCADE DELETE FROM departments WHERE id 5; -- 会自动删除关联的用户 -- 使用事务确保数据一致性 BEGIN; DELETE FROM user_sessions WHERE user_id 1; DELETE FROM users WHERE id 1; COMMIT;在实际应用中我强烈建议采用软删除模式即通过标志位标记记录为删除状态而不是物理删除数据。这可以避免数据意外丢失也便于审计。2. PostgreSQL性能优化深度解析2.1 索引策略与查询优化正确的索引设计对性能至关重要。以下是我总结的索引使用经验B-tree索引适合等值查询和范围查询-- 多列复合索引注意列顺序 CREATE INDEX idx_users_name_active ON users (last_name, first_name) WHERE is_active TRUE;部分索引只索引满足条件的行节省空间CREATE INDEX idx_users_active ON users(id) WHERE is_active TRUE;GIN索引适合数组、JSON和全文搜索CREATE INDEX idx_users_tags ON users USING GIN(tags);BRIN索引适合按时间顺序排列的大表CREATE INDEX idx_orders_created ON orders USING BRIN(created_at);实战技巧使用EXPLAIN ANALYZE分析查询计划EXPLAIN ANALYZE SELECT * FROM users WHERE email LIKE %example.com;2.2 事务与并发控制PostgreSQL的MVCC机制使其具有优秀的并发性能但仍需注意-- 明确设置事务隔离级别 BEGIN; SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; -- 业务操作 COMMIT; -- 使用SELECT FOR UPDATE处理竞态条件 BEGIN; SELECT * FROM accounts WHERE id 1 FOR UPDATE; -- 更新账户余额 UPDATE accounts SET balance balance - 100 WHERE id 1; COMMIT;常见锁问题解决方案短事务原则尽量缩短事务持续时间避免热点更新如计数器可以考虑使用乐观锁合理设置锁超时SET lock_timeout 1s2.3 批量操作优化批量数据处理时这些技巧可以显著提升性能批量插入-- 使用unnest进行高效批量插入 INSERT INTO users (username, email) SELECT unnest(ARRAY[user1, user2]), unnest(ARRAY[user1test.com, user2test.com]);批量更新-- 使用临时表批量更新 CREATE TEMP TABLE user_updates (id INT, new_email TEXT); -- 填充临时表数据... UPDATE users SET email u.new_email FROM user_updates u WHERE users.id u.id;批量删除-- 分批次删除大表数据 DO $$ DECLARE batch_size INT : 1000; BEGIN WHILE EXISTS (SELECT 1 FROM logs WHERE created_at 2020-01-01 LIMIT 1) LOOP DELETE FROM logs WHERE created_at 2020-01-01 LIMIT batch_size; COMMIT; END LOOP; END $$;2.4 服务器参数调优关键的postgresql.conf配置参数根据服务器规格调整# 内存相关 shared_buffers 4GB # 通常设为物理内存的25% work_mem 16MB # 每个查询操作的内存复杂查询多可增大 maintenance_work_mem 512MB # 维护操作(如VACUUM)使用的内存 # 并行查询 max_worker_processes 8 # 并行工作进程数 max_parallel_workers_per_gather 4 # 每个查询的并行工作进程 # 预写日志(WAL) wal_level replica # 复制和PITR需要 synchronous_commit on # 数据安全与性能的权衡3. 常见问题与解决方案3.1 慢查询诊断当遇到性能问题时我通常按以下步骤排查启用慢查询日志# postgresql.conf log_min_duration_statement 1000 # 记录执行超过1秒的查询使用pg_stat_statements扩展CREATE EXTENSION pg_stat_statements; SELECT query, calls, total_time, rows FROM pg_stat_statements ORDER BY total_time DESC LIMIT 10;检查锁等待SELECT blocked_locks.pid AS blocked_pid, blocking_locks.pid AS blocking_pid, blocked_activity.query AS blocked_query, blocking_activity.query AS blocking_query FROM pg_catalog.pg_locks blocked_locks JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid blocked_locks.pid JOIN pg_catalog.pg_locks blocking_locks ON blocking_locks.locktype blocked_locks.locktype AND blocking_locks.DATABASE IS NOT DISTINCT FROM blocked_locks.DATABASE AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid AND blocking_locks.pid ! blocked_locks.pid JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid blocking_locks.pid WHERE NOT blocked_locks.GRANTED;3.2 连接池管理高并发场景下合理配置连接池至关重要服务器端连接参数max_connections 200 # 最大连接数 superuser_reserved_connections 3 # 为管理员保留的连接推荐使用PgBouncer配置为事务模式(pool_modetransaction)设置合理的default_pool_size启用连接复用应用层连接管理使用连接池库(如HikariCP)遵循获取连接晚释放连接早原则设置合理的连接超时时间3.3 VACUUM与自动清理PostgreSQL的MVCC机制需要定期维护-- 手动执行VACUUM VACUUM (VERBOSE, ANALYZE) users; -- 针对大表的优化VACUUM VACUUM (VERBOSE, ANALYZE, SKIP_LOCKED) large_table; -- 查看需要VACUUM的表 SELECT relname, n_dead_tup, last_autovacuum FROM pg_stat_user_tables ORDER BY n_dead_tup DESC;关键autovacuum配置autovacuum on # 启用自动清理 autovacuum_max_workers 3 # 自动清理工作进程数 autovacuum_vacuum_cost_limit 2000 # 清理工作强度4. 高级技巧与实战经验4.1 使用CTE优化复杂查询公共表表达式(CTE)可以显著提高复杂查询的可读性和性能-- 递归CTE处理树形结构 WITH RECURSIVE org_tree AS ( SELECT id, name, parent_id, 1 AS level FROM organizations WHERE parent_id IS NULL UNION ALL SELECT o.id, o.name, o.parent_id, ot.level 1 FROM organizations o JOIN org_tree ot ON o.parent_id ot.id ) SELECT * FROM org_tree ORDER BY level, name; -- 使用CTE优化分页查询 WITH user_rank AS ( SELECT id, username, ROW_NUMBER() OVER (ORDER BY created_at DESC) AS rank FROM users WHERE is_active TRUE ) SELECT id, username FROM user_rank WHERE rank BETWEEN 21 AND 30;4.2 JSON/JSONB高级操作PostgreSQL对JSON的支持非常强大-- 创建包含JSONB列的表 CREATE TABLE products ( id SERIAL PRIMARY KEY, name TEXT NOT NULL, attributes JSONB, tags TEXT[] ); -- 插入JSON数据 INSERT INTO products (name, attributes) VALUES (Smartphone, {color: black, storage: 128GB, price: 699.99}); -- JSON查询 SELECT name, attributes-color AS color FROM products WHERE attributes {storage: 128GB}; -- JSON更新 UPDATE products SET attributes jsonb_set(attributes, {price}, 599.99) WHERE id 1; -- 数组操作 UPDATE products SET tags ARRAY[electronics, mobile] WHERE id 1; -- 数组查询 SELECT * FROM products WHERE mobile ANY(tags);4.3 分区表实战对于大型表分区可以显著提高查询性能-- 创建分区表 CREATE TABLE measurement ( id SERIAL, city_id INT NOT NULL, logdate DATE NOT NULL, peaktemp INT, unitsales INT ) PARTITION BY RANGE (logdate); -- 创建分区 CREATE TABLE measurement_y2020 PARTITION OF measurement FOR VALUES FROM (2020-01-01) TO (2021-01-01); CREATE TABLE measurement_y2021 PARTITION OF measurement FOR VALUES FROM (2021-01-01) TO (2022-01-01); -- 自动创建分区需要pg_partman扩展 CREATE EXTENSION pg_partman; SELECT partman.create_parent(public.measurement, logdate, native, monthly);分区策略选择时间范围分区适合时间序列数据列表分区适合离散值如地区哈希分区均匀分布数据4.4 扩展与自定义函数PostgreSQL的扩展生态系统非常丰富-- 安装常用扩展 CREATE EXTENSION pg_trgm; -- 模糊搜索 CREATE EXTENSION hstore; -- 键值存储 CREATE EXTENSION postgis; -- 地理空间数据 CREATE EXTENSION timescaledb; -- 时序数据 -- 创建自定义函数 CREATE OR REPLACE FUNCTION get_user_age(username TEXT) RETURNS INTERVAL AS $$ DECLARE user_age INTERVAL; BEGIN SELECT age(created_at) INTO user_age FROM users WHERE users.username get_user_age.username; RETURN user_age; END; $$ LANGUAGE plpgsql; -- 使用函数 SELECT username, get_user_age(username) AS account_age FROM users;在实际项目中我发现合理使用扩展可以避免重复造轮子显著提高开发效率。
企业数字化 ERP 产品动态
相关推荐
FCC认证全流程指南:从机构筛选到证书获取 1. 项目概述:FCC认证的核心价值与挑战作为电子设备进入北美市场的强制性门槛,FCC认证(Federal Communications Commission Certification)直接关系到产品能否合法销售。2023年全球通过FCC认证的无线设备超过1.2亿台,但… · 2026/11/3 12:47:14
提示缓存命中率高不等于省钱?GPT-6下监控仪表盘的正确打开方式 直接说结论:提示缓存命中率高,是平台设计得好,不是你监控得好。把仪表盘卸了、盯着命中率数字过日子,迟早会踩坑。 先交代背景。GPT-6发布之后,我自己在项目里最直观的感受,就是API调用的延迟和成本都明显… · 2026/11/3 12:47:14
数据库文件类型详解与性能优化实战 1. 数据库文件类型概述 在数据库系统中,文件类型是数据存储的物理表现形式,直接影响着数据库的性能、可靠性和可维护性。作为一名长期从事数据库开发的工程师,我发现很多初学者容易忽视文件类型的选择和管理,而这恰恰是数据库优化… · 2026/11/3 12:47:14
从零开始AI工程:入门路径与核心技术栈全解析 ai-engineering-from-scratch,字面意思就是“从零开始搞AI工程”。作为一个在这个行业摸爬滚打了十几年的工程师,我每隔一两个月就会收到类似的问题:不懂AI、非科班出身、想转进这个领域,到底该怎么走?市面上课程一堆&… · 2026/11/3 13:26:16
十大经典排序算法原理与Python实现 1. 排序算法基础与核心概念 排序算法是计算机科学中最基础也是最重要的算法类别之一。作为数据处理的核心操作,排序直接影响着数据库查询、搜索引擎结果、数据分析等众多应用的性能表现。在实际开发中,我们经常需要对数据进行排序处理,比如电… · 2026/11/3 13:26:16
FAST-LIO源码精读:流形状态、ikd-Tree与工程避坑 简介:围绕FAST-LIO论文与源码整理的个人理解文档,面向已具备ROS、C与SLAM基础、希望吃透LiDAR-IMU紧耦合框架的读者,可用于梳理算法脉络、对照代码理解实现细节。压缩包仅含1个docx,体积约5.09MB,内容按基础准备、FAST… · 2026/11/3 13:26:16
2024年TensorFlow生产实践:安装、部署与PyTorch选型指南 你要是现在打开技术讨论区,大概率会看到一种论调:TensorFlow 已经凉了,学它不如学 PyTorch。我在 2024 年还选择把 TensorFlow 写进生产环境,不是因为我守旧,而是因为我把模型从开发环境推到线上那条路走了太多次&… · 2026/11/3 13:26:16
RS-485电动窗帘中控协议解析:帧结构、CRC校验与联调实现 简介:杜亚管状电机开合帘485协议文档面向智能家居集成商、电动窗帘控制开发者和中控调试人员,聚焦管状电机与外部设备之间的RS-485通讯规则与数据格式。内容围绕波特率9600bps、8位数据位、1位停止位、无校验等参数展开,说明以0x55为起始码的… · 2026/11/3 13:26:16
PyCharm 2025.3.3安装指南与性能优化技巧 1. PyCharm 2025.3.3 安装前的准备工作 作为一名使用PyCharm多年的开发者,我深知一个顺畅的安装过程对编程新手的重要性。PyCharm作为Python开发领域的顶级IDE,其2025.3.3版本带来了诸多性能优化和新功能,但在安装前仍需要做好充分准备。
1… · 2026/11/3 13:25:14
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46
STM32F411RE与MAX14431实现SPI隔离:工业现场抗共模干扰实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59
ESP32+大模型AI硬件开发:从Demo到产品的8个工程问题 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59
基于MAX14431BAEE+与PIC18F85J10的SPI隔离方案设计与实践 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46