数据库与图片完美解决方案

本文涉及的产品
RDS DuckDB + QuickBI 企业套餐,8核32GB + QuickBI 专业版
RDS AI 助手,专业版
RDS Agent(兼容OpenClaw),2核4GB
简介: 你是是不是在开发中常常遇到,删除了数据库记录后,发现该记录对应的图片没有删除,或者删除了图片,数据库中仍有数据存在,你的网站脏数据(图片)成几何数增长,阅读下文这里为你提供了一个完美决方案。


数据库与图片完美解决方案

电商商品图品与数据库脏数据完美解决方案

MrNeo Chen (陈景峯)netkiller, BG7NYT


1. 背景

我以电商网站为例,一般的网站产品数据存放在数据库中,商品图片是上传到文件服务器,然后通过http服务器浏览商品图片。这是最基本的也是最常见做法。

稍复杂的方案是,如果图片数量庞大,会使用分布式文件系统方案。但是这些方案都不能保证数据的完整性,极易产生脏数据(垃圾数据)。脏数据是指当你删除了数据库表中的记录后,图片仍然存在,或者手工删除了图片,而数据库中的记录仍然存在。

将图片放入数据库中存放在BLOB的方法可以解决脏数据问题,典型的案例是公安的身份证系统。但这种方案的前提是,图片不能太大,数量不多,访问量不大。 这显然不适合电商网站。

2009年我在走秀网工作,商品图片与缩图文件900GB到2012离职已经有10TB,每天有成百上千的商品上架下架,很多商品下架后永远不会再上架,这些批量下架的商品数据不会删除,仅仅标记为删除,总是期望以后能继续使用,实际上再也不会有人过问,另一方面随着品类经理频繁更换,员工离职,这些商品会石沉大海,再也无人问均。这些商品所对应的图片也就脏数据主要来源。新的品类经理上任后,会重新拍照,上传新图片。

总之,删除数据库中的数据不能将图片删除就会产生脏数据。很多采用删除数据的时候去检查图片如果存在先删除图片,再删除数据的方法。这种方案也非完美解决方案,存在这图片先被删除,程序出错SQL没有运行,或者反之。

2. 解决思路

如果删除图片能够成为事物处理中的一个环节,所有问题都能迎刃而解,可彻底解决脏数据的烦恼。

3. 解决方案

mysql plugin 开发 udf。我写几个function

UDF
image_check(filename)

检查图片是否存在.

image_remove(filename)

删除图片.

image_rename(oldfile,newfile)

更改图片文件名.

image_md5sum(filename)

md5sum 主要用户图片是否被更改过.

image_move(filename,filename)

移动图片的位置

有了上面的function后你就可以在begin,commit,rollback 直接穿插使用,实现在事物处理期间做你爱做的事。

4. plugin 的开发与使用

编译UDF你需要安装下面的软件包

sudo apt-get install pkg-config
sudo apt-get install libmysqlclient-dev

sudo apt-get install gcc gcc-c++ make automake autoconf
		

https://github.com/netkiller/mysql-image-plugin

编译udf,最后将so文件复制到 /usr/lib/mysql/plugin/

git clone https://github.com/netkiller/mysql-image-plugin.git
cd mysql-image-plugin/src

gcc -I/usr/include/mysql -I./ -fPIC -shared -o image.so image.c
sudo mv image.so /usr/lib/mysql/plugin/
		

装载

create function image_check returns boolean soname 'images.so';
create function image_remove returns boolean soname 'images.so';
create function image_rename returns boolean soname 'images.so';
create function image_md5sum returns string soname 'images.so';
create function image_move returns string soname 'images.so';
		

卸载

drop function image_check;
drop function image_remove;
drop function image_rename;
drop function image_md5sum;
drop function image_move;
		

5. 在事务中使用该插件

插入图片流程,上传图片后,通过插件检查图片是否正确上传,然后插入记录

begin;
IF image_check('/path/to/images.jpg') THEN
	insert into images(product_id,thumbnail,original) values(1000,'thumbnail/path/to/images.jpg','original/path/to/images.jpg');
	commit;
ELSE
	image_remove('/path/to/images.jpg');
END IF
rollback;
		

删除商品采用image_move 方案,当出现异常rollback后还可以还原被删除的图片

begin;
IF image_check('/path/to/images.jpg') THEN
	select thumbnail,original into @thumbnail,@original from images where id='1000' for delete;
	delete from images where id='1000';
	select image_move(@thumbnail,'recycle/path/to/');
	select image_move(@original,'recycle/path/to/');
	commit;
END IF

rollback;
select image_move('recycle/path/to/images.jpg','path/to/images.jpg');
		

我们可以使用EVENT定时删除回收站内的图片

