PostgreSQL 操作数据库命令语法

操作类型语法说明示例
创建数据库CREATE DATABASE database_name [WITH options];创建一个新数据库。可选参数包括编码、拥有者等。CREATE DATABASE mydb;
创建名为 mydb 的数据库。
CREATE DATABASE database_name WITH OWNER = username ENCODING = 'UTF8';指定拥有者和编码创建数据库。CREATE DATABASE mydb WITH OWNER = admin ENCODING = 'UTF8';
创建 mydb,归 admin 用户,编码 UTF-8。
删除数据库DROP DATABASE database_name [WITH (FORCE)];删除指定数据库。FORCE 强制断开所有连接后删除。DROP DATABASE mydb;
删除 mydb 数据库。
DROP DATABASE IF EXISTS database_name;如果数据库存在则删除,不存在也不报错。DROP DATABASE IF EXISTS mydb;
安全删除 mydb,不存在也没事。
修改数据库ALTER DATABASE database_name RENAME TO new_name;重命名数据库。ALTER DATABASE mydb RENAME TO mynewdb;
mydb 改名为 mynewdb
ALTER DATABASE database_name OWNER TO new_owner;更改数据库的拥有者。ALTER DATABASE mydb OWNER TO admin;
mydb 的拥有者改为 admin
ALTER DATABASE database_name SET parameter = value;修改数据库的配置参数(如连接数限制)。ALTER DATABASE mydb SET max_connections = 200;
设置 mydb 最大连接数为 200。
连接数据库\c database_name (在 psql 中)在 psql 命令行中切换到指定数据库。\c mydb
连接到 mydb 数据库。
psql -d database_name -U username (命令行连接)从终端连接到指定数据库,需要用户名。psql -d mydb -U admin
admin 用户连接到 mydb
查看所有数据库SELECT datname FROM pg_database;查询当前实例中的所有数据库名称。SELECT datname FROM pg_database;
输出:postgres, mydb, template1 等。
\l (在 psql 中)在 psql 中列出所有数据库及其信息(如拥有者、大小)。\l
显示所有数据库列表。
备份数据库pg_dump database_name > backup_file.sql (命令行工具)导出数据库到 SQL 文件,用于备份。pg_dump mydb > mydb_backup.sql
备份 mydbmydb_backup.sql 文件。
pg_dump -h host -U username database_name > backup_file.sql指定主机和用户备份数据库。pg_dump -h localhost -U admin mydb > backup.sql
备份 mydb 到文件。
恢复数据库psql -d database_name < backup_file.sql (命令行工具)从 SQL 文件恢复数据库(需先创建空数据库)。psql -d mydb < mydb_backup.sql
mydb_backup.sql 恢复到 mydb
pg_restore -d database_name backup_file (若备份为自定义格式)从自定义格式备份文件恢复数据库。pg_restore -d mydb mydb_backup.dump
恢复 mydb.dump 文件。
创建表CREATE TABLE table_name (column_name type [constraints]);在当前数据库中创建表,默认在 public SCHEMA 中。CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(50));
创建 users 表。
删除表`DROP TABLE table_name [CASCADERESTRICT];`删除当前数据库中的表。CASCADE 删除关联,RESTRICT 如果有关联则拒绝。
查看表列表SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';查询当前数据库中指定 SCHEMA 的所有表。SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';
列出 public 中的表。
\dt (在 psql 中)在 psql 中列出当前数据库的所有表。\dt
显示当前数据库的表列表。
修改表结构ALTER TABLE table_name ADD COLUMN column_name type;向表中添加新列。ALTER TABLE users ADD COLUMN age INT;
users 表添加 age 列。
ALTER TABLE table_name DROP COLUMN column_name;删除表中的列。ALTER TABLE users DROP COLUMN age;
删除 users 表的 age 列。
ALTER TABLE table_name RENAME COLUMN old_name TO new_name;重命名表中的列。ALTER TABLE users RENAME COLUMN name TO username;
name 改名为 username
插入数据INSERT INTO table_name (column1, column2) VALUES (value1, value2);向表中插入数据。INSERT INTO users (id, name) VALUES (1, '小明');
插入一条记录到 users 表。
查询数据SELECT column_name FROM table_name [WHERE condition];从表中查询数据,可加条件。SELECT name FROM users WHERE id = 1;
查询 id=1 的用户姓名。
更新数据UPDATE table_name SET column_name = value [WHERE condition];更新表中的数据,可加条件。UPDATE users SET name = '小红' WHERE id = 1;
id=1 的名字改为 小红
删除数据DELETE FROM table_name [WHERE condition];删除表中的数据,可加条件。DELETE FROM users WHERE id = 1;
删除 id=1 的记录。
创建用户CREATE ROLE username WITH LOGIN PASSWORD 'password';创建一个可登录的用户(角色)。CREATE ROLE admin WITH LOGIN PASSWORD '123456';
创建用户 admin,密码 123456
授权数据库GRANT privileges ON DATABASE database_name TO username;给用户授予数据库权限(如 ALL, SELECT)。GRANT ALL ON DATABASE mydb TO admin;
admin 赋予 mydb 的所有权限。
撤销权限REVOKE privileges ON DATABASE database_name FROM username;撤销用户的数据库权限。REVOKE ALL ON DATABASE mydb FROM admin;
撤销 adminmydb 上的所有权限。

