php+mysql缓存技术的实现

本教程适合于那些对缓存SQL查询以减少数据库连接与执行的负载、提高脚本性能感兴趣的PHP程序员。
概述

许多站点使用数据库作为站点数据存储的容器。数据库包含了产器信息、目录结构、文章或者留言本,有些数据很可能是完全静态的,这些将会从一个缓存系统中得到的极大好处。
   这样一个系统通过把SQL查询的结果缓存到系统的一个文件中存储,从而阻止连接数据库,构造查询与取得返回结果而提高了响应时间。
   有些系统数据库并不是放在WEB服务器上的,这样需要一个远程连接(TCP或者其它类似的),或者从数据库中获取大量的数据,这样你得忍受更多时间,这决定于系统响应时间与资源利用。
前提

本教程使用MySQL作为数据库。你需要安装MySQL(www.mysql.com下载是有效的)和激活PHP MYSQL扩展(默认情况是激活的)。
由于要查询数据库,你需要知识一些SQL(结构化查询语言)的基本常识。
缓存SQL查询结果
为什么要缓存查询结果?
缓存查询结果能极大地改进脚本执行时间和资源需求。
    缓存SQL查询结果也允许你通过后期处理数据。如果你用文件缓存去存储全部脚本的输出结果(HTML输出),这样可能是行不通的。
当你执行一个SQL查询时,点典的处理过程是:
<!--[if !supportLists]-->l        <!--[endif]-->连接数据库
<!--[if !supportLists]-->l        <!--[endif]-->准备SQL查询
<!--[if !supportLists]-->l        <!--[endif]-->发送查询到数据库
<!--[if !supportLists]-->l        <!--[endif]-->取得返回结果
<!--[if !supportLists]-->l        <!--[endif]-->关闭数据库连接
   以上方法非常占用资源并且相反的影响了脚本的性能。只能通过取得的大量返回数据和数据库服务器的位置这二个要素来相互协调。尽管持续连接可以改进连接数据库时的负载,但非常耗费内存资源,如果获取的是大量的数据,那么存储的全部时间会非常短暂。
创建一条SQL查询:
   SQL(结构化查询语言)查询被用作操作数据库及它内容的接口。SQL可用于定义和编辑表的结构,插入数据到表,更新或删除表中的信息。
   SQL是用于与数据通讯的语言,在大多数PHP数据库扩展(MySQL,ODBC,Oracle等)通过传递SQL查询到数据库中来管理整个过程。
   本教程中,仅仅用select语言来获取数据库中的数据。这些数据将被缓存,之后将用作数据源。
决定什么时候更新缓存:
根据程序的需要,缓存可以采取多种形式。最常见的3种方式是:
<!--[if !supportLists]-->l        <!--[endif]-->时间触发缓存(过期的时间戳)
<!--[if !supportLists]-->l        <!--[endif]-->内容改变触发缓存(发现数据改变后,相应地更新缓存)
<!--[if !supportLists]-->l        <!--[endif]-->人工触发缓存(人工的方式告知系统信息超期并且强制产生新的缓存)
         你的缓存需求可能是以上原理的一个或多个的综合。本教程将讨论时间触发方式。然而,在一个全面的缓存机制中,3种方式的综合将被使用。
缓存结果:
        基本的缓存是用PHP的两个函数serialize()和unserialize()(译注:这二个函数分别代表序列化与反序列化)。
        函数serialize()用于存储PHP的值,它能保证不失去这些值的类型和结构。
        事实上,PHP的session扩展是用序列化过的变量,把session变量($_SESSION)存储在系统的一个文件中。
        函数unserialize()与以上操作相反并且使序列化过的字符串返回到它原来的结构和数据内容。
        在本例中,以一个电子商务商店为例。商店有2个基本表,categories和products(此处为原始数据库表名).product表可能每天都在变化,categories仍然是不变静止的。
        要显示产品,你可以用一个输出缓存脚本来存储输出的HTML结果到一个文件中。然而categories表可能需要后期处理。例如,所有的目录通过变量 category_id(通过$_REQUEST[‘category_id‘]来取得)被显示,你可能希望高亮当前被选择的目录。

