1. 首页 > PostgreSQL教程 > 正文

PostgreSQL教程FG138-PG大对象实战:文件上传与存储实现

本文档风哥主要介绍PostgreSQL数据库大对象的实战应用,包括文件上传与存储实现、大对象管理、性能优化等内容,风哥教程参考PostgreSQL官方文档Large
Objects内容编写,适合DBA人员和开发人员在学习和测试中使用,如果要应用于生产环境则需要自行确认。

Part01-基础概念与理论知识

1.1 PostgreSQL数据库大对象概念

PostgreSQL数据库大对象(Large
Objects)是一种用于存储大型二进制数据的机制,支持存储超过1GB的文件。大对象提供了流式访问接口,适合存储图片、视频、文档等大型文件。更多视频教程www.fgedu.net.cn

PostgreSQL数据库大对象的特点:

  • 支持存储大型二进制数据(最大可达4TB)
  • 提供流式读写接口
  • 支持事务性操作
  • 存储在专用的系统表中
  • 可以通过OID(对象标识符)引用

1.2 PostgreSQL数据库大对象存储原理

PostgreSQL数据库大对象的存储原理:

  • 存储位置:大对象数据存储在pg_largeobject系统表中
  • 存储方式:数据被分割成固定大小的块(默认2048字节)
  • 元数据:大对象的元数据存储在pg_largeobject_metadata表中
  • 访问方式:通过OID进行引用和访问

1.3 PostgreSQL数据库大对象适用场景

PostgreSQL数据库大对象的适用场景:

# 适用场景
– 存储大型图片和视频文件
– 存储文档和PDF文件
– 存储科学数据和实验结果
– 存储任何超过字段大小限制的二进制数据
– 需要事务支持的文件存储

# 不适用场景
– 频繁访问的小文件(建议使用普通字段)
– 需要文件系统特性的场景
– 需要高并发访问的场景

Part02-生产环境规划与建议

2.1 PostgreSQL数据库大对象存储规划

生产环境中,大对象存储规划建议:

# 存储规划
– 为大对象创建专用表空间
– 考虑使用SSD存储提高性能
– 估计存储空间需求,预留足够空间
– 制定数据清理策略

# 表空间规划
CREATE TABLESPACE lobs_ts LOCATION ‘/postgresql/fgdata/lobs’;

# 大对象表规划
CREATE TABLE fgedu_files (
file_id SERIAL PRIMARY KEY,
file_name VARCHAR(255) NOT NULL,
file_size BIGINT NOT NULL,
file_type VARCHAR(100) NOT NULL,
lob_oid OID NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) TABLESPACE lobs_ts;

2.2 PostgreSQL数据库大对象性能考虑

性能考虑:

  • 读写性能:大对象读写可能较慢,建议使用预读和缓存
  • 事务处理:大对象操作会产生大量WAL日志
  • 备份影响:大对象会增加备份大小和时间
  • 并发访问:大对象不适合高并发场景

2.3 PostgreSQL数据库大对象安全考虑

安全考虑:

风哥教程针对风哥教程针对风哥教程针对生产环境建议:为大对象创建专用表空间,制定合理的存储和清理策略,考虑性能和安全因素。学习交流加群风哥微信: itpux-com

Part03-生产环境项目实施方案

3.1 PostgreSQL数据库大对象管理

3.1.1 PostgreSQL数据库创建和管理大对象

$ psql -U pgsql -d fgedudb

# 创建大对象
SELECT lo_create(0);

# 删除大对象
SELECT lo_unlink(12345);

# 查看大对象信息
SELECT * FROM pg_largeobject_metadata;

# 查看大对象数据块
SELECT * FROM pg_largeobject WHERE loid = 12345;

— 执行结果
lo_create
———–
16384
(1 row)

— 删除大对象
lo_unlink
———–
1
(1 row)

— 查看大对象元数据
oid | owner | size | creation
——-+—————-+————–+————
16384 | pgsql | 1048576 | 2026-04-02
(1 row)

3.2 PostgreSQL数据库文件上传实现

