Postgresql常规SQL语句操作

news2025/6/6 19:48:48

        

目录

一、数据库与对象管理

二、数据操作 (CRUD)

三、查询优化与执行计划分析

四、事务控制

五、数据类型与高级特性应用

六、系统查询与维护

研发中的重要注意事项


        在 PostgreSQL 研发中,以下这些 SQL 应用是极其常见且核心的操作,涵盖了数据库设计、数据操作、查询优化和系统维护的关键方面:

一、数据库与对象管理

  1. 创建/修改表:

    CREATE TABLE employees (
        id SERIAL PRIMARY KEY,  -- 自增主键
        name VARCHAR(100) NOT NULL,
        email VARCHAR(255) UNIQUE,
        department_id INTEGER REFERENCES departments(id), -- 外键
        salary NUMERIC(10, 2),
        hire_date DATE DEFAULT CURRENT_DATE,
        is_active BOOLEAN DEFAULT true,
        skills TEXT[] -- 数组类型
        profile JSONB -- JSONB 类型存储灵活数据
    );
    
    -- 添加索引
    CREATE INDEX idx_employees_department ON employees(department_id);
    CREATE INDEX idx_employees_name ON employees(name);
    CREATE INDEX idx_employees_profile_email ON employees USING gin ((profile->>'email')); -- JSONB 字段索引
    
    -- 修改表 (添加列、修改列类型、添加约束等)
    ALTER TABLE employees ADD COLUMN phone VARCHAR(20);
    ALTER TABLE employees ALTER COLUMN salary TYPE DECIMAL(12, 2);
    ALTER TABLE employees ADD CONSTRAINT salary_check CHECK (salary > 0);
    
  2. 创建视图:

    CREATE VIEW active_employees AS
    SELECT id, name, email, department_id
    FROM employees
    WHERE is_active = true;
    -- 物化视图 (定期刷新)
    CREATE MATERIALIZED VIEW department_salary_summary AS
    SELECT department_id, AVG(salary) AS avg_salary, SUM(salary) AS total_salary
    FROM employees
    GROUP BY department_id
    WITH DATA;
    REFRESH MATERIALIZED VIEW department_salary_summary; -- 手动刷新
    
  3. 创建函数/存储过程:

    CREATE OR REPLACE FUNCTION get_employee_count(dept_id INTEGER)
    RETURNS INTEGER AS $$
    DECLARE
        emp_count INTEGER;
    BEGIN
        SELECT COUNT(*) INTO emp_count
        FROM employees
        WHERE department_id = dept_id AND is_active = true;
        RETURN emp_count;
    END;
    $$ LANGUAGE plpgsql;
    
    -- 调用函数
    SELECT get_employee_count(5);
    

二、数据操作 (CRUD)

  1. 插入数据:

    INSERT INTO employees (name, email, department_id, salary)
    VALUES ('Alice Smith', 'alice@example.com', 3, 75000.00),
           ('Bob Johnson', 'bob@example.com', 3, 82000.00);
    
    -- 插入来自查询的结果
    INSERT INTO archived_employees (id, name, email, leave_date)
    SELECT id, name, email, CURRENT_DATE
    FROM employees
    WHERE is_active = false;
    
  2. 查询数据:

    • 基础查询:
      SELECT id, name, salary FROM employees WHERE department_id = 3 AND salary > 80000;
      
    • 连接:
      SELECT e.name, d.name AS department_name, e.salary
      FROM employees e
      INNER JOIN departments d ON e.department_id = d.id;
      -- LEFT JOIN, RIGHT JOIN, FULL JOIN 也很常用
      
    • 聚合与分组:
      SELECT department_id, COUNT(*) AS num_employees, AVG(salary) AS avg_salary
      FROM employees
      WHERE is_active = true
      GROUP BY department_id
      HAVING AVG(salary) > 60000;
      
    • 子查询:
      SELECT name, salary
      FROM employees
      WHERE salary > (SELECT AVG(salary) FROM employees);
      
    • 窗口函数:
      SELECT name, department_id, salary,
             RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS dept_salary_rank,
             salary - LAG(salary) OVER (PARTITION BY department_id ORDER BY hire_date) AS salary_diff
      FROM employees;
      
    • JSONB 查询:
      SELECT name, profile->>'address' AS address -- 提取文本
      FROM employees
      WHERE profile @> '{"skills": ["PostgreSQL"]}'; -- 包含特定键值对
      
  3. 更新数据:

    UPDATE employees
    SET salary = salary * 1.05 -- 涨薪5%
    WHERE department_id = 3 AND performance_rating >= 4;
    
    -- 基于子查询更新
    UPDATE employees e
    SET manager_id = (SELECT manager_id FROM departments d WHERE d.id = e.department_id)
    WHERE e.manager_id IS NULL;
    
  4. 删除数据:

    DELETE FROM employees
    WHERE is_active = false AND hire_date < '2020-01-01';
    
    -- 使用事务确保操作原子性
    BEGIN;
    -- 先存档再删除
    INSERT INTO deleted_employees_log SELECT *, CURRENT_TIMESTAMP FROM employees WHERE id = 123;
    DELETE FROM employees WHERE id = 123;
    COMMIT;
    