PostgreSQL 数据类型

数据类型存储内容用途示例通俗解释
SMALLINT小整数 (-32,768 到 32,767)年龄、班级编号小号盒子,装小份数字
INTEGER (INT)整数 (-2亿多 到 2亿多)用户 ID、商品数量中号盒子,装常用数字
BIGINT大整数 (-9千亿亿 到 9千亿亿)银行余额、全球人口大号盒子,装超大数字
DECIMAL / NUMERIC自定义精度的数字(带小数)金额(3.14、100.50)计算器,精确存钱和分数
REAL6位精度浮点数温度、身高近似小数盒,存不太精确的数字
DOUBLE PRECISION15位精度浮点数科学计算数据高精度小数盒,存很精确的数字
CHAR(n)固定长度字符串(n 个字符)邮编(6位)、性别(M/F)定长信封,装固定大小的字
VARCHAR(n)可变长度字符串(最大 n 个字符)名字、地址伸缩袋子,装大小不定的字
TEXT无长度限制的字符串文章、评论大口袋,装多少字都行
BOOLEANTRUE、FALSE 或 NULL是否已婚、是否通过考试开关,只有开和关两种状态
DATE日期(年-月-日)生日、订单日期日历,记年月日
TIME时间(时:分:秒)会议开始时间时钟,记几点几分
TIMESTAMP日期+时间(无时区)事件时间(2025-03-09 14:30:00)邮戳,记完整时间
TIMESTAMPTZ日期+时间(带时区)国际航班时间全球邮戳,带时区的时间
INTERVAL时间段(几天几小时)借书期限(3天、2小时)计时器,记一段时间
BYTEA二进制数据图片、视频文件U盘,存原始字节流
ENUM自定义固定值集合心情(happy/sad)、订单状态选择题,只能挑几个固定答案
ARRAY一组同类型数据成绩([90, 85, 88])、标签筐子,装一堆东西
JSONJSON 格式文本商品属性({“name”: “鞋”, “size”: 42})便签本,记结构化信息
JSONB二进制 JSON(支持查询和索引)复杂商品属性查询智能便签,带索引的高级本子
POINT坐标点(x, y)地图上的位置地图上的一个点
PostGIS 扩展地理数据(经纬度、区域等)导航、定位高级导航仪,存地图信息
INETIP 地址(IPv4/IPv6)用户登录 IP(192.168.1.1)网络门牌号
CIDR网络地址范围子网范围(192.168.1.0/24)网络地盘范围
MACADDRMAC 地址设备地址(00:1A:2B:3C:4D:5E)设备身份证号
UUID全球唯一标识符(128位)订单号(550e8400-e29b-41d4-…)宇宙身份证,独一无二
INT4RANGE 等范围范围值(如 [1, 10))时间段、价格区间划地盘,标出一段范围
XMLXML 格式数据结构化文档文件夹,存 XML 文件
MONEY货币金额价格(¥100.50)钱包,存带货币符号的金额