3.2.1 PostgreSQL数据库使用psql上传文件

# 上传文件到大对象
\lo_import ‘/path/to/file.jpg’

# 查看上传的大对象
SELECT oid, size FROM pg_largeobject_metadata;

# 导出大对象到文件
\lo_export 16384 ‘/path/to/output.jpg’

— 执行结果
lo_import 16384

oid | size
——-+——–
16384 | 1024000
(1 row)

lo_export

3.2.2 PostgreSQL数据库使用PL/pgSQL处理大对象

# 创建大对象处理函数
CREATE OR REPLACE FUNCTION fgedu_upload_file(p_file_path text, p_file_name text)
RETURNS OID AS $$
DECLARE
l_oid OID;
l_fd INTEGER;
l_buf BYTEA;
l_file TEXT;
BEGIN
— 读取文件内容
l_file := pg_read_file(p_file_path, 0, 1000000000);

— 创建大对象
l_oid := lo_create(0);

— 打开大对象进行写入
l_fd := lo_open(l_oid, 131072); — 131072 = WRITE flag

— 写入数据
lo_write(l_fd, l_file);

— 关闭大对象
PERFORM lo_close(l_fd);

— 记录文件信息
INSERT INTO fgedu_files (file_name, file_size, file_type, lob_oid)
VALUES (p_file_name, length(l_file), substring(p_file_name from ‘\.[^.]+$’), l_oid);

RETURN l_oid;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

# 调用函数上传文件
SELECT fgedu_upload_file(‘/path/to/file.pdf’, ‘document.pdf’);

— 执行结果
fgedu_upload_file
——————-
16385
(1 row)

— 查看文件信息
SELECT * FROM fgedu_files;

file_id | file_name | file_size | file_type | lob_oid | created_at
———+————–+———–+———–+———+—————————-
1 | document.pdf | 512000 | .pdf | 16385 | 2026-04-02 10:00:00.000000
(1 row)

3.3 PostgreSQL数据库大对象操作

3.3.1 PostgreSQL数据库大对象读写操作

# 读取大对象内容
CREATE OR REPLACE FUNCTION fgedu_read_lob(p_oid OID)
RETURNS BYTEA AS $$
DECLARE
l_fd INTEGER;
l_data BYTEA;
l_buf BYTEA;
l_len INTEGER;
BEGIN
— 打开大对象进行读取
l_fd := lo_open(p_oid, 262144); — 262144 = READ flag

— 读取数据
l_data := ”;
LOOP
l_buf := loread(l_fd, 8192);
EXIT WHEN length(l_buf) = 0;
l_data := l_data || l_buf;
END LOOP;

— 关闭大对象
PERFORM lo_close(l_fd);

RETURN l_data;
END;
$$ LANGUAGE plpgsql;

# 写入大对象内容
CREATE OR REPLACE FUNCTION fgedu_write_lob(p_oid OID, p_data BYTEA)
RETURNS INTEGER AS $$
DECLARE
l_fd INTEGER;
l_len INTEGER;
BEGIN
— 打开大对象进行写入
l_fd := lo_open(p_oid, 131072); — 131072 = WRITE flag

— 写入数据
l_len := lo_write(l_fd, p_data);

— 关闭大对象
PERFORM lo_close(l_fd);

RETURN l_len;
END;
$$ LANGUAGE plpgsql;

风哥提示:大对象操作需要注意事务管理,确保数据的一致性和完整性。建议在事务中执行大对象的创建、读写和删除操作。学习交流加群风哥QQ113257174

Part04-生产案例与实战讲解

4.1 PostgreSQL数据库文件上传系统实现

#!/bin/bash
# file_upload.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: `http://www.fgedu.net.cn`

# 文件上传脚本

# 数据库连接信息
DB_HOST=”localfgedu.net.cn”
DB_PORT=”5432″
DB_NAME=”fgedudb”
DB_USER=”pgsql”

