1. 首页 > PostgreSQL教程 > 正文

PostgreSQL教程FG132-PG大对象适用场景:文件/大二进制数据存储

本文档风哥主要介绍PostgreSQL大对象的适用场景,包括文件存储、二进制数据存储等实际应用场景,风哥教程参考PostgreSQL官方文档,适合开发人员和DBA在学习和测试中使用。

更多视频教程www.fgedu.net.cn

Part01-基础概念与理论知识

1.1 大对象适用场景概述

PostgreSQL大对象适用于需要存储大型二进制数据的场景,最大支持4TB的数据存储。以下是主要的适用场景:

大对象适用场景:

  • 文档管理:PDF、Word、Excel等办公文档
  • 媒体文件:图片、音频、视频等多媒体文件
  • 备份数据:数据库备份、日志文件等
  • 二进制数据:序列化对象、加密数据等
  • 科学数据:实验数据、观测数据等

1.2 文件存储场景

文件存储是大对象最常见的应用场景之一:

— 文件存储场景示例

— 1. 文档管理系统
— 适用:企业文档、合同、报告等
— 优势:统一管理、版本控制、权限控制

— 2. 内容管理系统(CMS)
— 适用:网站内容、文章附件、用户上传文件
— 优势:与元数据关联、全文检索支持

— 3. 电子邮件系统
— 适用:邮件附件存储
— 优势:事务支持、备份恢复方便

— 4. 电子档案系统
— 适用:扫描文档、电子档案
— 优势:长期保存、安全可靠

1.3 二进制数据存储场景

二进制数据存储场景:

— 二进制数据存储场景

— 1. 序列化对象存储
— 适用:Java对象、Python对象等序列化数据
— 优势:保持对象完整性、支持复杂数据结构

— 2. 加密数据存储
— 适用:敏感信息、加密文件
— 优势:与数据库安全机制集成

— 3. 压缩数据存储
— 适用:压缩日志、压缩备份
— 优势:节省存储空间

— 4. 科学数据存储
— 适用:实验数据、观测数据、传感器数据
— 优势:支持大容量、支持随机访问

风哥提示:选择大对象存储方案时,需要综合考虑数据大小、访问模式、性能要求等因素,选择最适合的存储方式。学习交流加群风哥微信: itpux-com

Part02-生产环境规划与建议

2.1 文档管理系统

文档管理系统是大对象的典型应用场景:

— 文档管理系统设计

— 1. 文档表设计
CREATE TABLE fgedu_documents (
id SERIAL PRIMARY KEY,
document_name VARCHAR(255) NOT NULL,
document_type VARCHAR(50) NOT NULL,
file_size BIGINT NOT NULL,
file_data OID NOT NULL,
category_id INTEGER REFERENCES fgedu_categories(id),
department_id INTEGER REFERENCES fgedu_departments(id),
created_by INTEGER REFERENCES fgedu_fgedus(id),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
version INTEGER DEFAULT 1,
status VARCHAR(20) DEFAULT ‘active’
);