三、查询优化与执行计划分析

  1. EXPLAIN / EXPLAIN ANALYZE

    EXPLAIN ANALYZE
    SELECT * FROM orders
    WHERE customer_id = 456 AND order_date BETWEEN '2023-01-01' AND '2023-12-31'
    ORDER BY total_amount DESC
    LIMIT 10;
    
    • 解读输出,查看是否使用了正确的索引、扫描类型(Seq Scan, Index Scan, Bitmap Heap Scan)、连接策略、排序方式、预估/实际行数、执行时间等。
    • 这是优化慢查询的最重要工具
  2. 强制使用索引 (通常不推荐,优化器通常更聪明):

    SET enable_seqscan = off; -- 临时关闭顺序扫描 (测试用,勿在生产库长期开启)
    -- ... 运行查询 ...
    SET enable_seqscan = on;
    
  3. 创建/优化索引:

    • 组合索引: CREATE INDEX idx_orders_customer_date ON orders(customer_id, order_date);
    • 条件索引: CREATE INDEX idx_active_high_salary ON employees(salary) WHERE is_active = true AND salary > 100000;
    • 表达式索引: CREATE INDEX idx_employee_lower_name ON employees(LOWER(name));
    • 覆盖索引: CREATE INDEX idx_order_summary ON orders(customer_id, order_date) INCLUDE (total_amount); (PG 11+)
    • GIN/GiST 索引: 用于全文搜索(tsvector)、数组、JSONB、几何类型等。

四、事务控制

  1. 显式事务:

    BEGIN;
    -- 一系列操作 (INSERT, UPDATE, DELETE, SELECT ... FOR UPDATE)
    UPDATE accounts SET balance = balance - 100.00 WHERE id = 1;
    UPDATE accounts SET balance = balance + 100.00 WHERE id = 2;
    -- 根据业务逻辑决定提交或回滚
    COMMIT; -- 或 ROLLBACK;
    
  2. 事务隔离级别:

    SET TRANSACTION ISOLATION LEVEL READ COMMITTED; -- 默认级别
    -- 或 REPEATABLE READ, SERIALIZABLE
    BEGIN;
    ... -- 在指定隔离级别下执行事务
    COMMIT;
    
  3. SELECT ... FOR UPDATE / SELECT ... FOR SHARE

    BEGIN;
    SELECT * FROM inventory WHERE product_id = 789 FOR UPDATE; -- 锁定该行,防止其他事务并发修改
    -- 检查库存、扣减库存...
    UPDATE inventory SET stock = stock - 1 WHERE product_id = 789;
    COMMIT;
    

