PostgreSQL 中文教程
1. 核心概念
PostgreSQL 是一个功能强大的开源对象关系型数据库系统,它使用 SQL 语言并结合了许多现代特性。PostgreSQL 以其可靠性、稳定性和强大的功能而闻名,是企业级应用的理想选择。
1.1 主要特点
- 对象关系型:支持对象导向和关系型数据库的特性
- SQL 标准兼容:高度符合 SQL 标准
- 可扩展性:支持自定义数据类型、函数、操作符等
- 强大的索引系统:支持 B-tree、Hash、GiST、SP-GiST、GIN、BRIN 等多种索引类型
- 事务支持:完整的 ACID 事务支持
- 并发控制:多版本并发控制 (MVCC)
- 外键约束:支持完整的外键约束
- 高级查询功能:支持复杂查询、子查询、连接查询等
- 存储过程和触发器:支持 PL/pgSQL、PL/Tcl、PL/Perl、PL/Python 等
- 地理空间支持:通过 PostGIS 扩展支持地理空间数据
- JSON 支持:原生支持 JSON 和 JSONB 数据类型
1.2 技术栈特点
- 可靠性:强大的事务支持和数据完整性保证
- 可扩展性:支持水平和垂直扩展
- 安全性:丰富的安全特性,包括行级安全性
- 性能:优化的查询执行和索引系统
- 兼容性:高度符合 SQL 标准,支持多种编程语言接口
- 生态系统:丰富的扩展和工具
2. 安装配置
2.1 安装
2.1.1 Windows 安装
- 从 PostgreSQL 官方网站 下载 Windows 版本的 PostgreSQL
- 运行安装程序,按照向导完成安装
- 安装过程中会设置超级用户密码和端口号
- 安装完成后,可以使用 pgAdmin 进行管理
2.1.2 Linux 安装
使用包管理器安装:
# Ubuntu/Debian
apt-get update
apt-get install postgresql postgresql-contrib
# CentOS/RHEL
yum install postgresql-server postgresql-contrib
# 初始化数据库(CentOS/RHEL)
postgresql-setup --initdb
# 启动服务
systemctl start postgresql
systemctl enable postgresql2.1.3 macOS 安装
使用 Homebrew 安装:
brew install postgresql
# 启动服务
brew services start postgresql
# 初始化数据库(首次安装)
initdb /usr/local/var/postgres2.2 基本配置
PostgreSQL 的主要配置文件位于:
- Windows:
C:\Program Files\PostgreSQL\版本\data\postgresql.conf - Linux:
/etc/postgresql/版本/main/postgresql.conf - macOS:
/usr/local/var/postgres/postgresql.conf
主要配置项:
# 连接配置
listen_addresses = 'localhost' # 监听地址
port = 5432 # 端口号
max_connections = 100 # 最大连接数
# 资源配置
shared_buffers = 128MB # 共享内存缓冲区
work_mem = 4MB # 每个查询的工作内存
maintenance_work_mem = 64MB # 维护操作的工作内存
# 日志配置
log_directory = 'log' # 日志目录
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' # 日志文件名
log_level = warning # 日志级别
# 认证配置
hba_file = 'pg_hba.conf' # 主机基础认证配置文件
ident_file = 'pg_ident.conf' # 标识认证配置文件认证配置文件 pg_hba.conf:
# 类型 数据库 用户 地址 认证方法
local all all peer
host all all 127.0.0.1/32 md5
host all all ::1/128 md52.3 启动和停止 PostgreSQL
2.3.1 Windows
- 通过服务管理器启动/停止 PostgreSQL 服务
- 使用命令行:
net start postgresql-x64-版本 net stop postgresql-x64-版本
2.3.2 Linux
# 启动服务
systemctl start postgresql
# 停止服务
systemctl stop postgresql
# 重启服务
systemctl restart postgresql
# 查看服务状态
systemctl status postgresql2.3.3 macOS
# 启动服务
brew services start postgresql
# 停止服务
brew services stop postgresql
# 重启服务
brew services restart postgresql
# 查看服务状态
brew services list2.4 连接到 PostgreSQL
使用 psql 命令行工具连接:
# 基本连接
psql -U postgres
# 指定数据库
psql -U postgres -d database_name
# 指定主机和端口
psql -U postgres -h host -p port -d database_name
# 使用环境变量
PGUSER=postgres PGDATABASE=database_name psql3. 基本使用
3.1 数据库操作
-- 创建数据库
CREATE DATABASE database_name;
-- 删除数据库
DROP DATABASE database_name;
-- 重命名数据库
ALTER DATABASE old_name RENAME TO new_name;
-- 连接数据库\c database_name;
-- 查看所有数据库\l3.2 用户和权限
-- 创建用户
CREATE USER username WITH PASSWORD 'password';
-- 修改用户密码
ALTER USER username WITH PASSWORD 'new_password';
-- 删除用户
DROP USER username;
-- 授予权限
GRANT ALL PRIVILEGES ON DATABASE database_name TO username;
GRANT SELECT, INSERT, UPDATE, DELETE ON table_name TO username;
-- 撤销权限
REVOKE ALL PRIVILEGES ON DATABASE database_name FROM username;
-- 查看用户
\du
-- 查看权限\dp3.3 表操作
-- 创建表
CREATE TABLE table_name (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
age INTEGER,
email VARCHAR(255) UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 修改表
-- 添加列
ALTER TABLE table_name ADD COLUMN address VARCHAR(255);
-- 修改列
ALTER TABLE table_name ALTER COLUMN age SET NOT NULL;
-- 删除列
ALTER TABLE table_name DROP COLUMN address;
-- 重命名表
ALTER TABLE table_name RENAME TO new_table_name;
-- 删除表
DROP TABLE table_name;
-- 查看表\dt
-- 查看表结构\d table_name;3.4 数据操作
3.4.1 插入数据
-- 插入单行数据
INSERT INTO table_name (name, age, email) VALUES ('张三', 30, 'zhangsan@example.com');
-- 插入多行数据
INSERT INTO table_name (name, age, email) VALUES
('李四', 25, 'lisi@example.com'),
('王五', 35, 'wangwu@example.com');
-- 插入并返回数据
INSERT INTO table_name (name, age, email) VALUES ('赵六', 28, 'zhaoliu@example.com') RETURNING id, name;3.4.2 查询数据
-- 查询所有数据
SELECT * FROM table_name;
-- 查询指定列
SELECT id, name, age FROM table_name;
-- 带条件查询
SELECT * FROM table_name WHERE age > 25;
-- 排序
SELECT * FROM table_name ORDER BY age ASC;
SELECT * FROM table_name ORDER BY age DESC;
-- 限制结果
SELECT * FROM table_name LIMIT 10;
SELECT * FROM table_name OFFSET 5 LIMIT 10;
-- 分组
SELECT age, COUNT(*) FROM table_name GROUP BY age;
-- 分组并过滤
SELECT age, COUNT(*) FROM table_name GROUP BY age HAVING COUNT(*) > 1;
-- 连接查询
SELECT t1.*, t2.* FROM table1 t1 JOIN table2 t2 ON t1.id = t2.table1_id;
SELECT t1.*, t2.* FROM table1 t1 LEFT JOIN table2 t2 ON t1.id = t2.table1_id;
SELECT t1.*, t2.* FROM table1 t1 RIGHT JOIN table2 t2 ON t1.id = t2.table1_id;
SELECT t1.*, t2.* FROM table1 t1 FULL JOIN table2 t2 ON t1.id = t2.table1_id;
-- 子查询
SELECT * FROM table_name WHERE age > (SELECT AVG(age) FROM table_name);
-- EXISTS 查询
SELECT * FROM table1 WHERE EXISTS (SELECT 1 FROM table2 WHERE table2.table1_id = table1.id);3.4.3 更新数据
-- 更新数据
UPDATE table_name SET age = 31, email = 'zhangsanupdated@example.com' WHERE name = '张三';
-- 使用 FROM 子句更新
UPDATE table1 t1 SET t1.status = t2.status FROM table2 t2 WHERE t1.id = t2.table1_id;
-- 更新并返回数据
UPDATE table_name SET age = 32 WHERE name = '张三' RETURNING id, name, age;3.4.4 删除数据
-- 删除数据
DELETE FROM table_name WHERE name = '张三';
-- 删除所有数据
DELETE FROM table_name;
-- 删除并返回数据
DELETE FROM table_name WHERE age < 25 RETURNING id, name;3.5 索引操作
-- 创建索引
CREATE INDEX idx_table_name_age ON table_name(age);
-- 创建唯一索引
CREATE UNIQUE INDEX idx_table_name_email ON table_name(email);
-- 创建复合索引
CREATE INDEX idx_table_name_name_age ON table_name(name, age);
-- 创建部分索引
CREATE INDEX idx_table_name_age_over_30 ON table_name(age) WHERE age > 30;
-- 删除索引
DROP INDEX idx_table_name_age;
-- 查看索引\di3.6 约束
-- 创建表时添加约束
CREATE TABLE table_name (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
age INTEGER CHECK (age > 0),
email VARCHAR(255) UNIQUE,
department_id INTEGER REFERENCES departments(id)
);
-- 添加约束
ALTER TABLE table_name ADD CONSTRAINT unique_email UNIQUE (email);
ALTER TABLE table_name ADD CONSTRAINT fk_department FOREIGN KEY (department_id) REFERENCES departments(id);
ALTER TABLE table_name ADD CONSTRAINT check_age CHECK (age > 0);
-- 删除约束
ALTER TABLE table_name DROP CONSTRAINT unique_email;
-- 查看约束\d table_name;4. 高级功能
4.1 事务
PostgreSQL 支持完整的 ACID 事务:
-- 开始事务
BEGIN;
-- 执行操作
INSERT INTO table_name (name, age, email) VALUES ('张三', 30, 'zhangsan@example.com');
UPDATE table_name SET age = 31 WHERE name = '张三';
-- 提交事务
COMMIT;
-- 回滚事务
ROLLBACK;
-- 保存点
BEGIN;
INSERT INTO table_name (name, age, email) VALUES ('李四', 25, 'lisi@example.com');
SAVEPOINT savepoint1;
UPDATE table_name SET age = 26 WHERE name = '李四';
ROLLBACK TO savepoint1;
COMMIT;4.2 视图
视图是虚拟表,基于查询结果:
-- 创建视图
CREATE VIEW view_name AS
SELECT id, name, age FROM table_name WHERE age > 25;
-- 创建物化视图
CREATE MATERIALIZED VIEW mat_view_name AS
SELECT age, COUNT(*) as count FROM table_name GROUP BY age;
-- 刷新物化视图
REFRESH MATERIALIZED VIEW mat_view_name;
-- 删除视图
DROP VIEW view_name;
DROP MATERIALIZED VIEW mat_view_name;
-- 查看视图\dv4.3 存储过程和函数
PostgreSQL 支持多种过程语言,默认使用 PL/pgSQL:
-- 创建函数
CREATE OR REPLACE FUNCTION get_user_by_id(user_id INTEGER)
RETURNS TABLE(id INTEGER, name VARCHAR, age INTEGER, email VARCHAR)
AS $$
BEGIN
RETURN QUERY SELECT * FROM table_name WHERE id = user_id;
END;
$$ LANGUAGE plpgsql;
-- 调用函数
SELECT * FROM get_user_by_id(1);
-- 创建存储过程
CREATE OR REPLACE PROCEDURE update_user_age(user_id INTEGER, new_age INTEGER)
AS $$
BEGIN
UPDATE table_name SET age = new_age WHERE id = user_id;
END;
$$ LANGUAGE plpgsql;
-- 调用存储过程
CALL update_user_age(1, 35);
-- 删除函数
DROP FUNCTION get_user_by_id(INTEGER);
-- 删除存储过程
DROP PROCEDURE update_user_age(INTEGER, INTEGER);4.4 触发器
触发器在特定事件发生时自动执行:
-- 创建触发器函数
CREATE OR REPLACE FUNCTION log_user_changes()
RETURNS TRIGGER
AS $$
BEGIN
IF TG_OP = 'INSERT' THEN
INSERT INTO user_logs (action, user_id, old_data, new_data, created_at)
VALUES ('INSERT', NEW.id, NULL, row_to_json(NEW), CURRENT_TIMESTAMP);
ELSIF TG_OP = 'UPDATE' THEN
INSERT INTO user_logs (action, user_id, old_data, new_data, created_at)
VALUES ('UPDATE', NEW.id, row_to_json(OLD), row_to_json(NEW), CURRENT_TIMESTAMP);
ELSIF TG_OP = 'DELETE' THEN
INSERT INTO user_logs (action, user_id, old_data, new_data, created_at)
VALUES ('DELETE', OLD.id, row_to_json(OLD), NULL, CURRENT_TIMESTAMP);
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- 创建触发器
CREATE TRIGGER user_changes_trigger
AFTER INSERT OR UPDATE OR DELETE ON table_name
FOR EACH ROW
EXECUTE FUNCTION log_user_changes();
-- 删除触发器
DROP TRIGGER user_changes_trigger ON table_name;
-- 删除触发器函数
DROP FUNCTION log_user_changes();4.5 高级查询
4.5.1 窗口函数
窗口函数用于对查询结果集的子集进行计算:
-- 计算排名
SELECT id, name, age, RANK() OVER (ORDER BY age DESC) as rank FROM table_name;
-- 计算分区排名
SELECT id, name, age, department, RANK() OVER (PARTITION BY department ORDER BY age DESC) as dept_rank FROM table_name;
-- 计算移动平均值
SELECT id, name, age, AVG(age) OVER (ORDER BY id ROWS BETWEEN 2 PRECEDING AND 2 FOLLOWING) as moving_avg FROM table_name;4.5.2 递归查询
使用 WITH RECURSIVE 进行递归查询:
-- 创建部门表
CREATE TABLE departments (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
parent_id INTEGER REFERENCES departments(id)
);
-- 插入数据
INSERT INTO departments (name, parent_id) VALUES ('总公司', NULL);
INSERT INTO departments (name, parent_id) VALUES ('技术部', 1);
INSERT INTO departments (name, parent_id) VALUES ('产品部', 1);
INSERT INTO departments (name, parent_id) VALUES ('前端组', 2);
INSERT INTO departments (name, parent_id) VALUES ('后端组', 2);
-- 递归查询部门层级
WITH RECURSIVE department_tree AS (
SELECT id, name, parent_id, 0 as level
FROM departments
WHERE parent_id IS NULL
UNION ALL
SELECT d.id, d.name, d.parent_id, dt.level + 1
FROM departments d
JOIN department_tree dt ON d.parent_id = dt.id
)
SELECT id, REPEAT(' ', level) || name as name, level
FROM department_tree
ORDER BY id;4.6 JSON 支持
PostgreSQL 原生支持 JSON 和 JSONB 数据类型:
-- 创建包含 JSON 列的表
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
profile JSONB
);
-- 插入 JSON 数据
INSERT INTO users (name, profile) VALUES (
'张三',
'{"age": 30, "email": "zhangsan@example.com", "address": {"city": "北京", "district": "朝阳区"}}'
);
-- 查询 JSON 数据
SELECT name, profile->>'age' as age, profile->>'email' as email FROM users;
SELECT name, profile->'address'->>'city' as city FROM users;
-- 使用 JSON 操作符
SELECT name FROM users WHERE profile->>'age' > '25';
SELECT name FROM users WHERE profile @> '{"age": 30}';
-- 更新 JSON 数据
UPDATE users SET profile = profile || '{"phone": "13800138000"}'::jsonb WHERE name = '张三';4.7 全文搜索
PostgreSQL 支持强大的全文搜索功能:
-- 创建包含文本列的表
CREATE TABLE articles (
id SERIAL PRIMARY KEY,
title VARCHAR(255) NOT NULL,
content TEXT
);
-- 创建全文搜索索引
CREATE INDEX idx_articles_content ON articles USING GIN (to_tsvector('english', content));
-- 使用全文搜索
SELECT id, title FROM articles WHERE to_tsvector('english', content) @@ plainto_tsquery('english', 'database postgresql');
-- 使用加权搜索
SELECT id, title, ts_rank(to_tsvector('english', content), plainto_tsquery('english', 'database postgresql')) as rank
FROM articles
WHERE to_tsvector('english', content) @@ plainto_tsquery('english', 'database postgresql')
ORDER BY rank DESC;5. 最佳实践
5.1 性能优化
5.1.1 索引优化
- 选择合适的索引类型:根据数据类型和查询模式选择合适的索引类型
- B-tree:适用于大多数查询,支持等值和范围查询
- Hash:适用于等值查询
- GiST:适用于地理空间数据和全文搜索
- GIN:适用于数组和 JSON 数据
- 复合索引顺序:将选择性高的列放在前面
- 避免过度索引:过多的索引会影响写入性能
- 使用部分索引:只对常用查询条件创建索引
- 定期重建索引:对于频繁更新的表,定期重建索引
5.1.2 查询优化
- 使用 EXPLAIN 分析查询计划:
EXPLAIN ANALYZE SELECT * FROM table_name WHERE condition; - 避免全表扫描:确保查询条件使用索引
- 使用 LIMIT 限制结果集:避免返回过多数据
- **避免 SELECT ***:只选择需要的列
- 使用连接代替子查询:某些情况下连接查询性能更好
- 使用物化视图:对于复杂查询结果,使用物化视图缓存
- 避免在 WHERE 子句中使用函数:会导致索引失效
5.1.3 数据库配置优化
- 调整 shared_buffers:通常设置为总内存的 25%
- 调整 work_mem:根据查询复杂度调整
- 调整 maintenance_work_mem:用于维护操作,如 VACUUM
- 启用查询缓存:设置
shared_preload_libraries = 'pg_stat_statements' - 调整 checkpoint 配置:平衡性能和安全性
5.2 安全性
5.2.1 访问控制
- 使用最小权限原则:只授予用户必要的权限
- 使用角色管理权限:创建角色组管理权限
- 定期审查用户权限:确保权限设置正确
- 使用 SSL 连接:加密客户端和服务器之间的通信
- 配置 pg_hba.conf:限制连接来源和认证方式
5.2.2 数据安全
- 定期备份:使用 pg_dump 或 pg_basebackup 备份数据
- 使用 WAL 归档:启用归档模式,支持 Point-in-Time Recovery
- 加密敏感数据:使用 pgcrypto 扩展加密敏感数据
- 实现行级安全性:使用 Row-Level Security 控制数据访问
- 定期更新 PostgreSQL:保持版本最新,获取安全补丁
5.3 备份和恢复
5.3.1 备份
使用 pg_dump 备份:
# 备份整个数据库
pg_dump -U postgres -d database_name -F c -f backup_file.dump
# 备份特定表
pg_dump -U postgres -d database_name -t table_name -F c -f backup_file.dump
# 备份为 SQL 文件
pg_dump -U postgres -d database_name -f backup_file.sql
# 压缩备份
pg_dump -U postgres -d database_name | gzip > backup_file.sql.gz使用 pg_basebackup 进行基础备份:
# 基础备份
pg_basebackup -D /backup/directory -h host -U postgres -v -P
# 增量备份
# 需要配置 WAL 归档5.3.2 恢复
从 pg_dump 备份恢复:
# 从自定义格式备份恢复
pg_restore -U postgres -d database_name -v backup_file.dump
# 从 SQL 文件恢复
psql -U postgres -d database_name -f backup_file.sql从基础备份恢复:
# 停止 PostgreSQL
systemctl stop postgresql
# 清空数据目录
rm -rf /var/lib/postgresql/版本/main/*
# 恢复基础备份
rsync -av /backup/directory/ /var/lib/postgresql/版本/main/
# 创建恢复配置文件
echo "restore_command = 'cp /archive/%f %p'" > /var/lib/postgresql/版本/main/recovery.conf
# 启动 PostgreSQL
systemctl start postgresql5.4 监控和维护
5.4.1 监控工具
- pg_stat_statements:跟踪查询性能
- pg_stat_activity:查看当前连接和查询
- pg_stat_database:数据库统计信息
- pg_top:实时监控 PostgreSQL 活动
- Prometheus + Grafana:可视化监控
5.4.2 维护操作
VACUUM:回收死元组空间
-- 手动执行 VACUUM VACUUM table_name; -- 全量 VACUUM VACUUM FULL table_name; -- 分析表统计信息 ANALYZE table_name;REINDEX:重建索引
-- 重建索引 REINDEX TABLE table_name; REINDEX INDEX index_name;检查数据库:
-- 检查数据库一致性 CHECKPOINT; -- 查看数据库大小 SELECT pg_size_pretty(pg_database_size('database_name')); -- 查看表大小 SELECT pg_size_pretty(pg_total_relation_size('table_name'));
6. 实际应用
6.1 Node.js 集成
使用 pg 模块连接 PostgreSQL:
const { Pool } = require('pg');
// 创建连接池
const pool = new Pool({
user: 'postgres',
host: 'localhost',
database: 'test',
password: 'password',
port: 5432,
});
// 执行查询
async function getUsers() {
try {
const res = await pool.query('SELECT * FROM users');
console.log(res.rows);
return res.rows;
} catch (err) {
console.error(err);
}
}
// 插入数据
async function createUser(name, age, email) {
try {
const res = await pool.query(
'INSERT INTO users (name, age, email) VALUES ($1, $2, $3) RETURNING id, name',
[name, age, email]
);
console.log('创建用户:', res.rows[0]);
return res.rows[0];
} catch (err) {
console.error(err);
}
}
// 调用函数
getUsers();
createUser('张三', 30, 'zhangsan@example.com');
// 关闭连接池
// pool.end();6.2 Express.js 集成
使用 Express.js 和 pg 模块构建 REST API:
const express = require('express');
const { Pool } = require('pg');
const app = express();
const port = 3000;
// 中间件
app.use(express.json());
// 创建连接池
const pool = new Pool({
user: 'postgres',
host: 'localhost',
database: 'test',
password: 'password',
port: 5432,
});
// 路由
app.get('/users', async (req, res) => {
try {
const result = await pool.query('SELECT * FROM users');
res.json(result.rows);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.get('/users/:id', async (req, res) => {
try {
const { id } = req.params;
const result = await pool.query('SELECT * FROM users WHERE id = $1', [id]);
if (result.rows.length === 0) {
return res.status(404).json({ message: '用户不存在' });
}
res.json(result.rows[0]);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.post('/users', async (req, res) => {
try {
const { name, age, email } = req.body;
const result = await pool.query(
'INSERT INTO users (name, age, email) VALUES ($1, $2, $3) RETURNING *',
[name, age, email]
);
res.status(201).json(result.rows[0]);
} catch (error) {
res.status(400).json({ error: error.message });
}
});
app.put('/users/:id', async (req, res) => {
try {
const { id } = req.params;
const { name, age, email } = req.body;
const result = await pool.query(
'UPDATE users SET name = $1, age = $2, email = $3 WHERE id = $4 RETURNING *',
[name, age, email, id]
);
if (result.rows.length === 0) {
return res.status(404).json({ message: '用户不存在' });
}
res.json(result.rows[0]);
} catch (error) {
res.status(400).json({ error: error.message });
}
});
app.delete('/users/:id', async (req, res) => {
try {
const { id } = req.params;
const result = await pool.query('DELETE FROM users WHERE id = $1 RETURNING *', [id]);
if (result.rows.length === 0) {
return res.status(404).json({ message: '用户不存在' });
}
res.json({ message: '用户已删除' });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// 启动服务器
app.listen(port, () => {
console.log(`服务器运行在 http://localhost:${port}`);
});6.3 数据迁移工具
使用 pg-migrate 进行数据库迁移:
# 安装
npm install -g node-pg-migrate
# 创建迁移
node-pg-migrate create create-users-table
# 编辑迁移文件
# 在 migrations 目录中编辑生成的文件
# 运行迁移
DATABASE_URL=postgres://postgres:password@localhost:5432/test node-pg-migrate up
# 回滚迁移
DATABASE_URL=postgres://postgres:password@localhost:5432/test node-pg-migrate down6.4 ORM 集成
使用 Sequelize ORM:
const { Sequelize, DataTypes } = require('sequelize');
// 创建连接
const sequelize = new Sequelize('test', 'postgres', 'password', {
host: 'localhost',
dialect: 'postgres'
});
// 定义模型
const User = sequelize.define('User', {
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
name: {
type: DataTypes.STRING,
allowNull: false
},
age: {
type: DataTypes.INTEGER
},
email: {
type: DataTypes.STRING,
unique: true
}
}, {
tableName: 'users',
timestamps: true
});
// 同步模型
(async () => {
await sequelize.sync({ alter: true });
console.log('数据库同步完成');
})();
// CRUD 操作
(async () => {
// 创建用户
const user = await User.create({ name: '张三', age: 30, email: 'zhangsan@example.com' });
console.log('创建用户:', user.toJSON());
// 查询用户
const users = await User.findAll();
console.log('所有用户:', users.map(u => u.toJSON()));
// 更新用户
await user.update({ age: 31 });
console.log('更新后的用户:', user.toJSON());
// 删除用户
// await user.destroy();
})();7. 总结
PostgreSQL 是一个功能强大、可靠且高度可扩展的开源关系型数据库系统。它提供了丰富的特性,包括完整的 SQL 支持、高级索引、事务处理、JSON 支持、全文搜索等,使其成为从个人项目到企业级应用的理想选择。
7.1 主要优势
- 功能丰富:支持高级特性如 JSON、全文搜索、地理空间数据等
- 可靠性:强大的事务支持和数据完整性保证
- 可扩展性:支持自定义数据类型、函数和操作符
- 性能:优化的查询执行和索引系统
- 安全性:丰富的安全特性和访问控制
- 开源:免费使用,社区活跃
- 标准兼容:高度符合 SQL 标准
7.2 适用场景
- 企业级应用:需要可靠性和数据完整性的业务系统
- 数据分析:支持复杂查询和聚合操作
- Web 应用:与各种编程语言和框架良好集成
- 地理信息系统:通过 PostGIS 扩展支持地理空间数据
- 内容管理系统:支持全文搜索和复杂数据结构
- 金融系统:需要事务支持和数据一致性
7.3 未来展望
PostgreSQL 作为一个成熟的开源项目,不断发展和完善。未来的 PostgreSQL 可能会:
- 进一步提高性能:优化查询执行和存储引擎
- 增强云原生支持:更好地适应云环境
- 提供更多高级特性:如机器学习集成、更强大的 JSON 支持
- 简化管理:提供更直观的管理工具和接口
- 增强安全性:提供更多企业级安全特性
通过本文的学习,相信开发者已经对 PostgreSQL 有了全面的了解,可以开始在实际项目中使用 PostgreSQL 构建可靠、高性能的应用了。