约束 (Constraints)

什么是约束? 约束是数据库的“规矩”,确保数据符合规则,防止乱七八糟的数据塞进来。

约束类型说明通俗理解示例
NOT NULL列不能是空值(NULL)。“这格必须填,不能留空!”CREATE TABLE users (id INT NOT NULL, name VARCHAR);
UNIQUE列值不能重复,但允许 NULL(多个 NULL 不算重复)。“每个人身份证号不能一样!”CREATE TABLE users (email VARCHAR UNIQUE);
PRIMARY KEY唯一且非空的列,用来标识每行记录。“每人一个独一无二的学号!”CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR);
FOREIGN KEY列值必须引用另一张表的主键或唯一键,确保关联有效。“学生的班级必须是真实班级!”CREATE TABLE orders (id INT, user_id INT REFERENCES users(id));
CHECK列值必须满足指定条件。“年龄不能是负数!”CREATE TABLE users (age INT CHECK (age >= 0));
EXCLUDE (高级)防止表中某些值的组合重复(需要扩展支持,如 GiST)。“会议室不能同时被两个人预定!”CREATE TABLE bookings (room INT, time TSTZRANGE, EXCLUDE USING gist (room WITH =, time WITH &&));

多表关联查询 (JOIN)

什么是关联查询? 把多张表拼起来查,就像把几页名单拼成一份大表格。

JOIN 类型说明通俗理解示例
INNER JOIN只返回两表匹配的行。“只找两边都有的记录!”SELECT u.name, o.order_date FROM users u INNER JOIN orders o ON u.id = o.user_id;
LEFT JOIN返回左表所有行,右表匹配不上就填 NULL。“左边全要,右边有就带上!”SELECT u.name, o.order_date FROM users u LEFT JOIN orders o ON u.id = o.user_id;
RIGHT JOIN返回右表所有行,左表匹配不上就填 NULL。“右边全要,左边有就带上!”SELECT u.name, o.order_date FROM users u RIGHT JOIN orders o ON u.id = o.user_id;
FULL JOIN返回两表所有行,匹配不上的填 NULL。“两边全要,没配对的也留着!”SELECT u.name, o.order_date FROM users u FULL JOIN orders o ON u.id = o.user_id;
CROSS JOIN两表每行交叉组合(笛卡尔积)。“所有人跟所有订单配一遍!”SELECT u.name, o.order_date FROM users u CROSS JOIN orders o;

别名 (Alias)

  • AS 或直接写简称给表或列起个“昵称”,让查询更简洁。
  • 示例:SELECT u.name AS username FROM users u;
  • 通俗理解:“给表和列取个小名,写起来不那么累!”

触发器 (Triggers)

什么是触发器? 触发器是表的“自动反应”,某事发生时自动执行操作。

  • 用途:记录日志、检查数据、同步表。
  • 语法
    CREATE TRIGGER trigger_name
    BEFORE | AFTER event (INSERT | UPDATE | DELETE)
    ON table_name
    FOR EACH ROW
    EXECUTE FUNCTION function_name();
    
  • 通俗理解:“表的小助手,有人改数据时它就跳出来干活!”

示例

CREATE FUNCTION log_update() RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO audit_log (table_name, changed_at) VALUES ('users', NOW());
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER user_update_log
AFTER UPDATE ON users
FOR EACH ROW
EXECUTE FUNCTION log_update();
  • 效果:每次更新 users 表,audit_log 都会记一笔。

索引 (Indexes)

什么是索引? 索引是表的“目录”,加速查找,减少翻遍全书的麻烦。