五、数据类型与高级特性应用

  1. JSONB 操作:

    -- 插入
    INSERT INTO products (id, name, attributes)
    VALUES (1, 'T-Shirt', '{"color": "red", "size": ["S", "M", "L"], "material": "cotton"}');
    
    -- 查询
    SELECT name, attributes->'size' AS available_sizes
    FROM products
    WHERE attributes @> '{"color": "red"}'; -- 包含 color=red
    
    -- 更新
    UPDATE products
    SET attributes = jsonb_set(attributes, '{price}', '19.99') -- 添加/更新 price 键
    WHERE id = 1;
    
    UPDATE products
    SET attributes = attributes || '{"discount": 0.1}' -- 合并添加 discount 键
    WHERE id = 1;
    
  2. 数组操作:

    SELECT name FROM employees WHERE 'PostgreSQL' = ANY(skills); -- 包含特定技能
    UPDATE employees SET skills = array_append(skills, 'Docker') WHERE id = 456; -- 添加技能
    SELECT unnest(skills) AS skill, COUNT(*) FROM employees GROUP BY skill; -- 展开数组统计
    
  3. 全文搜索:

    -- 创建 tsvector 列和索引
    ALTER TABLE articles ADD COLUMN search_vector tsvector;
    UPDATE articles SET search_vector = to_tsvector('english', title || ' ' || body);
    CREATE INDEX idx_articles_search ON articles USING gin(search_vector);
    
    -- 搜索
    SELECT title, snippet(search_vector, query) AS highlight
    FROM articles, plainto_tsquery('english', 'database performance') query
    WHERE search_vector @@ query
    ORDER BY ts_rank(search_vector, query) DESC;
    

六、系统查询与维护

  1. 查看表/索引信息:

    \d employees -- psql 元命令
    SELECT * FROM pg_tables WHERE schemaname = 'public'; -- 系统表
    SELECT * FROM pg_indexes WHERE tablename = 'employees'; -- 索引信息
    SELECT pg_size_pretty(pg_total_relation_size('employees')); -- 表大小 (含索引)
    
  2. 查看连接/锁:

    SELECT * FROM pg_stat_activity; -- 当前活动连接/查询
    SELECT * FROM pg_locks; -- 当前锁信息
    
  3. 权限管理:

    GRANT SELECT, INSERT, UPDATE ON employees TO developer_role;
    REVOKE DELETE ON employees FROM public;
    

研发中的重要注意事项

  1. 避免 N+1 查询: 在 ORM (如 Hibernate, Django ORM, ActiveRecord) 中尤其要注意。使用 JOIN 或批量查询 (WHERE ... IN (...)) 代替在循环中执行单个查询。
  2. 参数化查询: 永远使用参数化查询或预处理语句来防止 SQL 注入攻击。不要拼接 SQL 字符串。
  3. 理解索引: 不是所有字段都适合加索引。索引有写入开销。理解查询模式,创建合适的索引(类型、字段顺序、条件)。定期分析索引使用情况 (pg_stat_all_indexes)。
  4. 事务边界: 明确事务的开始和结束。保持事务尽可能短小,减少锁竞争。正确处理并发冲突。
  5. 批量操作: 对于大批量插入/更新,使用 COPY 命令、批量 INSERT ... VALUES (...), (...), ... 或 INSERT ... SELECT ...,比循环单条插入高效得多。
  6. 监控与分析: 使用 EXPLAIN ANALYZE 分析慢查询。监控数据库性能指标(连接数、锁、CPU、IO)。使用 pg_stat_statements 扩展找出高频/高消耗 SQL。
  7. 连接池: 在应用层(如 HikariCP, pgBouncer)使用连接池管理数据库连接,避免频繁建立/断开连接的开销。
  8. 模式迁移: 使用成熟的迁移工具(如 Flyway, Liquibase, Alembic, Django Migrations)管理数据库模式变更,确保变更可追溯、可重复、可在不同环境一致执行。

        掌握这些常规 SQL 应用并结合 PostgreSQL 的强大特性(如 JSONB、数组、GIN/GiST 索引、窗口函数、CTE、强大的 PL/pgSQL),能够高效、安全地进行应用研发,构建高性能、可扩展的后端系统。


     这篇博客到这里就接近尾声了,希望我的分享能给您带来一些启发和帮助,别忘了点赞、收藏。您的每一次互动、鼓励是我持续创作的动力!期待与您再次相遇,共同探索更广阔的世界!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2399312.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

英国2025年战略防御评估报告:网络与电磁域成现代战争核心

