商品图片,用户上传的头像,其余方面的图片。目前业界存储图片有两种作法:php
一、 把图片直接以二进制形式存储在数据库中css
通常数据库提供一个二进制字段来存储二进制数据。好比mysql中有个blob字段。oracle数据库中是blob或bfile类型html
二、 图片存储在磁盘上,数据库字段中保存的是图片的路径。前端
1、图片以二进制形式直接存储在数据库中java
第一种存储实现(php语言):mysql
大致思路:nginx
一、将读取到的图片用php程序转化成二进制形式。再结合insert into 语句插入数据表中的blob类型字段中去。web
三、 从数据库取出图片展现的时候。则是直接发送图片内容sql
四、 数据库
$row=mysql_fetch_object($result);
Header( "Content-type: image/gif");
echo $row->this_image;
实现代码以下:
$PicturePath = ‘/tmp/xxxjgjgj.jpg’;//假设这是上传的图片,php放在一个临时文件夹。脚本执行完毕后自动删除了。
$imgStream = fread(fopen($PicturePath, "r");
$blob_img = fread(fopen($imgStream, "r"), filesize($PicturePath));
$sql =” INSERT INTO Images (this_image) VALUES ($blob_img)";
注:this_image就是数据表中一个blob字段类型的字段
================取出展现图片代码
$result=mysql_query("SELECT * FROM Images WHERE PicNum=$PicNum") or die("Cant perform Query");
$row=mysql_fetch_object($result);
Header( "Content-type: image/gif");
echo $row-> this_image;
总结:处理代码感受还真比较麻烦。其实,我历来没用过在数据库中以二进制存储图片的作法。咱们用得更多的是存储图片的路径,实际图片是在磁盘上保存的(图片二进制放到数据库,把数据库的负担弄重了)。
据我了解,互联网环境中,大访问量,数据库速度和性能方面很重要。通常在数据库存储图片的作法比较少,更多的是将图片路径存储在数据库中,展现图片的时候只须要链接磁盘路径把图片载入进来便可。由于图片是属于大字段。一张图片可能1m到几m。
有个原则:图片尽可能不要存储在数据库中(是指不要二进制形式保存到字段,而只保存图片的路径)。这样的大字段数据会加剧数据库的负担,拖慢数据库。在大并发访问的状况下很重要。这是一个经验。去看看dba对数据库性能调优方面的分析都能获得这个答案的:就是图片不要存储在数据库中。
就像这个规则同样:文章分为标题、做者、添加时间、更新时间、文章内容、文章关键字
文章内容通常是比较长的。常用text字段去存储。文章的内容就属于大字段。通常文章内容能够拆分到单独一个表中去。不要与文章信息存储在一张表里面。
我理解的原理是:mysql中一张表的数据是所有在一个数据文件中的。若是大字段的数据也存储在里面。程序展现列表,好比文章列表。这个时候根本不须要展现文章内容的。可是仍然会影响速度,数据库查找数据其实就是扫描那个数据文件,文件容量越小,速度就会越快(为何单表的容量在1g-2g的时候基本上要分表了)。拆分出去到一张单独的表,就是单独的文件了。我以为,触类旁通,相互独立,分离的思想不只在系统开发中用到,在现实生活中常常存在的。相互混合,就会形成相互影响。小巧,简洁是一种思想。
能够看看这篇翻译的文章,
http://developer.51cto.com/art/201211/364472.htm
做者建议,三种东西永远不要放到数据库里,图片,文件,二进制数据。做者的理由是,
把图片缩略图存到数据库里?很好,那你就不能使用nginx或其它类型的轻量级服务器来处理它们了。
给本身行个方便吧,在数据库里只简单的存放一个磁盘上你的文件的相对路径,或者使用S3(备注:亚马逊云服务)或CDN之类的服务。
============================================================
关于mysql中的blob类型
bolb像int型那样,分为blob、MEDIUMBLOB、LONGBLOB。其实就是从小到大,
blob 容量为64KB ,MEDIUMBLOB 容量为16M,LONGBLOB 容量为4G。
说实话,图片用这样子存储用得还真少。使用php函数serialize
进行
序列化的值,我看到有人存入这个字段中去。
php
手册:serialize
返回字符串,此字符串包含了表示 value
的字节流,能够存储于任何地方。
mysql中blob字段存储图片有个通讯大小的设置:
图片要传输给mysql存储起来,那么须要涉及到数据通讯。mysql中有个配置是限制通讯数据大小的。
my.conf配置文件中的max_allowed_packet,mysql默认的值是1M。
好多图片尤为是原始图可能不止1m。传输的数据(也就是图片)超过这个设置大小。结果就会出错
呵呵,限制挺多。感受好麻烦。这样子明显占用与mysql交互的通讯时间嘛。延长响应时长了。我直接丢个图片路径”images/xxxx”给mysql。没这么耗费资源。
其实所谓的性能,最关键是数据库性能。由于随着数据库数据量增大,大部分时间耗费是在php,java等语言等待数据库返回数据的过程当中耗费时间。
网站访问量大了后,具体的语言不是瓶颈,瓶颈都在数据库。用c,,php,java,net都能操做mysql数据库获取数据。语言之间可能存在速度执行差别,可是其实这种差异已经很小了。至少我以为,给予用户感受不到明显。执行相差0.0001秒用户感受并无明显的区别。可能说,大并发(不少用户同时访问)的时候,就会体现到差异了。其实我以为,大并发访问是数据库瓶颈。等待数据库给予数据。没达到必定级别实在体现不了差异。数据库数据量达到必定级别。语言相差0.001s会给予用户体验上的差异。我想,这也是为何php很适合作web开发了。解析页面速度快(解释型语言,不须要编译)。能够用java来与数据库打交道获取数据。php不直接操做数据库,而是调用java提供的数据接口,获取数据,立刻展现在页面中。这是利用了php的页面执行速度快的一个优点。
备份图片数据和迁移数据方便
图片以二进制形式存储在数据库,有一个好处:备份的时候方便。直接备份数据库,图片也跟着备份。换句话说,迁移环境的时候是方便。
而图片放在磁盘上的话,数据库中存储的只是图片路径。备份数据库后。磁盘上的图片也要跟着备份才行。
不过我以为,备份这个好处不是很明显。图片在磁盘上,备份磁盘也没很大的事情。打包压缩也能够了。互联网环境毕竟与传统的软件开发不一样,web开发比较关注网站速度。也就是数据库的速度。就像互联网开发中,有时候为了速度,用空间换时间的作法比较广泛,因此每每在设计数据库的时候并不必定遵循传统数据库设计三大范式。
数据库中保存的是图片路径的话,在web开发环境下,其实有个更好处,就是cdn加速。就是下面要进行总结的地方。
2、数据库中保存图片路径
通常是这样子的:
按照年月日生成路径。具体是按照年月日仍是按照年月去生成路径,根据本身须要(不必定是按照日期去生成)。
理解为何要分散到多个文件夹中去才是关键,涉及到一个原理就明白了:
操做系统对单个目录的文件数量是有限制的。当文件数量不少的时候。从目录中获取文件的速度就会愈来愈慢。因此为了保持速度,才要按照固定规则去分散到多个目录中去。
图片分散到磁盘路径中去。数据库字段中保存的是相似于这样子的”images/2012/09/25/ 1343287394783.jpg”
原来上传的图片文件名称会从新命名保存,好比按照时间戳来生成,1343287394783. jpg。这样子是为了不文件名重复,多我的往同一个目录上传图片的时候会出现。
反正用什么样的规则命名图片,只要作到图片名称的惟一性便可。
好比网站的并发访问量大,目录的生成分得月细越好。好比精确到小时,一个小时均可以是一个文件夹。同时0.001秒有两个用户同时在上传图片(由于那么就会往同一个小时文件夹里面存图片)。由于时间戳是精确到秒的。为了作到图片名称惟一性而不至于覆盖,生成能够在在时间戳后面继续加毫秒微秒等。总结的规律是,并发访问量越大。就越精确就行了。
我如今还没碰到须要这么精细的。几率比较少。
有个方面总结一下:为何保存的磁盘路径,是”images/2012/09/25/1343287394783.jpg”,而不是” /images/2012/09/25/ 1343287394783.jpg”(最前面带有斜杠)
个人理解:
连那个斜杠都不要。这里也是作到方便之后系统扩展。
在页面中须要取出图片路径展现图片的时候,若是是相对路径,则可使用”./”+”images/2012/09/25/1343287394783.jpg”进行组装。
若是须要单独的域名(好比作cdn加速的时候)域名,img1.xxx.com,img2.xxx.com这样的域名,
直接组装 “http://img1.xxx.com/”+”images/2012/09/25/1343287394783.jpg”
固然数据库是能够在前面加斜杠/保存起来,/images/2012/09/25/ 1343287394783.jpg
其实不方便统一。好比相对路径载入图片的时候,则是”.”+” /images/2012/09/25/ 1343287394783.jpg”
可能我还没体会到坏处,之后会遇到问题的。不过,遵循惯例不加斜杠” images/2012/09/25/ 1343287394783.jpg”就对了。
涉及到一个新问题:为何大部分系统都不会域名保存进去,像这样子http://www.xxx.com/images/2012/09/25/1343287394783.jpg保存到数据库中
曾经与一个上海的网友聊天,他也是习惯不会把域名保存数据库中过去。但当时咱们两聊的时候,他对”域名保存进去的作法”与”不保存域名进去”也没有一个明确利弊。他就以为,没有什么明显的区别啊。
了解的知识越多,越有利于咱们作决定。可能就是一个”感受区别不是很大”的影响下,去作一个决定,反而对后面是比较大的影响的。至少是增长本身的工做量了。
其实把域名保存进去,也不是什么滔天大罪的事情。但凡是经验丰富的开发人员都不会这样子作。这是一个经验积累出来的,因此上海那个网友也对此并无明显的概念很正常,他说他不知道cdn方面的(固然以为存个域名进去没什么大不了的)。须要了解cdn知识,什么状况下会用到cdn知识。
虽然是作开发人员,不须要关注运维和服务器之类的知识。不过了解一些就有利于理解了。
这里涉及到cdn加速。
关于cdn原理(就是内容分发网络)
cdn,我理解其本质就是为了解决距离远产生的速度问题,使用就近的服务。
从中国请求美国一台服务器上的图片。通常比较慢,由于距离这么远,网络传输是存在损耗的,距离越远,传输的时间就越长。通常会看到浏览器左下角显示:“已响应,正在传输数据..”。这不是服务器自己问题了。实际上服务器早就响应请求,把数据发给客户端,可是网络问题,就一直在传输,没传完了。
在中国,是南北距离远的问题。南北还会涉及到跨网,南方用户使用电信居多,北方用户网通居多。两个线路须要跨越,会有时间延迟。北京到广州的距离,若是直接请求
cdn加速就是适应这个需求产生的:如今不请求美国的服务器。直接在中国安放节点(节点是比较笼统的词语,能够理解成一台服务器,也能够理解成一个机房,就是一个点嘛),请求距离近的节点。这样子就不须要那么远的距离了。
记得之前在长沙的网站,团购以城市分站的形式。北京和长沙用的是同一套程序。服务器在长沙。北京用户访问北京站的时候,实际上须要远距离访问长沙的服务器。速度怎么都快不起来。跟服务器性能彻底不要紧。当时不懂这些。不清楚怎么折腾。看那本《前端优化技巧》,想办法去作js代码压缩,浏览器缓存之类的。实际上瞎折腾。不是说这些前端优化不重要,哲学上有主次矛盾之分,瓶颈在哪里就去突破哪里。没解决主要矛盾,问题并不会迎刃而解。当时也不是数据库瓶颈。若是去优化数据库。也不会明显改善。就那点数据量。根本就达不到瓶颈。哪里谈得上主要矛盾。随着后来去其余公司工做,接触一些东西,相似不找瓶颈的优化例子发生在身边好几回了,先没找到瓶颈就瞎去优化。个人同事多是抱着多多益善的心态去作的,但主要矛盾(技术上说是瓶颈)没找到,也没改善。
当时若是没想到是距离问题。也就不会想到cdn,当时其实我根本不知道cdn服务。我只知道,google这些网站确定在中国部署的服务器,要否则,中国用户还去访问美国的服务器,那再好的服务器都会速度慢的。
因为本身搭建cdn环境和机房的资金比较大(须要大量的服务器),也须要人力维护。反正通常的公司弄不起,其实根本不划算。淘宝之前用商用的cdn服务,后来商用的扛不住了,就搭建了本身的cdn网。我不知道新浪有没有本身搭建,但其实我以为跟淘宝的特色有关,店铺不少,不管是商品仍是交易记录总计起来商品不少的图片,图片都是静态的部分,cdn原本就是用来作静态的(图片,css,js等)请求分发用的。
我以前在网上看到一句话,cdn网络不是通常的公司玩得起的。
通常的公司本身搭建cdn网络成本高,因此就有商业的cdn提供付费租用服务,这是一项很成熟的业务,不少这样的公司,大部分全国性的互联网公司都会使用到cdn。
总结:cdn服务。对于静态内容是很是适合的。因此像商品图片,随着访问量大了后,租用cdn服务,只须要把图片上传到他们的服务器上去。
例子:北京访问长沙服务器,距离太远。我彻底能够把商品图片,放到北京的云服务(我以为如今提供给网站使用的云存储其实就是cdn,给网站提供分流和就近访问)上去。这样子北京用户访问的时候,实际上图片就是就近获取。不须要很长距离的传输。
本身用一个域名img.xxx.com来载入图片。这个域名解析到北京的云服务上去。
作法:数据库中保存的是” images/2012/09/25/1343287394783.jpg”,
这些图片实际上不存储在web服务器上。上传到北京的cdn服务器上去。
我从数据库取出来,直接”img.xxx.com/”+” images/2012/09/25/1343287394783.jpg”
好比若是还有多个,就命名img1.xx.com、img2.xx.com
反正能够随便。因此若是把域名直接保存进去。就显得很麻烦了。迁移麻烦。
像淘宝,凡客,亚马逊这些电子商务网站,咱们看到请求的时候,下面每每会有
img1.xxx.cdn.com
img2.xxx.cdn.com
其实他们保存在数据库中的是相对路径。有些是不须要在数据库保存的,缩略图能够实时访问的时候用程序生成(节省不少存储空间)
实际上,把域名保存在数据库中,很是不利于系统迁移。一旦换个域名的话,原来保存在数据库中的是“www.abc.om/images/xxxxxx“,由于路径都在数据库中写死了。下回换个域名就用不了了。那个时候本身去写sql语句批量更新字段吧。
几个术语:
icp,Internet Content Provider,也就是网络内容提供者。联想到咱们运营一个网站须要icp备案了吗?你本身运营网站,你就是icp服务商
IDC(Internet Data Center),互联网数据中心。IDC的概念,目前尚未一个统一的标准。通俗点,就是提供机房托管(服务器租用和托管),域名注册之类的。
关于淘宝的图片存储
了解到:淘宝之前使用了商用的存储。可是无法知足需求。听说,到2010年,淘宝网后端保存着286亿张图片。商用的系统系统无法知足需求的时候。他们就本身开发了一个tfs。大规模的小文件在磁盘上读取,须要磁盘磁头频繁的寻道和换道。大并发状况下和大量的操做确实很麻烦。其实借鉴了当时google公布的gfs设计论文。google有相册服务。为每一个用户提供上传图片存储。
估计,google是率先实现这种小文件网络存储系统的。
有个观点比较好:对于老板们而言,每每以为,用钱能解决的都不算问题。但问题在于,你遇到的问题,别人都没遇到过。那这个时候你就没有经验能够参考或者直接拿来使用。只有本身参考一些思路去创造技术了。
3、关于图片进行云存储(cdn加速)
曾经看过这个,这个是比较适合创业公司的。价格相对便宜
介绍提到,咱们在全国各地部署了55个CDN节点,500多台服务器,电信,联通,移动和教育网的4线带宽。
其实,如今的云存储本质就是一个cdn服务商。你把静态的图片上传到他提供的服务器上去(ftp方式上传或者api形式编写程序上传)。他为你作就近节点访问。
计费方式:按照流量付费,99元购买100g。怎么算流量。每次访问文件的大小累加,好比一个1m的文件,访问一次流量就加1m。
我我的理解,对于图片的量不大的状况下,使用这种云服务,好处不是节省存储空间。你本身的服务器100g的空间可能创业型公司都没用完,不是什么存储空间不够用,而后去用云存储。之前我对cdn比较模糊,有这么点理解,或者觉得是分散网站web服务器流压力,服务器分流。这些好处是有的。可是,只要理解了cdn产生的背景和解决的关键问题后,就会明白云存储关键好处在于:给用户就近节点访问,加速。
我以为,若是不是出于这个考虑,或者达不到这样的目的。用其余方案也彻底能够替代。何须使用云存储呢?就是你无非有实力作到全国多个节点去部署服务,才须要租用cdn来帮你,毕竟他们是规模产生的效益,专一于解决这个领域。
还有:腾讯云、阿里云
原文:http://www.cnblogs.com/wangtao_20/p/3440570.html