表categories结构
Field                            Type                                    Key                 Extra
category_id                      int(10) unsigned               PRI                 auto_incremen
category_name                 varchar(255)
category_description       text 
       在本例中,通过时间触发缓存技术被运用,设定一段时间后让其缓存SQL输出过期。在此特殊的例子中,定一段时间为24小时。
序列化例子:
<!--[if !supportLists]-->l        <!--[endif]-->连接数据库
<!--[if !supportLists]-->l        <!--[endif]-->执行查询
<!--[if !supportLists]-->l        <!--[endif]-->取得所有结果构成一个数组以便后面你可以访问
<!--[if !supportLists]-->l        <!--[endif]-->序列化数组
<!--[if !supportLists]-->l        <!--[endif]-->保存序列化过的数组到文件中*/

$file = ‘sql_cache.txt‘;
$link = mysql_connect(‘localhost‘,‘username‘,‘password‘) or die (mysql_error());
mysql_select_db(‘shop‘) or die (mysql_error());

/* 构造SQL查询 */
$query = "SELECT * FROM categories";
$result = mysql_query($query) or die (mysql_error());
while ($record = mysql_fetch_array($result) ){
    $records[] = $record;
}
$OUTPUT = serialize($records);
$fp = fopen($file,"w"); // 以写权限的方式打开文件
fputs($fp, $OUTPUT);
//fwrite($fp,$OUTPUT);
fclose($fp);

/*查看sql_cache.txt文件,里面的内容可能类似这样的:
a:1:{i:0;a:6:{i:0;s:1:"1";s:11:"category_id";s:1:"1";i:1;s:9:"Computers";s:13:"category_name";s:9:"Computers" ;i:2;s:25:"Description for computers";s:20:"category_description";s:25:"Description for computers";}}
       这个输出是它的变量和类型的内部表现形式。假若你用mysql_fetch_array()函数返回数字索引的数组和一个关联的数组(这就是为什么数据看起来像是发生了两次),一个是数字索引,另一个是字符串索引。
使用缓存:
要用缓存,你需要用函数unserialize()来使数据还原成原始格式与类型。
你可以用file_get_contents()这个函数来读取sql_cache.txt文件的内容,把它赋给一个变量。
       请注意:这个函数在PHP4.3.0及以上版本有效。若你使用的是一个老版本的PHP,一个简单的方法是用file()函数(读整个文件到一个数组,每行变成一个数组)。implode()函数用于把数组的各元素连接成一个字符串然后使用unserialize()反序列化。*/

// file_get_contents() 适合于for PHP < 4.3.0
$file = ‘sql_cache.txt‘;
$records = unserialize(implode(‘‘,file($file)));
//现在你可以通过$records数组并且取得原始查询的数据:
foreach ($records as $id=>$row) {
    print $row[‘category_name‘]."<br>";
}
       /* 注意$records是数组(一个包含了查询结果的数字索引列——每行是一个数字和一个字符串...真是混乱)的一排。
把它们放在一块:
      基于本例子中的时间来决定是否缓存。如果文件修改的时间戳比当前时间戳减去过期时间戳大,那么就用缓存,否则更新缓存。
<!--[if !supportLists]-->l        <!--[endif]-->检查文件是否存在并且时间戳小于设置的过期时间
<!--[if !supportLists]-->l        <!--[endif]-->获取存储在缓存文件中的记录或者更新缓存文件
$file = ‘sql_cache.txt‘;*/
$expire = 86400; // 24 小时 (单位:秒)
if (file_exists($file)&&filemtime($file) > (time() - $expire)){
    // 取得缓存中的记录
    $records = unserialize(file_get_contents($file));
} else {
    // 通过 serialize() 函数创建缓存
}
/*附加其它可能的:
<!--[if !supportLists]-->l        <!--[endif]-->把缓存结果存储在共享内存中以获取更快的速度
<!--[if !supportLists]-->l        <!--[endif]-->增加一个功能随机地运行SQL查询并且检查是否输出与缓存输出一致。如果不一致,则更新缓存(本函数运行次数的概率可以定为1/100)。通过哈希算法(如MD5())可以协助判断字符串或者文件是否改变。
<!--[if !supportLists]-->l        <!--[endif]-->增加一个管理员的功能,人工的删除这个缓存文件,以强制更新缓存(如file_exists()函数返回 false时)。你可以用函数unlink()删除文件。
脚本:*/

