[size=13.3333px]http://www.cnblogs.com/wangtao_20/p/3440570.html
[size=13.3333px]商品图片,用户上传的头像,其他方面的图片。目前业界存储图片有两种做法: [size=13.3333px]1、 把图片直接以二进制形式存储在数据库中 [size=13.3333px]一般数据库提供一个二进制字段来存储二进制数据。比如mysql中有个blob字段。oracle数据库中是blob或bfile类型
[size=13.3333px]2、 图片存储在磁盘上,数据库字段中保存的是图片的路径。
[size=13.3333px]一、图片以二进制形式直接存储在数据库中
[size=13.3333px]第一种存储实现(php语言): [size=13.3333px]大体思路: [size=13.3333px]1、将读取到的图片用php程序转化成二进制形式。再结合insert into 语句插入数据表中的blob类型字段中去。 [size=13.3333px]3、 从数据库取出图片展示的时候。则是直接发送图片内容 [size=13.3333px]4、 代码 [size=13.3333px]总结:处理代码感觉还真比较麻烦。其实,我从来没用过在数据库中以二进制存储图片的做法。我们用得更多的是存储图片的路径,实际图片是在磁盘上保存的(图片二进制放到数据库,把数据库的负担弄重了)。
[size=13.3333px]据我了解,互联网环境中,大访问量,数据库速度和性能方面很重要。一般在数据库存储图片的做法比较少,更多的是将图片路径存储在数据库中,展示图片的时候只需要连接磁盘路径把图片载入进来即可。因为图片是属于大字段。一张图片可能1m到几m。
[size=13.3333px]有个原则:图片尽量不要存储在数据库中(是指不要二进制形式保存到字段,而只保存图片的路径)。这样的大字段数据会加重数据库的负担,拖慢数据库。在大并发访问的情况下很重要。这是一个经验。去看看dba对数据库性能调优方面的分析都能得到这个答案的:就是图片不要存储在数据库中。
[size=13.3333px]就像这个规则一样:文章分为标题、作者、添加时间、更新时间、文章内容、文章关键字 [size=13.3333px]文章内容一般是比较长的。经常使用text字段去存储。文章的内容就属于大字段。一般文章内容可以拆分到单独一个表中去。不要与文章信息存储在一张表里面。 [size=13.3333px]我理解的原理是:mysql中一张表的数据是全部在一个数据文件中的。如果大字段的数据也存储在里面。程序展示列表,比如文章列表。这个时候根本不需要展示文章内容的。但是仍然会影响速度,数据库查找数据其实就是扫描那个数据文件,文件容量越小,速度就会越快(为什么单表的容量在1g-2g的时候基本上要分表了)。拆分出去到一张单独的表,就是单独的文件了。我觉得,举一反三,相互独立,分离的思想不仅在系统开发中用到,在现实生活中经常存在的。相互混合,就会造成相互影响。小巧,简洁是一种思想。
[size=13.3333px] [size=13.3333px]可以看看这篇翻译的文章, [size=13.3333px]作者建议,三种东西永远不要放到数据库里,图片,文件,二进制数据。作者的理由是, - 对数据库的读/写的速度永远都赶不上文件系统处理的速度
- 数据库备份变的巨大,越来越耗时间
- 对文件的访问需要穿越你的应用层和数据库层
[size=13.3333px]把图片缩略图存到数据库里?很好,那你就不能使用nginx或其它类型的轻量级服务器来处理它们了。 [size=13.3333px]给自己行个方便吧,在数据库里只简单的存放一个磁盘上你的文件的相对路径,或者使用S3(备注:亚马逊云服务)或CDN之类的服务。
[size=13.3333px]============================================================
[size=13.3333px]关于mysql中的blob类型
[size=13.3333px]bolb像int型那样,分为blob、MEDIUMBLOB、LONGBLOB。其实就是从小到大, [size=13.3333px]blob 容量为64KB ,MEDIUMBLOB 容量为16M,LONGBLOB 容量为4G。
[size=13.3333px]说实话,图片用这样子存储用得还真少。使用php函数serialize进行序列化的值,我看到有人存入这个字段中去。
[size=13.3333px]php手册:serialize返回字符串,此字符串包含了表示 value 的字节流,可以存储于任何地方。
[size=13.3333px]mysql中blob字段存储图片有个通信大小的设置:
[size=13.3333px]图片要传输给mysql存储起来,那么需要涉及到数据通信。mysql中有个配置是限制通信数据大小的。
[size=13.3333px]my.conf配置文件中的max_allowed_packet,mysql默认的值是1M。
[size=13.3333px]好多图片尤其是原始图可能不止1m。传输的数据(也就是图片)超过这个设置大小。结果就会出错
[size=13.3333px]呵呵,限制挺多。感觉好麻烦。这样子明显占用与mysql交互的通信时间嘛。延长响应时长了。我直接丢个图片路径”images/xxxx”给mysql。没这么耗费资源。
[size=13.3333px]其实所谓的性能,最关键是数据库性能。因为随着数据库数据量增大,大部分时间耗费是在php,java等语言等待数据库返回数据的过程中耗费时间。
[size=13.3333px]网站访问量大了后,具体的语言不是瓶颈,瓶颈都在数据库。用c,,php,java,net都能操作mysql数据库获取数据。语言之间可能存在速度执行差异,但是其实这种差别已经很小了。至少我觉得,给予用户感觉不到明显。执行相差0.0001秒用户感觉并没有明显的区别。可能说,大并发(很多用户同时访问)的时候,就会体现到差别了。其实我觉得,大并发访问是数据库瓶颈。等待数据库给予数据。没达到一定级别实在体现不了差别。数据库数据量达到一定级别。语言相差0.001s会给予用户体验上的差别。我想,这也是为什么php很适合做web开发了。解析页面速度快(解释型语言,不需要编译)。可以用java来与数据库打交道获取数据。php不直接操作数据库,而是调用java提供的数据接口,获取数据,马上展示在页面中。这是利用了php的页面执行速度快的一个优势。
[size=13.3333px]备份图片数据和迁移数据方便
[size=13.3333px]图片以二进制形式存储在数据库,有一个好处:备份的时候方便。直接备份数据库,图片也跟着备份。换句话说,迁移环境的时候是方便。
[size=13.3333px]而图片放在磁盘上的话,数据库中存储的只是图片路径。备份数据库后。磁盘上的图片也要跟着备份才行。
[size=13.3333px]不过我觉得,备份这个好处不是很明显。图片在磁盘上,备份磁盘也没很大的事情。打包压缩也可以了。互联网环境毕竟与传统的软件开发不同,web开发比较关注网站速度。也就是数据库的速度。就像互联网开发中,有时候为了速度,用空间换时间的做法比较普遍,所以往往在设计数据库的时候并不一定遵循传统数据库设计三大范式。
|