image_remove('recycle/path/to/images.jpg');
		

6. 通过触发器调用图片处理函数

通过触发器更能保证数据完整性

1. insert 触发器的任务: 插入记录的时候通过image_check检查图片是否正常上传,如果非没有上传,数据插入失败。
2. delete 触发器的任务: 检查删除记录的时候,首先去删除图片,删除成功再删除该记录。
		

触发器进一步优化

1. insert 触发器的任务: 插入记录的时候通过image_check检查图片是否正常上传,如果非没有上传,数据插入失败。如果上传成功再做image_md5sum 进行校验100% 正确后插入记录
2. delete 触发器的任务: 检查删除记录的时候,首先去改图片文件名,然后删除该记录,最后删除图片,删除成功。如果中间环境失败 记录会rollback,图片会在次修改文件名改回来。100% 保险


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
目录
相关文章
|
11月前
|
运维 监控 关系型数据库
AI 时代的 MySQL 数据库运维解决方案
本文探讨了大模型与MySQL数据库运维结合所带来的变革,介绍了构建结构化运维知识库、选择合适的大模型、设计Prompt调用策略、开发MCP Server以及建立监控优化闭环等关键步骤。通过将自然语言处理能力与数据库运维相结合,实现了故障智能诊断、SQL自动优化等功能,显著提升了MySQL运维效率和准确性。
997 18
|
Cloud Native 关系型数据库 分布式数据库
阿里云PolarDB与沃趣科技携手打造一体化数据库解决方案,助推国产数据库生态发展
阿里云瑶池数据库与沃趣科技将继续深化合作,共同推动国产数据库技术的持续创新与广泛应用,为行业生态的繁荣注入更强劲的技术动力。
阿里云PolarDB与沃趣科技携手打造一体化数据库解决方案,助推国产数据库生态发展
|
关系型数据库 MySQL 数据库连接
docker拉取MySQL后数据库连接失败解决方案
通过以上方法,可以解决Docker中拉取MySQL镜像后数据库连接失败的常见问题。关键步骤包括确保容器正确启动、配置正确的环境变量、合理设置网络和权限,以及检查主机防火墙设置等。通过逐步排查,可以快速定位并解决连接问题,确保MySQL服务的正常使用。
2898 82
|
运维 监控 关系型数据库
AI 时代的 MySQL 数据库运维解决方案
本方案将大模型与MySQL运维深度融合,构建智能诊断、SQL优化与知识更新的自动化系统。通过知识库建设、大模型调用策略、MCP Server开发及监控闭环设计,全面提升数据库运维效率与准确性,实现从人工经验到智能决策的跃迁。
1180 27
|
11月前
|
SQL 安全 关系型数据库
数据库安全管理新范式:DBKEEPER一体化数据库权限管控堡垒机解决方案
在数字化时代,数据库安全至关重要。DBKEEPER提供一站式数据库安全访问与权限管控解决方案,支持多种数据库,具备精细化权限管理、数据脱敏、高危操作拦截、全面审计等功能,助力企业实现智能、安全的数据治理,满足金融、医疗、互联网等行业合规需求。选择DBKEEPER,让数据库安全管理更高效!
数据库安全管理新范式:DBKEEPER一体化数据库权限管控堡垒机解决方案
|
负载均衡 算法 关系型数据库
大数据新视界--大数据大厂之MySQL数据库课程设计:MySQL集群架构负载均衡故障排除与解决方案
本文深入探讨 MySQL 集群架构负载均衡的常见故障及排除方法。涵盖请求分配不均、节点无法响应、负载均衡器故障等现象,介绍多种负载均衡算法及故障排除步骤,包括检查负载均衡器状态、调整算法、诊断修复节点故障等。还阐述了预防措施与确保系统稳定性的方法,如定期监控维护、备份恢复策略、团队协作与知识管理等。为确保 MySQL 数据库系统高可用性提供全面指导。
|
算法 安全 数据库
数据库死锁的解决方案有哪些?
【10月更文挑战第28天】数据库死锁是数据库管理中的一个常见问题
738 71
|
安全 网络安全 数据库
Access denied for user ‘qingtingstpublic’@’171.213.253.88’ (using password: YES)宝塔数据库远程无法连接-宝塔数据远程无法连接的正确解决方案-优雅草央千澈-问题解决
Access denied for user ‘qingtingstpublic’@’171.213.253.88’ (using password: YES)宝塔数据库远程无法连接-宝塔数据远程无法连接的正确解决方案-优雅草央千澈-问题解决
425 28
|
运维 监控 关系型数据库
数据库管理中的自动化运维:挑战与解决方案
数据库管理中的自动化运维:挑战与解决方案