# 上传文件
upload_file() {
local file_path=$1
local file_name=$2

# 检查文件是否存在
if [ ! -f “$file_path” ]; then
echo “文件不存在: $file_path”
return 1
fi

# 获取文件大小
file_size=$(stat -c “%s” “$file_path”)

# 获取文件类型
file_type=$(echo “$file_name” | grep -o “\.[^.]*$”)

# 上传文件到PostgreSQL
result=$(psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME -t -c ”
SELECT lo_import(‘$file_path’);
“)

# 提取OID
oid=$(echo $result | tr -d ‘ ‘)

if [ -z “$oid” ]; then
echo “上传失败”
return 1
fi

# 记录文件信息
psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME -c ”
INSERT INTO fgedu_files (file_name, file_size, file_type, lob_oid)
VALUES (‘$file_name’, $file_size, ‘$file_type’, $oid);

echo “文件上传成功,OID: $oid”
return 0
}

# 下载文件
download_file() {
local file_id=$1
local output_path=$2

# 获取大对象OID
oid=$(psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME -t -c ”
SELECT lob_oid FROM fgedu_files WHERE file_id = $file_id;
” | tr -d ‘ ‘)

if [ -z “$oid” ]; then
echo “文件不存在”
return 1
fi

# 导出大对象
psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME -c “\lo_export $oid ‘$output_path'”

echo “文件下载成功: $output_path”
return 0
}

# 主菜单
echo “PostgreSQL文件上传系统”
echo “1. 上传文件”
echo “2. 下载文件”
echo “3. 列出文件”
echo “4. 退出”

read -p “请选择操作: ” choice

case $choice in
1)
read -p “请输入文件路径: ” file_path
read -p “请输入文件名: ” file_name
upload_file “$file_path” “$file_name”
;;
2)
read -p “请输入文件ID: ” file_id
read -p “请输入输出路径: ” output_path
download_file “$file_id” “$output_path”
;;
3)
psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME -c ”
SELECT file_id, file_name, file_size, file_type, created_at
FROM fgedu_files
ORDER BY created_at DESC;

;;
4)
echo “退出系统”
exit 0
;;
*)
echo “无效选择”
;;
esac

# 执行脚本
$ chmod +x file_upload.sh
$ ./file_upload.sh

# 执行结果
PostgreSQL文件上传系统
1. 上传文件
2. 下载文件
3. 列出文件
4. 退出
请选择操作: 1
请输入文件路径: /home/fgedu/document.pdf
请输入文件名: report.pdf
文件上传成功,OID: 16386

$ ./file_upload.sh
PostgreSQL文件上传系统
1. 上传文件
2. 下载文件
3. 列出文件
4. 退出
请选择操作: 3
file_id | file_name | file_size | file_type | created_at
———+————–+———–+———–+—————————-
2 | report.pdf | 768000 | .pdf | 2026-04-02 10:30:00.000000
1 | document.pdf | 512000 | .pdf | 2026-04-02 10:00:00.000000
(2 rows)

4.2 PostgreSQL数据库大对象备份与恢复

大对象的备份与恢复:

# 使用pg_dump备份包含大对象的数据库
pg_dump -h localfgedu.net.cn -p 5432 -U pgsql -d fgedudb -F c -f fgedudb_backup.dump

# 使用pg_restore恢复数据库
pg_restore -h localfgedu.net.cn -p 5432 -U pgsql -d fgedudb fgedudb_backup.dump

# 单独备份大对象
pg_dump -h localfgedu.net.cn -p 5432 -U pgsql -d fgedudb -t pg_largeobject -t pg_largeobject_metadata -F c -f
lobs_backup.dump

# 恢复大对象
pg_restore -h localfgedu.net.cn -p 5432 -U pgsql -d fgedudb lobs_backup.dump

4.3 PostgreSQL数据库大对象性能优化

大对象性能优化策略:

# 性能优化策略

## 1. 存储优化
– 使用专用表空间存储大对象
– 考虑使用SSD存储
– 合理设置表空间参数

## 2. 读写优化
– 使用较大的缓冲区大小
– 实现流式读写
– 避免频繁的小数据读写