英国 2025 年战略防御评估 (SDR) 详细制定了一项计划&#xff0c;通过加强使用网络、人工智能和数字战争来整合其军事防御和进攻能力。 与美国一样&#xff0c;英国也被认为&#xff08;尽管未被公开证实&#xff09;会开展进攻性网络行动&#xff0c;甚至针对盟友。斯诺登泄露…

基于QPSK调制解调+Polar编译码(SCL译码)的matlab性能仿真,并对比BPSK

目录 1.引言 2.算法仿真效果演示 3.数据集格式或算法参数简介 4.MATLAB核心程序 5.算法涉及理论知识概要 6.参考文献 7.完整算法代码文件获得 1.引言 Polar码由土耳其教授Erdal Arikan于2008年提出&#xff0c;是第一种被严格证明可以达到香农极限的构造性编码方法。其核…

Glide NoResultEncoderAvailableException异常解决

首先将解决方法提出来&#xff1a;缓存策略DiskCacheStrategy.DATA。 使用Glide加载图片&#xff0c;版本是4.15.0&#xff0c;有天发现无法显示gif图片&#xff0c;原始代码如下&#xff1a; Glide.with(context).load(本地资源路径).diskCacheStrategy(DiskCacheStrategy.A…

无人机巡检智能边缘计算终端技术方案‌‌——基于EFISH-SCB-RK3588工控机/SAIL-RK3588核心板的国产化替代方案‌

一、方案核心价值‌ ‌实时AI处理‌&#xff1a;6TOPS NPU实现无人机影像的实时缺陷检测&#xff08;延迟&#xff1c;50ms&#xff09;‌全国产化‌&#xff1a;芯片、操作系统、算法工具链100%自主可控‌极端环境适配‌&#xff1a;-40℃~85℃稳定运行&#xff0c;IP65防护等…

相机--相机成像原理和基础概念

教程 成像原理 基础概念 焦距&#xff08;物理焦距&#xff09; 镜头的光学中心到感光元件之间的距离&#xff0c;用f表示&#xff0c;单位&#xff1a;mm&#xff1b;。 像素焦距 相机内参矩阵中的 fx​ 和 fy​ 是将物理焦距转换到像素坐标系的产物&#xff0c;可能不同。…

2025-0604学习记录17——文献阅读与分享(2)

最近不是失踪了&#xff01;也不是弃坑了...这不是马上要毕业了嘛&#xff01;所以最近在忙毕业论文答辩、毕业去向填报、户档去向填报等等&#xff0c;事情太多了&#xff0c;没顾得上博客。现在这些事基本上都解决完了&#xff0c;也有时间静下心来写写文字了~ 想要写的内容…

图解浏览器多进程渲染:从DNS到GPU合成的完整旅程

目录 浅谈浏览器进程 浏览器进程架构的演化 进程和线程关系图示 进程&#xff08;Process&#xff09; 线程&#xff08;Thread&#xff09; 协程&#xff08;Coroutine&#xff09; 进程&线程&协程核心对比 单进程和多进程浏览器 单进程浏览器​编辑 单进程…

【计算机网络】第3章:传输层—TCP 拥塞控制

目录 一、PPT 二、总结 TCP 拥塞控制详解 ⭐ 核心机制与算法 1. 慢启动&#xff08;Slow Start&#xff09; 2. 拥塞避免&#xff08;Congestion Avoidance&#xff09; 3. 快速重传&#xff08;Fast Retransmit&#xff09; 4. 快速恢复&#xff08;Fast Recovery&…

idea不识别lombok---实体类报没有getter方法

介绍 本篇文章&#xff0c;主要讲idea引入lombok后&#xff0c;在实体类中加注解Data&#xff0c;在项目启动的时候&#xff0c;编译不通过&#xff0c;报错xxx.java没有getXxxx&#xff08;&#xff09;方法。 原因有以下几种 1. idea没有开启lombok插件 2. 使用idea-2023…

SAP学习笔记 - 开发15 - 前端Fiori开发 Boostrap,Controls,MVC(Model,View,Controller),Modules