索引类型说明通俗理解示例
B-Tree默认索引,适合等值和范围查询。“普通目录,按顺序查!”CREATE INDEX idx_name ON users(name);
GiST通用索引,适合几何、范围查询。“高级目录,查地图和时间!”CREATE INDEX idx_time ON bookings USING gist(time);
GIN倒排索引,适合数组、JSON、全文搜索。“搜索目录,查关键词快!”CREATE INDEX idx_tags ON articles USING gin(tags);
BRIN块范围索引,适合大数据有序列。“粗略目录,查大表省空间!”CREATE INDEX idx_date ON logs USING brin(timestamp);
  • 语法CREATE INDEX index_name ON table_name(column_name);
  • 通俗理解:“给表加个快查手册,找东西不用一行行翻!”

最新特性

  • 并行索引创建CREATE INDEX ... WITH (PARALLEL_WORKERS = 4);,加速大表索引构建。
  • 覆盖索引CREATE INDEX idx_cover ON users(id) INCLUDE (name);,查询时不用访问表。

视图 (Views)

什么是视图? 视图是表的“虚拟窗口”,基于查询结果,像个快捷方式。

  • 语法
    CREATE VIEW view_name AS SELECT ...;
    
  • 通俗理解:“把复杂查询存下来,随时看,不用每次重写!”

示例

CREATE VIEW active_users AS
SELECT id, name FROM users WHERE status = 'active';
  • 效果:SELECT * FROM active_users; 直接看活跃用户。

事务(Transactions)

什么是事务? 事务是一组操作,要么全成功,要么全取消,保证数据不乱。

  • 语法
    BEGIN;
    -- 操作1
    -- 操作2
    COMMIT;  -- 成功提交
    -- 或 ROLLBACK;  -- 失败回滚
    
  • 通俗理解:“一篮子任务,要么全做完,要么全撤销,像转账不能只扣不加!”

示例

BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;

锁 (Locks)

什么是锁? 锁是数据库的“门锁”,防止多人同时改数据出错。

锁类型说明通俗理解示例
行锁 (ROW)锁住某行,别人不能改。“这行我先用,你等会!”SELECT * FROM users WHERE id = 1 FOR UPDATE;
表锁 (TABLE)锁住整张表,如 SHARE(读锁)、EXCLUSIVE(写锁)。“整张表我包了,别动!”LOCK TABLE users IN EXCLUSIVE MODE;
死锁两事务互相等对方解锁,卡住。“你等我,我等你,谁也不动!”系统自动检测并终止一个事务。
  • 通俗理解:“锁是交通信号灯,控制谁能动,谁得等!”

函数 (Functions)

什么是函数? 函数是数据库的“自定义工具”,写一段代码反复用。

  • 语法
    CREATE FUNCTION function_name(params) RETURNS type AS $$
    BEGIN
        -- 逻辑
    END;
    $$ LANGUAGE plpgsql;
    
  • 通俗理解:“自己造个小机器人,干重复活!”

示例

CREATE FUNCTION add_numbers(a INT, b INT) RETURNS INT AS $$
BEGIN
    RETURN a + b;
END;
$$ LANGUAGE plpgsql;
  • 使用:SELECT add_numbers(3, 5); 输出 8。

补充知识点

知识点说明通俗理解示例
序列 (Sequences)自动生成递增数字,常用于主键。“自动编号机!”CREATE SEQUENCE user_seq;
INSERT INTO users (id) VALUES (nextval('user_seq'));
分区表把大表拆成小块,按范围或列表分。“大书拆成小册子,好查!”CREATE TABLE logs (id INT, ts TIMESTAMP) PARTITION BY RANGE (ts);
全文搜索搜索文本内容,支持关键词和高亮。“数据库里的搜索引擎!”SELECT * FROM articles WHERE to_tsvector(content) @@ to_tsquery('good & news');
表空间 (Tablespaces)指定数据存储的物理位置。“换个硬盘存数据!”CREATE TABLESPACE fastdisk LOCATION '/ssd/pgdata';
角色与权限管理用户和访问权限。“谁能看谁能改的门禁卡!”GRANT SELECT ON users TO reader;

通俗总结

  • 约束:表的规矩,防乱填。
  • 关联查询:拼表找数据,别名是小助手。
  • 触发器:表的小机器人,自动干活。
  • 索引:表的快查目录,找得快。
  • 视图:表的快捷窗口,省事。
  • 事务:一篮子任务,全成或全废。
  • :表的门锁,防抢。
  • 函数:自定义工具,偷懒神器。
  • 补全:序列编号、分区拆表、搜索文本、权限管理,一个不漏!