## 3. 索引优化
– 为fgedu_files表创建适当的索引
– 优化查询语句

## 4. 配置优化
– 调整shared_buffers参数
– 优化work_mem参数
– 配置适当的maintenance_work_mem

# 具体优化措施
CREATE INDEX idx_fgedu_files_created_at ON fgedu_files(created_at);
CREATE INDEX idx_fgedu_files_file_type ON fgedu_files(file_type);

— 优化查询
EXPLAIN ANALYZE SELECT * FROM fgedu_files WHERE file_type = ‘.pdf’ ORDER BY created_at DESC;

— 执行结果
QUERY PLAN
—————————————————————————————————————————-
Sort (cost=18.70..19.20 rows=200 width=104) (actual time=0.032..0.033 rows=2 loops=1)
Sort Key: created_at DESC
Sort Method: quicksort Memory: 25kB
-> Bitmap Heap Scan on fgedu_files (cost=4.30..17.50 rows=200 width=104) (actual time=0.018..0.021 rows=2
loops=1)
Recheck Cond: (file_type = ‘.pdf’::text)
Heap Blocks: exact=1
-> Bitmap Index Scan on idx_fgedu_files_file_type (cost=0.00..4.25 rows=200 width=0) (actual
time=0.012..0.012 rows=2 loops=1)
Index Cond: (file_type = ‘.pdf’::text)
Planning Time: 0.107 ms
Execution Time: 0.056 ms
(10 rows)
风哥教程针对风哥教程针对风哥教程针对生产环境建议:定期清理不再使用的大对象,优化存储结构,监控大对象的使用情况,及时调整配置参数。更多学习教程公众号风哥教程itpux_com

Part05-风哥经验总结与分享

5.1 PostgreSQL数据库大对象管理最佳实践

PostgreSQL数据库大对象管理最佳实践:

  • 使用专用表空间:为大对象创建独立的表空间
  • 建立元数据表:创建专门的表存储大对象的元数据
  • 定期清理:删除不再使用的大对象
  • 备份策略:制定合理的备份策略
  • 性能监控:监控大对象的读写性能
  • 权限控制:严格控制大对象的访问权限
风哥提示:大对象管理需要平衡存储成本和性能需求,建议根据实际业务场景选择合适的存储方案。from PostgreSQL视频:www.itpux.com

5.2 PostgreSQL数据库大对象问题排查

# 常见大对象问题排查

## 1. 大对象损坏
– 检查大对象完整性:SELECT lo_manage(oid) FROM pg_largeobject_metadata;
– 重建损坏的大对象:使用备份恢复

## 2. 性能问题
– 检查大对象大小:SELECT oid, size FROM pg_largeobject_metadata ORDER BY size DESC;
– 分析查询执行计划:EXPLAIN ANALYZE 查询语句
– 监控I/O性能:使用iostat等工具

## 3. 存储空间问题
– 检查大对象占用空间:SELECT pg_size_pretty(pg_total_relation_size(‘pg_largeobject’));
– 清理未使用的大对象:DELETE FROM pg_largeobject WHERE loid NOT IN (SELECT lob_oid FROM fgedu_files);

## 4. 权限问题
– 检查大对象权限:SELECT * FROM information_schema.role_table_grants WHERE table_name = ‘pg_largeobject’;
– 授予必要的权限:GRANT SELECT ON pg_largeobject TO fgedu;

5.3 PostgreSQL数据库大对象工具推荐

PostgreSQL数据库大对象工具:

  • psql:使用\lo_import和\lo_export命令
  • libpq:使用C语言API操作大对象
  • PL/pgSQL:使用lo_*函数操作大对象
  • pgAdmin:图形化管理大对象
  • 自定义脚本:如本文中的文件上传脚本
持续改进:大对象管理是一个持续的过程,需要根据业务需求和系统性能不断优化。建议建立大对象管理的规范和流程,定期review和改进。

本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html

联系我们

在线咨询:点击这里给我发消息

微信号:itpux-com

工作日:9:30-18:30,节假日休息