外观
PostgreSQL 笔记
约 4033 字大约 13 分钟
2025-08-23
一、PostgreSQL 简介
1.1 什么是 PostgreSQL?
PostgreSQL 是一款功能强大的开源对象关系型数据库系统,拥有超过 30 年的积极开发历史。它以可靠性、功能强大和性能优异著称,支持丰富的数据类型和高级功能,如复杂查询、外键、触发器、视图、事务性 DDL 等。
1.2 PostgreSQL 核心特点
- 开源免费:完全开源,遵循 PostgreSQL 许可证
- 扩展性强:支持自定义函数、数据类型、操作符
- ACID 合规:保证事务的原子性、一致性、隔离性和持久性
- 丰富的数据类型:支持 JSON、XML、数组、范围类型等
- 强大的扩展系统:可通过扩展添加新功能(如 PostGIS、pgvector)
- 高可用性:支持流复制、逻辑复制、连接池等
- 全文搜索:内置全文搜索功能
1.3 PostgreSQL 与 MySQL 对比
| 特性 | PostgreSQL | MySQL |
|---|---|---|
| 许可证 | PostgreSQL 许可证(宽松开源) | GPL(社区版) |
| ACID 支持 | 完全支持 | InnoDB 支持 |
| JSON 支持 | JSONB(二进制存储,可索引) | JSON(文本存储) |
| 全文搜索 | 内置强大全文搜索 | 基本全文搜索 |
| 窗口函数 | 完整支持 | 8.0+ 支持 |
| 物化视图 | 支持 | 5.7+ 支持 |
| 扩展系统 | 丰富(PostGIS, pgvector 等) | 有限 |
| 复制 | 流复制、逻辑复制 | 主从复制、组复制 |
1.4 典型应用场景
- 复杂查询应用:需要执行复杂分析和聚合的应用
- 地理信息系统:配合 PostGIS 扩展处理地理空间数据
- JSON 数据处理:需要存储和查询 JSON 数据的场景
- 高可靠性系统:金融、电信等对数据完整性要求高的领域
- 数据仓库:作为 OLAP 系统的一部分
二、环境搭建
2.1 安装方法
Linux (Ubuntu):
# 添加 PostgreSQL 仓库
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
wget -qO- https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo apt update
# 安装最新版本
sudo apt install postgresqlWindows:
- 下载官方安装程序:https://www.postgresql.org/download/windows/
- 运行安装程序,按向导完成安装
- 设置超级用户密码和端口(默认 5432)
macOS:
# 使用 Homebrew
brew install postgresql
brew services start postgresql2.2 基本配置
主要配置文件:postgresql.conf(通常位于 /etc/postgresql/版本/main/ 或安装目录的 data 文件夹)
常用配置项:
# 连接和认证
listen_addresses = '*' # 监听所有IP
port = 5432 # 端口号
max_connections = 100 # 最大连接数
# 资源使用
shared_buffers = 1GB # 共享缓冲区大小(通常为内存的25%)
work_mem = 4MB # 排序操作的工作内存
maintenance_work_mem = 256MB # 维护操作的工作内存
# WAL 配置
wal_level = replica # WAL日志级别
archive_mode = on # 启用归档
archive_command = 'cp %p /path/to/archive/%f' # 归档命令
# 查询优化
random_page_cost = 1.1 # 随机页面成本(SSD可降低)
effective_cache_size = 4GB # 有效缓存大小2.3 连接 PostgreSQL
命令行连接:
psql -h localhost -p 5432 -U postgres -d mydb常用连接参数:
-h:服务器地址(默认 localhost)-p:端口号(默认 5432)-U:用户名-d:数据库名
创建数据库和用户:
-- 创建用户
CREATE USER myuser WITH PASSWORD 'mypassword';
-- 创建数据库
CREATE DATABASE mydb OWNER myuser;
-- 授予权限
GRANT ALL PRIVILEGES ON DATABASE mydb TO myuser;三、基础概念
3.1 数据库对象层次
PostgreSQL 的对象层次结构:
服务器 (Server)
└── 数据库 (Database)
└── 模式 (Schema)
├── 表 (Table)
├── 视图 (View)
├── 函数 (Function)
└── 其他对象关键概念:
- 数据库:独立的数据集合,不同数据库间完全隔离
- 模式:数据库中的命名空间,用于组织数据库对象
- 表:数据的存储单元
- 列:表中的字段
3.2 常用数据类型
| 类别 | 类型 | 描述 | 示例 |
|---|---|---|---|
| 整数类型 | |||
SMALLINT | 2字节 | -32,768 到 32,767 | |
INTEGER | 4字节 | -2,147,483,648 到 2,147,483,647 | |
BIGINT | 8字节 | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 | |
| 浮点类型 | |||
REAL | 4字节 | 单精度浮点数 | |
DOUBLE PRECISION | 8字节 | 双精度浮点数 | |
NUMERIC(p,s) | 可变 | 精确小数,p=精度,s=小数位 | NUMERIC(10,2) |
| 字符串类型 | |||
VARCHAR(n) | 可变 | 变长字符串 | VARCHAR(255) |
TEXT | 可变 | 无长度限制的字符串 | |
CHAR(n) | 固定 | 定长字符串 | CHAR(10) |
| 日期时间类型 | |||
DATE | 4字节 | 日期 | 2023-08-15 |
TIME | 8字节 | 时间 | 14:30:00 |
TIMESTAMP | 8字节 | 日期时间 | 2023-08-15 14:30:00 |
TIMESTAMPTZ | 8字节 | 带时区的日期时间 | |
INTERVAL | 16字节 | 时间间隔 | 1 day 2 hours |
| 特殊类型 | |||
UUID | 16字节 | 通用唯一标识符 | a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 |
JSON/JSONB | 可变 | JSON 数据 | {"name": "John", "age": 30} |
ARRAY | 可变 | 数组 | {1,2,3} |
HSTORE | 可变 | 键值对 | "k1"=>"v1", "k2"=>"v2" |
3.3 约束
-- 主键约束
CREATE TABLE users (
id SERIAL PRIMARY KEY,
...
);
-- 唯一约束
CREATE TABLE users (
email VARCHAR(100) UNIQUE,
...
);
-- 非空约束
CREATE TABLE users (
username VARCHAR(50) NOT NULL,
...
);
-- 检查约束
CREATE TABLE products (
price NUMERIC CHECK (price > 0),
...
);
-- 外键约束
CREATE TABLE orders (
order_id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE
);四、SQL 基础操作
4.1 数据库与模式操作
-- 创建数据库
CREATE DATABASE mydb;
-- 创建模式
CREATE SCHEMA myschema;
-- 切换搜索路径(设置默认模式)
SET search_path TO myschema, public;
-- 删除模式(级联删除对象)
DROP SCHEMA myschema CASCADE;4.2 表操作
-- 创建表
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(100) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 查看表结构
\d users
-- 修改表(添加列)
ALTER TABLE users ADD COLUMN age SMALLINT;
-- 修改表(修改列)
ALTER TABLE users ALTER COLUMN age TYPE INTEGER;
-- 修改表(删除列)
ALTER TABLE users DROP COLUMN age;
-- 删除表
DROP TABLE users;4.3 插入数据
-- 插入单条记录
INSERT INTO users (username, email, password)
VALUES ('john', 'john@example.com', 'password123');
-- 插入多条记录
INSERT INTO users (username, email, password)
VALUES
('alice', 'alice@example.com', 'password123'),
('bob', 'bob@example.com', 'password123');
-- 插入查询结果
INSERT INTO active_users (user_id, username)
SELECT id, username FROM users WHERE status = 'active';
-- 返回插入的记录
INSERT INTO users (username, email, password)
VALUES ('charlie', 'charlie@example.com', 'password123')
RETURNING id, created_at;4.4 查询数据
-- 基本查询
SELECT * FROM users;
SELECT id, username, email FROM users;
-- 条件查询
SELECT * FROM users WHERE username = 'john';
SELECT * FROM users WHERE age > 18 AND status = 'active';
-- 排序
SELECT * FROM users ORDER BY created_at DESC;
SELECT * FROM users ORDER BY age ASC, username DESC;
-- 限制结果
SELECT * FROM users LIMIT 10; -- 前10条
SELECT * FROM users OFFSET 5 LIMIT 10; -- 从第6条开始,取10条(分页)4.5 更新数据
-- 更新单条记录
UPDATE users SET email = 'new@example.com' WHERE id = 1;
-- 更新多条记录
UPDATE users SET status = 'inactive' WHERE last_login < '2022-01-01';
-- 更新时使用表达式
UPDATE products SET price = price * 0.9 WHERE category = 'sale';
-- 返回更新的记录
UPDATE users SET last_login = CURRENT_TIMESTAMP
WHERE id = 1
RETURNING *;4.6 删除数据
-- 删除特定记录
DELETE FROM users WHERE id = 1;
-- 删除多条记录
DELETE FROM users WHERE last_login < '2022-01-01';
-- 返回删除的记录
DELETE FROM users WHERE id = 1 RETURNING *;五、高级查询
5.1 聚合函数
-- 计数
SELECT COUNT(*) AS total_users FROM users;
-- 求和
SELECT SUM(amount) AS total_sales FROM orders;
-- 平均值
SELECT AVG(age) AS average_age FROM users;
-- 最大值/最小值
SELECT MAX(created_at) AS latest_user, MIN(created_at) AS earliest_user
FROM users;
-- 分组统计
SELECT status, COUNT(*) AS count
FROM users
GROUP BY status;5.2 分组查询
-- 基本分组
SELECT department, COUNT(*) AS employee_count
FROM employees
GROUP BY department;
-- 分组过滤(HAVING)
SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department
HAVING AVG(salary) > 50000;
-- 多列分组
SELECT department, position, COUNT(*) AS count
FROM employees
GROUP BY department, position;5.3 多表连接查询
-- 内连接(INNER JOIN)
SELECT users.username, orders.order_id
FROM users
INNER JOIN orders ON users.id = orders.user_id;
-- 左连接(LEFT JOIN)
SELECT users.username, orders.order_id
FROM users
LEFT JOIN orders ON users.id = orders.user_id;
-- 右连接(RIGHT JOIN)
SELECT users.username, orders.order_id
FROM users
RIGHT JOIN orders ON users.id = orders.user_id;
-- 全连接(FULL JOIN)
SELECT users.username, orders.order_id
FROM users
FULL JOIN orders ON users.id = orders.user_id;
-- 多表连接
SELECT users.username, orders.order_id, products.name
FROM users
JOIN orders ON users.id = orders.user_id
JOIN order_items ON orders.id = order_items.order_id
JOIN products ON order_items.product_id = products.id;5.4 子查询
-- WHERE 子句中的子查询
SELECT * FROM users
WHERE id IN (SELECT user_id FROM orders WHERE amount > 1000);
-- FROM 子句中的子查询
SELECT u.username, o.total_orders
FROM users u
JOIN (
SELECT user_id, COUNT(*) AS total_orders
FROM orders
GROUP BY user_id
) o ON u.id = o.user_id;
-- SELECT 子句中的子查询
SELECT
username,
(SELECT COUNT(*) FROM orders WHERE user_id = users.id) AS order_count
FROM users;5.5 窗口函数
-- 排名函数
SELECT
username,
salary,
RANK() OVER (ORDER BY salary DESC) AS rank
FROM employees;
-- 分区排名
SELECT
department,
username,
salary,
RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS dept_rank
FROM employees;
-- 累计求和
SELECT
order_date,
amount,
SUM(amount) OVER (ORDER BY order_date) AS cumulative_sales
FROM orders;
-- 前后行访问
SELECT
order_date,
amount,
LAG(amount, 1, 0) OVER (ORDER BY order_date) AS prev_amount,
LEAD(amount, 1, 0) OVER (ORDER BY order_date) AS next_amount
FROM daily_sales;六、JSONB 与全文搜索
6.1 JSONB 数据类型
-- 创建包含 JSONB 字段的表
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
attributes JSONB
);
-- 插入 JSONB 数据
INSERT INTO products (name, attributes)
VALUES ('Laptop', '{"color": "silver", "ram": "16GB", "storage": "512GB"}');
-- 查询 JSONB 字段
SELECT * FROM products
WHERE attributes->>'color' = 'silver';
-- 使用 JSONB 操作符
SELECT * FROM products
WHERE attributes @> '{"ram": "16GB"}'; -- 包含操作符
-- 更新 JSONB 字段
UPDATE products
SET attributes = jsonb_set(attributes, '{price}', '999.99')
WHERE id = 1;
-- 创建 JSONB 索引
CREATE INDEX idx_products_attributes ON products USING GIN (attributes);6.2 全文搜索
-- 创建包含文本搜索字段的表
CREATE TABLE articles (
id SERIAL PRIMARY KEY,
title TEXT,
content TEXT,
ts_vector TSVECTOR
);
-- 创建 tsvector 字段
UPDATE articles SET ts_vector = to_tsvector('english', coalesce(title,'') || ' ' || coalesce(content,''));
-- 创建全文搜索索引
CREATE INDEX idx_articles_tsvector ON articles USING GIN(ts_vector);
-- 执行全文搜索
SELECT id, title
FROM articles
WHERE ts_vector @@ to_tsquery('english', 'database & performance');
-- 带权重的全文搜索
SELECT id, title,
ts_rank(ts_vector, query) AS rank
FROM articles,
to_tsquery('english', 'database & performance') query
WHERE ts_vector @@ query
ORDER BY rank DESC;
-- 高亮显示匹配内容
SELECT id, title,
ts_headline('english', content, query, 'StartSel=<b>, StopSel=</b>') AS highlight
FROM articles,
to_tsquery('english', 'database & performance') query
WHERE ts_vector @@ query;七、索引与性能优化
7.1 常见索引类型
| 类型 | 描述 | 适用场景 |
|---|---|---|
| B-tree | 默认索引类型 | 等值查询、范围查询、排序 |
| Hash | 哈希索引 | 等值查询(不支持范围查询) |
| GIN | 通用 inverted index | JSONB、数组、全文搜索 |
| GiST | 通用搜索树 | 地理空间数据、全文搜索 |
| BRIN | 块范围索引 | 大型表,数据有序 |
7.2 索引操作
-- 创建索引
CREATE INDEX idx_username ON users(username);
-- 创建唯一索引
CREATE UNIQUE INDEX idx_email ON users(email);
-- 创建组合索引
CREATE INDEX idx_name_status ON users(username, status);
-- 创建部分索引
CREATE INDEX idx_active_users ON users(username) WHERE status = 'active';
-- 创建 JSONB 索引
CREATE INDEX idx_products_attributes ON products USING GIN (attributes);
-- 删除索引
DROP INDEX idx_username;7.3 查询优化技巧
**避免 SELECT ***
-- 不推荐 SELECT * FROM users; -- 推荐 SELECT id, username, email FROM users;合理使用 LIMIT
-- 分页查询优化 SELECT * FROM large_table ORDER BY id LIMIT 10000, 20; -- 优化为 SELECT * FROM large_table WHERE id > 10000 ORDER BY id LIMIT 20;避免在 WHERE 子句中对字段进行表达式操作
-- 不推荐(无法使用索引) SELECT * FROM users WHERE EXTRACT(YEAR FROM created_at) = 2023; -- 推荐 SELECT * FROM users WHERE created_at >= '2023-01-01' AND created_at < '2024-01-01';使用 EXPLAIN 分析查询
EXPLAIN ANALYZE SELECT * FROM users WHERE username = 'john';利用覆盖索引
-- 创建覆盖索引 CREATE INDEX idx_covering ON users(username, email); -- 查询只使用索引中的字段 SELECT username, email FROM users WHERE username = 'john';
八、事务与锁
8.1 事务基础
事务是什么:事务是一系列操作的集合,这些操作要么全部成功,要么全部失败。
ACID 特性:
- Atomicity(原子性):事务是一个不可分割的工作单位
- Consistency(一致性):事务必须使数据库从一个一致性状态变换到另一个一致性状态
- Isolation(隔离性):并发事务之间的操作互不干扰
- Durability(持久性):事务一旦提交,它对数据库的改变是永久的
8.2 事务控制语句
-- 开始事务
BEGIN;
-- 提交事务
COMMIT;
-- 回滚事务
ROLLBACK;
-- 保存点
SAVEPOINT point1;
-- 回滚到保存点
ROLLBACK TO point1;8.3 事务隔离级别
| 隔离级别 | 脏读 | 不可重复读 | 幻读 | 说明 |
|---|---|---|---|---|
| READ UNCOMMITTED | ✓ | ✓ | ✓ | 最低隔离级别,性能最好 |
| READ COMMITTED | ✗ | ✓ | ✓ | PostgreSQL 默认级别 |
| REPEATABLE READ | ✗ | ✗ | ✓ | 避免不可重复读 |
| SERIALIZABLE | ✗ | ✗ | ✗ | 最高隔离级别,性能最差 |
设置隔离级别:
-- 查看当前隔离级别
SHOW transaction_isolation;
-- 设置会话级别隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
-- 设置事务隔离级别
BEGIN TRANSACTION ISOLATION LEVEL READ COMMITTED;
-- 执行操作
COMMIT;8.4 锁机制
-- 显示当前锁
SELECT * FROM pg_locks;
-- 查看锁等待
SELECT blocked_locks.pid AS blocked_pid,
blocking_locks.pid AS blocking_pid,
blocked_activity.usename AS blocked_user,
blocking_activity.usename AS blocking_user,
blocked_activity.query AS blocked_statement,
blocking_activity.query AS current_statement_in_blocking_process
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;九、常用函数
9.1 字符串函数
-- 字符串拼接
SELECT 'Hello' || ' ' || 'PostgreSQL'; -- 'Hello PostgreSQL'
-- 大小写转换
SELECT UPPER('hello'); -- 'HELLO'
SELECT LOWER('HELLO'); -- 'hello'
-- 字符串长度
SELECT LENGTH('PostgreSQL'); -- 10
SELECT CHAR_LENGTH('你好'); -- 2
-- 子字符串
SELECT SUBSTRING('Hello PostgreSQL' FROM 1 FOR 5); -- 'Hello'
-- 填充
SELECT LPAD('1', 3, '0'); -- '001'
SELECT RPAD('1', 3, '0'); -- '100'
-- 去除空格
SELECT TRIM(' PostgreSQL '); -- 'PostgreSQL'
-- 正则表达式
SELECT REGEXP_REPLACE('123-456-7890', '[^0-9]', '', 'g'); -- '1234567890'9.2 数值函数
-- 向上取整
SELECT CEIL(1.1); -- 2
-- 向下取整
SELECT FLOOR(1.9); -- 1
-- 四舍五入
SELECT ROUND(2.344, 2); -- 2.34
-- 随机数
SELECT RANDOM(); -- 0到1之间的随机数
-- 绝对值
SELECT ABS(-10); -- 10
-- 幂运算
SELECT POWER(2, 3); -- 8
-- 对数
SELECT LN(10); -- 2.3025850929940469.3 日期函数
-- 当前日期时间
SELECT NOW(); -- '2023-08-15 14:30:00.123456+08'
-- 当前日期
SELECT CURRENT_DATE; -- '2023-08-15'
-- 当前时间
SELECT CURRENT_TIME; -- '14:30:00.123456+08'
-- 日期格式化
SELECT TO_CHAR(NOW(), 'YYYY-MM-DD HH24:MI:SS'); -- '2023-08-15 14:30:00'
-- 日期加减
SELECT NOW() + INTERVAL '1 day'; -- 明天
SELECT NOW() - INTERVAL '1 month'; -- 上个月
-- 日期差
SELECT AGE('2023-12-31', '2023-01-01'); -- '11 mons 30 days'9.4 JSON 函数
-- 创建 JSON 对象
SELECT JSON_BUILD_OBJECT('name', 'John', 'age', 30);
-- {"name": "John", "age": 30}
-- 创建 JSON 数组
SELECT JSON_BUILD_ARRAY('a', 'b', 1, 2);
-- ["a", "b", 1, 2]
-- JSON 转换
SELECT JSONB_SET('{"name": "John"}', '{age}', '30');
-- {"name": "John", "age": 30}
-- JSON 查询
SELECT '{"name": "John", "age": 30}'::jsonb->>'name'; -- 'John'
SELECT '{"name": "John", "age": 30}'::jsonb->'age'; -- 30十、最佳实践
10.1 表设计规范
命名规范
- 数据库名、表名、字段名使用小写字母
- 使用下划线分隔单词(如
user_info) - 避免使用 PostgreSQL 保留字
字段选择
- 选择合适的数据类型,优先选择更小的数据类型
- 为字段设置合适的长度
- 为经常查询的字段建立索引
- 为外键字段建立索引
主键设计
- 每个表都应该有一个主键
- 优先考虑使用
SERIAL或BIGSERIAL - 避免使用业务相关的字段作为主键
UUID 主键
-- 需要先创建扩展 CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; CREATE TABLE users ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), ... );
10.2 查询优化技巧
索引使用原则
- 为 WHERE 子句中的条件字段创建索引
- 为 ORDER BY 和 GROUP BY 字段创建索引
- 避免在索引列上使用函数或表达式
- 选择性高的列更适合创建索引
避免全表扫描
- 确保查询条件能有效利用索引
- 限制返回的字段数量
- 合理使用 LIMIT
优化 JOIN 操作
- 确保 JOIN 条件字段有索引
- 小表驱动大表
- 避免多表 JOIN
使用物化视图
-- 创建物化视图 CREATE MATERIALIZED VIEW user_summary AS SELECT department, COUNT(*) AS user_count FROM users GROUP BY department; -- 刷新物化视图 REFRESH MATERIALIZED VIEW user_summary;
10.3 安全注意事项
权限管理
- 为不同应用创建不同的数据库用户
- 遵循最小权限原则
- 定期审查用户权限
防止 SQL 注入
- 使用参数化查询
- 避免拼接 SQL 语句
- 对用户输入进行验证和过滤
备份策略
- 定期进行全量备份(
pg_dump) - 结合 WAL 归档进行增量备份
- 测试备份恢复流程
- 定期进行全量备份(
十一、扩展与集成
11.1 常用扩展
-- 创建 UUID 扩展
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- 创建 pgcrypto 扩展(加密函数)
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
-- 创建 PostGIS 扩展(地理空间数据)
CREATE EXTENSION IF NOT EXISTS "postgis";
-- 创建 pgvector 扩展(向量搜索)
CREATE EXTENSION IF NOT EXISTS "vector";11.2 与应用程序集成
Java (JDBC):
String url = "jdbc:postgresql://localhost:5432/mydb";
String user = "myuser";
String password = "mypass";
try (Connection conn = DriverManager.getConnection(url, user, password)) {
String sql = "SELECT * FROM users WHERE username = ?";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, "john");
try (ResultSet rs = pstmt.executeQuery()) {
while (rs.next()) {
System.out.println(rs.getString("email"));
}
}
}
}Python (psycopg2):
import psycopg2
conn = psycopg2.connect(
host="localhost",
database="mydb",
user="myuser",
password="mypass"
)
cur = conn.cursor()
cur.execute("SELECT * FROM users WHERE username = %s", ("john",))
rows = cur.fetchall()
for row in rows:
print(row)
cur.close()
conn.close()Node.js (pg):
const { Pool } = require('pg');
const pool = new Pool({
user: 'myuser',
host: 'localhost',
database: 'mydb',
password: 'mypass',
port: 5432,
});
async function getUsers() {
const client = await pool.connect();
try {
const res = await client.query('SELECT * FROM users WHERE username = $1', ['john']);
console.log(res.rows);
} finally {
client.release();
}
}
getUsers();