— 2. 文档版本表
CREATE TABLE fgedu_document_versions (
id SERIAL PRIMARY KEY,
document_id INTEGER REFERENCES fgedu_documents(id),
version INTEGER NOT NULL,
file_data OID NOT NULL,
change_description TEXT,
created_by INTEGER REFERENCES fgedu_fgedus(id),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

— 3. 文档权限表
CREATE TABLE fgedu_document_permissions (
id SERIAL PRIMARY KEY,
document_id INTEGER REFERENCES fgedu_documents(id),
fgedu_id INTEGER REFERENCES fgedu_fgedus(id),
permission_type VARCHAR(20) NOT NULL, — read, write, delete
granted_by INTEGER REFERENCES fgedu_fgedus(id),
granted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

— 4. 触发器:自动管理大对象
CREATE OR REPLACE FUNCTION manage_document_large_object()
RETURNS TRIGGER AS $$
BEGIN
IF TG_OP = ‘DELETE’ THEN
— 删除旧版本的大对象
IF OLD.file_data IS NOT NULL THEN
PERFORM lo_unlink(OLD.file_data);
END IF;
RETURN OLD;
ELSIF TG_OP = ‘UPDATE’ THEN
— 如果文件数据变更,删除旧的大对象
IF OLD.file_data IS NOT NULL AND OLD.file_data != NEW.file_data THEN
PERFORM lo_unlink(OLD.file_data);
END IF;
RETURN NEW;
END IF;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_manage_document_large_object
BEFORE DELETE OR UPDATE ON fgedu_documents
FOR EACH ROW
EXECUTE FUNCTION manage_document_large_object();

2.2 媒体文件存储

媒体文件存储场景:

— 媒体文件存储设计

— 1. 媒体文件表
CREATE TABLE fgedu_media_files (
id SERIAL PRIMARY KEY,
file_name VARCHAR(255) NOT NULL,
original_name VARCHAR(255) NOT NULL,
file_type VARCHAR(50) NOT NULL, — image, video, audio
mime_type VARCHAR(100) NOT NULL,
file_size BIGINT NOT NULL,
file_data OID NOT NULL,
width INTEGER, — 图片/视频宽度
height INTEGER, — 图片/视频高度
duration INTEGER, — 音视频时长(秒)
thumbnail_oid OID, — 缩略图
uploaded_by INTEGER REFERENCES fgedu_fgedus(id),
uploaded_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
download_count INTEGER DEFAULT 0,
status VARCHAR(20) DEFAULT ‘active’
);

— 2. 媒体分类表
CREATE TABLE fgedu_media_categories (
id SERIAL PRIMARY KEY,
category_name VARCHAR(100) NOT NULL,
parent_id INTEGER REFERENCES fgedu_media_categories(id),
description TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

— 3. 媒体标签表
CREATE TABLE fgedu_media_tags (
id SERIAL PRIMARY KEY,
tag_name VARCHAR(50) NOT NULL UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

— 4. 媒体文件标签关联表
CREATE TABLE fgedu_media_file_tags (
media_id INTEGER REFERENCES fgedu_media_files(id),
tag_id INTEGER REFERENCES fgedu_media_tags(id),
PRIMARY KEY (media_id, tag_id)
);

— 5. 查询媒体文件
SELECT
m.id,
m.file_name,
m.file_type,
m.mime_type,
pg_size_pretty(m.file_size) as file_size,
m.width,
m.height,
m.duration,
m.uploaded_at,
u.fgeduname as uploaded_by
FROM fgedu_media_files m
JOIN fgedu_fgedus u ON m.uploaded_by = u.id
WHERE m.file_type = ‘image’
AND m.status = ‘active’
ORDER BY m.uploaded_at DESC
LIMIT 20;

2.3 备份数据存储

备份数据存储场景:

from oracle:www.itpux.com

— 备份数据存储设计

— 1. 备份记录表
CREATE TABLE fgedu_backup_records (
id SERIAL PRIMARY KEY,
backup_name VARCHAR(255) NOT NULL,
backup_type VARCHAR(50) NOT NULL, — full, incremental, differential
fgedudb_name VARCHAR(100) NOT NULL,
file_size BIGINT NOT NULL,
file_data OID NOT NULL,
compression_ratio NUMERIC(5,2),
backup_start_time TIMESTAMP NOT NULL,
backup_end_time TIMESTAMP,
duration_seconds INTEGER,
status VARCHAR(20) DEFAULT ‘running’, — running, completed, failed
error_message TEXT,
created_by INTEGER REFERENCES fgedu_fgedus(id),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

— 2. 备份策略表
CREATE TABLE fgedu_backup_policies (
id SERIAL PRIMARY KEY,
policy_name VARCHAR(100) NOT NULL,
fgedudb_name VARCHAR(100) NOT NULL,
backup_type VARCHAR(50) NOT NULL,
schedule_cron VARCHAR(100) NOT NULL, — cron表达式
retention_days INTEGER NOT NULL,
compression_enabled BOOLEAN DEFAULT true,
encryption_enabled BOOLEAN DEFAULT false,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

— 3. 查询备份记录
SELECT
id,
backup_name,
backup_type,
fgedudb_name,
pg_size_pretty(file_size) as file_size,
compression_ratio,
backup_start_time,
backup_end_time,
duration_seconds,
status
FROM fgedu_backup_records
WHERE fgedudb_name = ‘fgedudb’
AND status = ‘completed’
ORDER BY backup_start_time DESC
LIMIT 10;

风哥教程针对风哥教程针对风哥教程针对生产环境建议:在生产环境中使用大对象存储文件时,建议建立完善的元数据管理机制,包括文件分类、版本控制、权限管理等,以提高系统的可维护性和安全性。学习交流加群风哥QQ113257174

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

3.1 实施策略

3.1.1 存储策略选择

— 存储策略选择

— 1. 小文件存储策略(< 1MB) -- 使用BYTEA类型 CREATE TABLE fgedu_small_files ( id SERIAL PRIMARY KEY, file_name VARCHAR(255) NOT NULL, file_data BYTEA NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- 2. 中等文件存储策略(1MB - 100MB) -- 使用OID大对象 CREATE TABLE fgedu_medium_files ( id SERIAL PRIMARY KEY, file_name VARCHAR(255) NOT NULL, file_size BIGINT NOT NULL, file_data OID NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- 3. 大文件存储策略(> 100MB)
— 使用OID大对象 + 分块存储
CREATE TABLE fgedu_large_files (
id SERIAL PRIMARY KEY,
file_name VARCHAR(255) NOT NULL,
file_size BIGINT NOT NULL,
chunk_size INTEGER DEFAULT 10485760, — 10MB
chunk_count INTEGER NOT NULL,
file_data OID NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

— 4. 混合存储策略
— 根据文件大小自动选择存储方式
CREATE OR REPLACE FUNCTION store_file(
p_file_name VARCHAR,
p_file_data BYTEA
) RETURNS INTEGER AS $$
DECLARE
v_file_size INTEGER;
v_file_id INTEGER;
v_oid OID;
BEGIN
v_file_size := LENGTH(p_file_data);

IF v_file_size < 1048576 THEN -- 小文件:使用BYTEA INSERT INTO fgedu_small_files (file_name, file_data) VALUES (p_file_name, p_file_data) RETURNING id INTO v_file_id; ELSIF v_file_size < 104857600 THEN -- 中等文件:使用OID v_oid := lo_create(0); -- 写入大对象数据... INSERT INTO fgedu_medium_files (file_name, file_size, file_data) VALUES (p_file_name, v_file_size, v_oid) RETURNING id INTO v_file_id; ELSE -- 大文件:使用OID + 分块 v_oid := lo_create(0); -- 分块写入大对象数据... INSERT INTO fgedu_large_files (file_name, file_size, chunk_count, file_data) VALUES (p_file_name, v_file_size, CEIL(v_file_size::NUMERIC / 10485760), v_oid) RETURNING id INTO v_file_id; END IF; RETURN v_file_id; END; $$ LANGUAGE plpgsql;

3.2 性能考虑

3.2.1 读取性能优化

— 读取性能优化

— 1. 使用流式读取
— 避免一次性加载大对象到内存

— 2. 缓存热点数据
— 使用Redis或Memcached缓存频繁访问的文件

— 3. 数据库参数优化
— 增加shared_buffers
ALTER SYSTEM SET shared_buffers = ‘2GB’;

— 增加work_mem
ALTER SYSTEM SET work_mem = ‘256MB’;

— 4. 使用CDN加速
— 对于公开访问的媒体文件,使用CDN分发

— 5. 异步加载
— 对于大文件,使用异步加载方式

3.3 安全考虑

3.3.1 访问控制

— 安全考虑

— 1. 权限控制
— 限制大对象访问权限
REVOKE ALL ON pg_largeobject FROM PUBLIC;
REVOKE ALL ON pg_largeobject_metadata FROM PUBLIC;

— 只允许特定用户访问
GRANT SELECT ON pg_largeobject TO fgedu_fgfgapp_fgedu;
GRANT SELECT ON pg_largeobject_metadata TO fgedu_fgfgapp_fgedu;

— 2. 数据加密
— 存储加密后的数据
CREATE EXTENSION IF NOT EXISTS pgcrypto;

— 加密存储
INSERT INTO fgedu_documents (document_name, file_data)
VALUES (‘sensitive.pdf’,
pgp_sym_encrypt_bytea(lo_get(file_oid), ‘secret_key’));

— 3. 审计日志
— 记录文件访问日志
CREATE TABLE fgedu_file_access_logs (
id SERIAL PRIMARY KEY,
file_id INTEGER NOT NULL,
fgedu_id INTEGER REFERENCES fgedu_fgedus(id),
access_type VARCHAR(20) NOT NULL, — read, write, delete
access_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
ip_address INET,
fgedu_agent TEXT
);

— 4. 数据脱敏
— 对于敏感文件,存储脱敏后的版本

风哥提示:大对象的安全管理非常重要,建议实施完善的权限控制、审计日志和数据加密机制,确保数据安全。更多学习教程公众号风哥教程itpux_com

Part04-生产案例与实战讲解

4.1 实战案例

4.1.1 电商平台商品图片存储

— 电商平台商品图片存储案例

— 1. 商品图片表
CREATE TABLE fgedu_product_images (
id SERIAL PRIMARY KEY,
product_id INTEGER REFERENCES fgedu_products(id),
image_name VARCHAR(255) NOT NULL,
image_type VARCHAR(20) NOT NULL, — main, detail, thumbnail
file_size BIGINT NOT NULL,
image_data OID NOT NULL,
width INTEGER,
height INTEGER,
sort_order INTEGER DEFAULT 0,
is_primary BOOLEAN DEFAULT false,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

— 2. 图片访问统计
CREATE TABLE fgedu_image_access_stats (
image_id INTEGER REFERENCES fgedu_product_images(id),
access_date DATE NOT NULL,
access_count INTEGER DEFAULT 0,
PRIMARY KEY (image_id, access_date)
);

— 3. 查询商品主图
SELECT
pi.id,
pi.image_name,
pi.width,
pi.height,
pg_size_pretty(pi.file_size) as file_size
FROM fgedu_product_images pi
WHERE pi.product_id = 123
AND pi.is_primary = true;

— 4. 批量上传图片
CREATE OR REPLACE FUNCTION upload_product_images(
p_product_id INTEGER,
p_images JSONB
) RETURNS INTEGER AS $$
DECLARE
v_image JSONB;
v_count INTEGER := 0;
v_oid OID;
BEGIN
FOR v_image IN SELECT * FROM jsonb_array_elements(p_images)
LOOP
— 创建大对象
v_oid := lo_create(0);
— 写入图片数据…

INSERT INTO fgedu_product_images (
product_id, image_name, image_type, file_size,
image_data, width, height, sort_order
) VALUES (
p_product_id,
v_image->>’name’,
v_image->>’type’,
(v_image->>’size’)::BIGINT,
v_oid,
(v_image->>’width’)::INTEGER,
(v_image->>’height’)::INTEGER,
(v_image->>’sort’)::INTEGER
);

v_count := v_count + 1;
END LOOP;

RETURN v_count;
END;
$$ LANGUAGE plpgsql;

4.1.2 医疗影像存储系统

— 医疗影像存储系统案例

— 1. 影像记录表
CREATE TABLE fgedu_medical_images (
id SERIAL PRIMARY KEY,
patient_id INTEGER REFERENCES fgedu_patients(id),
study_id VARCHAR(50) NOT NULL,
series_id VARCHAR(50) NOT NULL,
image_id VARCHAR(50) NOT NULL,
modality VARCHAR(20) NOT NULL, — CT, MRI, X-Ray, etc.
body_part VARCHAR(100),
file_size BIGINT NOT NULL,
image_data OID NOT NULL,
width INTEGER,
height INTEGER,
bits_allocated INTEGER,
pixel_representation INTEGER,
acquisition_date TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

— 2. DICOM标签表
CREATE TABLE fgedu_dicom_tags (
id SERIAL PRIMARY KEY,
image_id INTEGER REFERENCES fgedu_medical_images(id),
tag_group VARCHAR(4) NOT NULL,
tag_element VARCHAR(4) NOT NULL,
tag_name VARCHAR(100),
tag_value TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

— 3. 影像访问控制
CREATE TABLE fgedu_image_access_control (
image_id INTEGER REFERENCES fgedu_medical_images(id),
fgedu_id INTEGER REFERENCES fgedu_fgedus(id),
access_level VARCHAR(20) NOT NULL, — view, download, admin
granted_by INTEGER REFERENCES fgedu_fgedus(id),
granted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
expires_at TIMESTAMP,
PRIMARY KEY (image_id, fgedu_id)
);

— 4. 查询患者影像
SELECT
mi.id,
mi.study_id,
mi.series_id,
mi.modality,
mi.body_part,
mi.acquisition_date,
pg_size_pretty(mi.file_size) as file_size
FROM fgedu_medical_images mi
WHERE mi.patient_id = 12345
ORDER BY mi.acquisition_date DESC;

4.2 最佳实践

# 大对象存储最佳实践

# 1. 设计原则
– 元数据与数据分离:将文件元数据存储在普通表中,文件内容存储为大对象
– 统一命名规范:使用统一的文件命名规范,便于管理
– 版本控制:对于重要文件,实施版本控制
– 权限管理:建立完善的权限管理机制

# 2. 性能优化
– 使用流式读写:避免一次性加载大对象
– 实施缓存策略:缓存热点数据
– 优化数据库参数:调整shared_buffers、work_mem等参数
– 使用CDN:对于公开访问的文件,使用CDN加速

# 3. 安全策略
– 权限控制:限制大对象访问权限
– 数据加密:对敏感数据进行加密存储
– 审计日志:记录文件访问日志
– 备份恢复:建立完善的数据备份恢复机制

# 4. 运维管理
– 监控存储使用:定期监控大对象存储使用情况
– 清理孤立对象:定期清理孤立的大对象
– 归档历史数据:归档不再需要的历史数据
– 自动化运维:使用脚本自动化日常运维任务

4.3 经验教训

大对象存储的经验教训:

  • 避免存储超大文件:虽然大对象支持4TB,但建议将超大文件分割存储
  • 注意内存使用:避免一次性加载大对象到内存,使用流式读写
  • 定期清理:定期清理孤立的大对象,释放存储空间
  • 备份策略:制定完善的大对象备份策略
  • 权限管理:严格控制大对象的访问权限
  • 监控告警:建立存储使用监控和告警机制
风哥教程针对风哥教程针对风哥教程针对生产环境建议:在生产环境中使用大对象时,要充分考虑性能、安全、运维等方面,建立完善的管理机制,确保系统的稳定运行。from PostgreSQL:www.itpux.com

Part05-风哥经验总结与分享

5.1 选型指南

大对象存储选型指南:

# 大对象存储选型指南

# 1. 文件大小
– < 1MB:使用BYTEA类型 - 1MB - 100MB:使用OID大对象 - > 100MB:使用OID大对象 + 分块存储

# 2. 访问模式
– 频繁读取:使用缓存 + CDN
– 频繁写入:使用批量写入 + 异步处理
– 随机访问:使用大对象(支持随机访问)
– 顺序访问:使用BYTEA或文件系统

# 3. 数据类型
– 结构化数据:使用普通表
– 半结构化数据:使用JSONB
– 二进制数据:使用BYTEA或OID
– 大文件:使用OID大对象

# 4. 安全要求
– 高安全要求:使用加密存储 + 严格权限控制
– 一般安全要求:使用标准权限控制
– 公开数据:使用CDN分发

# 5. 性能要求
– 高性能要求:使用缓存 + 优化数据库参数
– 一般性能要求:使用标准配置
– 低性能要求:使用文件系统存储

5.2 实施技巧

大对象实施技巧:

  • 渐进式实施:先在小范围试点,再逐步推广
  • 充分测试:在生产环境使用前充分测试
  • 监控优化:持续监控性能,及时优化
  • 文档记录:记录实施过程和配置
  • 培训团队:培训运维团队掌握大对象管理
  • 制定规范:制定大对象使用规范
风哥提示:大对象存储的实施需要综合考虑多方面因素,建议制定详细的实施计划,分阶段推进,确保项目成功。

大对象存储的发展趋势:

  • 云原生:与云存储服务集成
  • 对象存储:与S3等对象存储集成
  • 分布式存储:支持分布式存储架构
  • 智能管理:AI驱动的存储优化
  • 边缘计算:支持边缘存储和计算
持续学习:大对象存储技术在不断发展,建议关注最新的技术趋势和最佳实践,持续优化存储方案。

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

联系我们

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

微信号:itpux-com

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