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

本文涉及的产品
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用版 2核4GB 50GB
简介:

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

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

MrNeo Chen (netkiller)陈景峰(BG7NYT)


中国广东省深圳市龙华新区民治街道溪山美地
518131
+86 13113668890
+86 755 29812080

$Id: MySQL-plugin.xml 587 2013-05-16 09:49:20Z netkiller $

版权 © 2011, 2012, 2013 http://netkiller.github.io

$Date: 2013-05-16 17:49:20 +0800 (Thu, 16 May 2013) $

摘要

你是是不是在开发中常常遇到,删除了数据库记录后,发现该记录对应的图片没有删除,或者删除了图片,数据库中仍有数据存在,你的网站脏数据(图片)成几何数增长,阅读下文这里为你提供了一个完美决方案。

原文出处:http://netkiller.github.io/journal/mysql-plugin.html


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 触发器的任务: 检查删除记录的时候,首先去改图片文件名,然后删除该记录,最后删除图片,删除成功。如果中间环境
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
1月前
|
存储 SQL BI
毫秒级查询性能优化实践!基于阿里云数据库 SelectDB 版内核:Apache Doris 在极越汽车数字化运营和营销方向的解决方案
毫秒级查询性能优化实践!基于阿里云数据库 SelectDB 版内核:Apache Doris 在极越汽车数字化运营和营销方向的解决方案
毫秒级查询性能优化实践!基于阿里云数据库 SelectDB 版内核:Apache Doris 在极越汽车数字化运营和营销方向的解决方案
|
11天前
|
关系型数据库 分布式数据库 数据库
PolarDB,阿里云的开源分布式数据库,与微服务相结合,提供灵活扩展和高效管理解决方案。
【7月更文挑战第3天】PolarDB,阿里云的开源分布式数据库,与微服务相结合,提供灵活扩展和高效管理解决方案。通过数据分片和水平扩展支持微服务弹性,保证高可用性,且兼容MySQL协议,简化集成。示例展示了如何使用Spring Boot配置PolarDB,实现服务动态扩展。PolarDB缓解了微服务数据库挑战,加速了开发部署,为云原生应用奠定基础。
84 3
|
20天前
|
SQL druid Java
传统后端SQL数据层替代解决方案: 内置数据源+JdbcTemplate+H2数据库 详解
传统后端SQL数据层替代解决方案: 内置数据源+JdbcTemplate+H2数据库 详解
17 1
|
26天前
|
存储 缓存 NoSQL
Redis是一种高性能的内存数据库,常用于高并发环境下的缓存解决方案
【6月更文挑战第18天】**Redis摘要:** 高性能内存数据库,擅长高并发缓存。数据存内存,访问迅速;支持字符串、列表等多元数据类型;具备持久化防止数据丢失;丰富命令集便于操作;通过节点集群实现数据分片与负载均衡,增强可用性和扩展性。理想的缓存解决方案。
33 1
|
10天前
|
关系型数据库 MySQL 分布式数据库
MySQL数据库上云选型解决方案
阿里云提供全面的MySQL数据库解决方案,适用于高并发、高弹性、大数据分析等场景。PolarDB、PolarDB-X和RDS MySQL版是核心产品,支持企业从初创到大规模发展的数据库选型。PolarDB具备分钟级弹性扩展,适合大促;PolarDB-X解决分布式扩展需求;RDS适合平稳运行的业务。案例包括数云、Ping++、长沙营智和特步,证明了方案的有效性和广泛适用性。此外,DTS服务确保平滑迁移。
18 0
|
1月前
|
存储 NoSQL 数据处理
探索MongoDB:灵活、高性能的NoSQL数据库解决方案与应用实践
探索MongoDB:灵活、高性能的NoSQL数据库解决方案与应用实践
112 1
|
20天前
|
NoSQL Java 关系型数据库
非关系型数据库NoSQL数据层解决方案 之 Mongodb 简介 下载安装 springboot整合与读写操作
非关系型数据库NoSQL数据层解决方案 之 Mongodb 简介 下载安装 springboot整合与读写操作
37 0
|
20天前
|
NoSQL Java 关系型数据库
非关系型数据库NoSQL数据层解决方案 之 redis springboot整合与读写操作 2024详解以及window版redis5.0.14下载
非关系型数据库NoSQL数据层解决方案 之 redis springboot整合与读写操作 2024详解以及window版redis5.0.14下载
18 0
|
23天前
|
缓存 NoSQL Java
高并发场景下缓存+数据库双写不一致问题分析与解决方案设计
高并发场景下缓存+数据库双写不一致问题分析与解决方案设计
|
1月前
|
数据管理 大数据 测试技术
宽睿数字平台兼容TDengine 等多种数据库,提供行情解决方案
最近,涛思数据与宽睿金融宣布了一项重要合作。在此之前,宽睿金融对 TDengine 进行了性能测试,并根据测试报告的结果,决定将 TDengine 接入宽睿数字平台,以提升高密度行情处理效率。本文将详细介绍此次合作的具体内容,供其他金融企业参考借鉴。
23 0