$file = ‘sql_cache.txt‘;
$expire = 86400; // 24 小时
if (file_exists($file)&&filemtime($file) > (time() - $expire)) {
    $records = unserialize(file_get_contents($file));
   //$records=unserialize(fread($file,filesize($file)));
} else {
    $link = mysql_connect(‘localhost‘,‘username‘,‘password‘) or die (mysql_error());
    mysql_select_db(‘shop‘) or die (mysql_error());
    /* 构造SQL查询 */
    $query = "SELECT * FROM categories";
    $result = mysql_query($query) or die (mysql_error());
    while ($record = mysql_fetch_array($result) ) {
        $records[] = $record;
    }
    $OUTPUT = serialize($records);
    $fp = fopen($file,"w");
    //fputs($fp, $OUTPUT);
    fwrite($fp,$OUTPUT);
    fclose($fp);
} // end else

// 查询结果在数组 $records 中
foreach ($records as $id=>$row) {
    if ($row[‘category_id‘] == $_REQUEST[‘category_id‘]) {
        // 被选择的目录显示粗体字
        print ‘<B>‘.$row[‘category_name‘].‘</B><BR>‘;
    } else {
        // 其它目录显示用常规字体
        print $row[‘category_name‘].‘<br>‘;
    }
} // end foreach

时间: 2024-09-30 06:37:39

php+mysql缓存技术的实现的相关文章

Redis缓存技术学习系列之邂逅Redis

??作为一个反主流的开发者,在某种程度上,我对传统关系型数据库一直有点"讨厌",因为关系型数据库实际上和面向对象思想是完全冲突的,前者建立在数学集合理论的基础上,而后者则是建立在软件工程基本原则的基础上.虽然传统的ORM.序列化/反序列化在一定程度上解决了这种冲突,但是软件开发中关于使用原生SQL语句还是使用ORM框架的争论从来没有停止过.可是实际的业务背景中,是完全无法脱离数据库的,除非在某些特定的场合下,考虑到信息安全因素而禁止开发者使用数据库,在主流技术中数据库是一个非常重要的组

PHP 缓存技术

PHP缓存包括PHP编译缓存和PHP数据缓存两种. PHP是一种解释型语言,属于边编译边运行的那种.这种运行模式的优点是程序修改很方便,但是运行效率却很低下. PHP编译缓存针对这种情况做改进处理,使得PHP语言只要运行一次,就可以把程序的编译结果缓存起来. PHP编译缓存: 目前最常见的PHP编译缓存工具有:APC,Accelerator,xcache(国产)等. PHP是一种解释型语言,在PHP语言执行代码的时候,需要下面两步: 1.编译过程.PHP读取文件,并编译该文件,然后生成能够在Ze

MySQL缓存参数优化(转)

MySQL 数据库性能优化之缓存参数优化 数据库属于 IO 密集型的应用程序,其主要职责就是数据的管理及存储工作.而我们知道,从内存中读取一个数据库的时间是微秒级别,而从一块普通硬盘上读取一个IO是在毫秒级别,二者相差3个数量级.所以,要优化数据库,首先第一步需要优化的就是 IO,尽可能将磁盘IO转化为内存IO.本文先从 MySQL 数据库IO相关参数(缓存参数)的角度来看看可以通过哪些参数进行IO优化. query_cache_size/query_cache_type (global) Qu