上一章讲了Fiori开发的准备&#xff0c;以及宇宙至简之HelloWorld。 SAP学习笔记 - 开发14 - 前端Fiori开发 HelloWorld-CSDN博客 本章继续学习 Fiori 开发的知识&#xff1a; Bootstrap&#xff0c;Controls&#xff0c;MVC(Model&#xff0c;View&#xff0c;Controller&a…

基于SDN环境下的DDoS异常攻击的检测与缓解

参考以下两篇博客&#xff0c;最后成功&#xff1a; 基于SDN的DDoS攻击检测和防御方法_基于sdn的ddos攻击检测与防御-CSDN博客 利用mininet模拟SDN架构并进行DDoS攻击与防御模拟&#xff08;Ryumininetsflowpostman&#xff09;_mininet模拟dos攻击-CSDN博客 需求 H2 模拟f…

如何轻松地将文件从 PC 传输到 iPhone?

传统上&#xff0c;您可以使用 iTunes 将文件从 PC 传输到 iPhone&#xff0c;但现在&#xff0c;使用 iTunes 已不再是唯一的选择。现在有多种不同且有效的方法可以帮助您传输文件。在今天的指南中&#xff0c;您可以找到 8 种使用或不使用 iTunes 传输文件的方法&#xff0c;…

Bresenham算法

一 Bresenham 绘直线 使用 Bresenham 算法&#xff0c;可以在显示器上绘制一直线段。该算法主要思想如下&#xff1a; 1 给出直线段上两个端点 &#xff0c;根据端点求出直线在X,Y方向上变化速率 &#xff1b; 2 当 时&#xff0c;X 方向上变化速率快于 Y 方向上变化速率&am…

【从GEO数据库批量下载数据】

从GEO数据库批量下载数据 1&#xff1a;进入GEO DataSets拿到所需要下载的数据的srr.list&#xff0c;上传到linux&#xff0c; 就可以使用prefetch这个函数来下载 2&#xff1a;操作步骤如下&#xff1a; conda 安装sra-tools conda create -n sra-env -c bioconda -c co…

day 44

使用DenseNet预训练模型对cifar10数据集进行训练 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms, models from torch.utils.data import DataLoader import matplotlib.pyplot as plt import os# 设置中文字体…

NER实践总结,记录一下自己实践遇到的各种问题。

更。 没卡&#xff0c;跑个模型休息好几天&#xff0c;又闲又急。 一开始直接套用了别人的代码进行实体识别&#xff0c;结果很差&#xff0c;原因是他的词表没有我需要的东西&#xff0c;我是用的医学文本。代码直接在github找了改的&#xff0c;用的是BERT的Chinese版本。 然…

微信小程序实现运动能耗计算

微信小程序实现运动能耗计算 近我做了一个挺有意思的微信小程序&#xff0c;能够实现运动能耗的计算。只需要输入性别、年龄、体重、运动时长和运动类型这些信息&#xff0c;就能算出对应的消耗热量。 具体来说&#xff0c;在小程序里&#xff0c;性别不同&#xff0c;身体基…

iTunes 无法备份 iPhone:10 种解决方法

Apple 设备是移动设备市场上最先进的产品之一&#xff0c;但有些人遇到过 iTunes 因出现错误而无法备份 iPhone 的情况。iTunes 拒绝备份 iPhone 时&#xff0c;可能会令人非常沮丧。不过&#xff0c;幸运的是&#xff0c;我们有 10 种有效的方法可以解决这个问题。您可以按照以…

LangChain4J 使用实践

这里写目录标题 大模型应用场景&#xff1a;创建一个测试示例AIService聊天记忆实现简单实现聊天记录记忆MessageWindowChatMemory实现聊天记忆 隔离聊天记忆聊天记忆持久化 添加AI提示词 大模型应用场景&#xff1a; 创建一个测试示例 导入依赖 <dependency><groupI…

【C++】—— 从零开始封装 Map 与 Set:实现与优化

人生的态度是&#xff0c;抱最大的希望&#xff0c;尽最大的努力&#xff0c;做最坏的打算。 —— 柏拉图 《理想国》 目录 1、理论基石——深度剖析 BSTree、AVLTree 与 RBTree 的概念区别 2、迭代器机制——RBTree 迭代器的架构与工程实现 3、高级容器设计——Map 与 Set…