什么是 SCHEMA?

在 PostgreSQL 中,SCHEMA 是一个逻辑上的“命名空间”或者“文件夹”,用来组织和管理数据库对象(比如表、视图、索引等)。一个数据库(Database)可以包含多个 SCHEMA,而每个 SCHEMA 里可以有自己的表、视图等东西。

  • 比喻:想象一个大仓库(数据库),里面有很多货架(SCHEMA),每个货架上放不同的货物(表、视图等)。SCHEMA 就是帮你把东西分门别类放好。
  • 官方定义:SCHEMA 是数据库中的一个逻辑分组,同一个数据库里的 SCHEMA 共享存储空间,但彼此独立命名。

SCHEMA 的作用

  1. 组织数据 把相关的表归类到一个 SCHEMA 中,方便管理。比如,一个公司数据库可以有 sales(销售)、hr(人力资源)、inventory(库存)三个 SCHEMA。
  2. 权限控制 可以给不同用户分配不同 SCHEMA 的访问权限。比如,销售团队只能看 sales 的表,HR 只能看 hr 的表。
  3. 避免命名冲突 在同一个数据库里,不同 SCHEMA 可以有同名表。比如 sales.productinventory.product,名字一样但内容不同,不会混淆。
  4. 模块化开发 大型项目中,不同模块可以用不同 SCHEMA 分开,逻辑更清晰。

在什么情况下要用到 SCHEMA?

  1. 多用户或多团队场景
    • 如果一个数据库被多个团队共用,每个团队可以用自己的 SCHEMA,避免互相干扰。
    • 示例:一个学校数据库,老师用 teacher SCHEMA,学生用 student SCHEMA。
  2. 复杂项目需要分模块
    • 大型应用可能有多个子系统(比如电商的订单、用户、库存),用 SCHEMA 分开更清晰。
    • 示例:orders.order_tableusers.user_table
  3. 权限管理需求
    • 需要精细控制谁能访问哪些表时,SCHEMA 是个好工具。
    • 示例:财务数据放 finance SCHEMA,只给财务人员权限。
  4. 测试和生产环境共存
    • 在同一个数据库里,test SCHEMA 放测试数据,prod SCHEMA 放生产数据,方便切换。

什么时候不用 SCHEMA? 如果你的项目很简单,只有一个团队、几个表,数据量也不大,默认的 public SCHEMA 就够用了。

SCHEMA 是否真实创建了一个数据库?

答案:不是。

  • SCHEMA 不是一个独立的数据库,它只是数据库内部的一个逻辑分组。
  • 数据库 vs SCHEMA
    • 数据库(Database):是物理隔离的存储单元,创建时会分配独立的空间。不同数据库之间完全独立,比如 mydb1mydb2 的数据互不影响。
    • SCHEMA:是数据库里的“子文件夹”,所有 SCHEMA 共享同一个数据库的存储空间和连接。切换 SCHEMA 不需要重新连接数据库。
  • 比喻
    • 数据库是大房子,SCHEMA 是房子里的房间。建新房子(数据库)需要地基和材料,分房间(SCHEMA)只是画个隔断。
  • 证明
    • 创建 SCHEMA:CREATE SCHEMA myschema; —— 只是在当前数据库里加了个“文件夹”。
    • 创建数据库:CREATE DATABASE mydb; —— 这是建了个新“仓库”,完全独立。

通俗总结

  • SCHEMA 是什么:数据库里的“文件夹”,帮你整理表和控制权限。
  • 什么时候用:项目复杂、需要分团队或模块时用。简单项目用 public 就行。
  • public 行不行:小项目行,大项目不够用。
  • 是不是数据库:不是,只是数据库里的分组,不会独立占用空间。

举个例子: 你开个小店,只有一个货架(public),够用。但如果开了连锁超市,货架得按类别分(fruitsdrinks),这就是 SCHEMA 的用武之地。