PHP网页缓存技术

http://blog.sina.com.cn/s/blog_646e51c40100weu9.html 前台静态化:把动态页面解析后保存为静态页面 文件缓存:把查询结果保存为文件,XML 内存缓存:memcache php缓存器:XCache.eaccelerator等 Memcache是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像.视频.文件以及数据库检索的结果等.简单的说就是将数据调用到内存中,然后从内存中读取,从

今天开始学习Mysql优化技术

随着工作的深入,愈发觉得数据库优化方面知识方面的重要性,于是下载了韩顺平的Mysql优化技术的视频,这里全当课后笔记,里面可能会穿插一些自己的工作经验(感谢韩老师). Mysql优化不是一种动作,而是全套动作,包括 : 1.表的设计合理化 2.添加适当的索引 3.分表技术(水平分表,垂直分表) 4.读写分离技术 5.对常用的sql语句使用存储过程(免去了dbms对sql的编译过程,但是降低了可移植性) 6.修改mysql配置(my.ini),比如mysql最大并发量,缓存之类的配置 7.碎片整理

ThinkPHP的缓存技术

原文:ThinkPHP的缓存技术 如果没有缓存的网站是百万级或者千万级的访问量,会给数据库或者服务器造成很大的压力,通过缓存,大幅减少服务器和数据库的负荷.假如我们 把读取数据的过程分为三个层,第一个是访问层,第一个是缓存层,第三个是数据库存取层.如果没有缓存层,访问层是直接从数据库存取层读取数据,而设置缓存 后,访问层不再是直接在数据库存取层读取,而是从缓存层读取数据.我们做个简单的对比,假设一个页面,在一个小时可被访问100万次,如 果这个页面每次被访问的时候,都直接读取数据库后再编译生成,

Gz_缓存技术1

目录 一.判断大型网站的标准:    1 1.pv(page views)网页的浏览量:    1 2.uv值(unique vistor)独立访客    1 3.独立ip,    1 二.大型网站带来的一些问题.    1 1.大的并发.    1 2.大流量.    2 3.大的存储,    2 三.大并发的解决方案:    2 1.负载均衡器:    2 2.负载均衡实现的方式:    3 3.集群:    3 四.大流量解决方案:    3 1.防止我们的网站资源被盗链.    3 2.

详细讲解PHP中缓存技术的应用

PHP,一门最近几年兴起的web设计脚本语言,由于它的强大和可伸缩性,近几年来得到长足的发展,php相比传统的asp网站,在速度上有绝对的优势,想mssql转6万条数据php如需要40秒,asp不下2分钟.但是,由于网站的数据越来越多,我们渴求能更快速的调用数据,不必要每次都从数据库掉,我们可以从其他的地方,比方一个文件,或者某个内存地址,这就是php的缓存技术,也就是Cache技术. 一般来说,缓存的目的是把数据放在一个地方让访问的更快点,毫无疑问,内存是最快的,但是,几百M的数据能往内存放么

php缓存技术介绍

      缓存是指临时文件交换区,电脑把最常用的文件从存储器里提出来临时放在缓存里,就像把工具和材料搬上工作台一样,这样会比用时现去仓库取更方便.因为缓存往往使用的是RAM(断电即掉的非永久储存),所以在忙完后还是会把文件送到硬盘等存储器里永久存储.电脑里最大的缓存就是内存条了,最快的是CPU上镶的L1和L2缓存,显卡的显存是给GPU用的缓存,硬盘上也有16M或者32M的缓存.千万不能把缓存理解成一个东西,它是一种处理方式的统称! 在WEB开发中用来应付高流量最有效的办法就是用缓存技术,能有效