本教程适合于那些对缓存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

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

  1. php缓存技术总结

          缓存是指临时文件交换区,电脑把最常用的文件从存储器里提出来临时放在缓存里,就像把工具和材料搬上工作台一样,这样会比用时现去仓库取更方便.因为缓存往往使用的是RAM(断电即掉的非永久储存), ...

  2. 网站缓存技术总结( ehcache、memcache、redis对比)

    网站技术高速发展的今天,缓存技术已经成为大型网站的一个关键技术,缓存设计好坏直接关系的一个网站访问的速度,以及购置服务器的数量,甚至影响到用户的体验. 网站缓存按照存放的地点不同,可以分为客户端缓存. ...

  3. PHP网页缓存技术

    http://blog.sina.com.cn/s/blog_646e51c40100weu9.html 前台静态化:把动态页面解析后保存为静态页面 文件缓存:把查询结果保存为文件,XML 内存缓存: ...

  4. ThinkPHP的缓存技术

    原文:ThinkPHP的缓存技术 如果没有缓存的网站是百万级或者千万级的访问量,会给数据库或者服务器造成很大的压力,通过缓存,大幅减少服务器和数据库的负荷.假如我们 把读取数据的过程分为三个层,第一个 ...

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

    PHP,一门最近几年兴起的web设计脚本语言,由于它的强大和可伸缩性,近几年来得到长足的发展,php相比传统的asp网站,在速度上有绝对的优势,想mssql转6万条数据php如需要40秒,asp不下2 ...

  6. PHP缓存技术的多种方法小结

    这里所说的数据缓存是指数据库查询PHP缓存机制,每次访问页面的时候,都会先检测相应的缓存数据是否存在,如果不存在,就连接数据库,得到数据,并把查询结果序列化后保存到文件中,以后同样的查询结果就直接从缓 ...

  7. ThinkPHP 缓存技术详解 使用大S方法

    如果没有缓存的网站是百万级或者千万级的访问量,会给数据库或者服务器造成很大的压力,通过缓存,大幅减少服务器和数据库的负荷,假如我们把读取数据的过程分为三个层,第一个是访问层,第一个是缓存层,第三个是数 ...

  8. MySQL缓存参数优化(转)

    MySQL 数据库性能优化之缓存参数优化 数据库属于 IO 密集型的应用程序,其主要职责就是数据的管理及存储工作.而我们知道,从内存中读取一个数据库的时间是微秒级别,而从一块普通硬盘上读取一个IO是在 ...

  9. java缓存技术的介绍

    一.什么是缓存1.Cache是高速缓冲存储器 一种特殊的存储器子系统,其中复制了频繁使用的数据以利于快速访问2.凡是位于速度相差较大的两种硬件/软件之间的,用于协调两者数据传输速度差异的结构,均可称之 ...

随机推荐

  1. 洛谷P1144 最短路计数 及其引申思考

    图论题目练得比较少,发一道spfa的板子题目- 题目:P1144 题目描述 给出一个N个顶点M条边的无向无权图,顶点编号为1-N.问从顶点1开始,到其他每个点的最短路有几条. 输入输出格式 输入格式: ...

  2. 【BZOJ1443】游戏(二分图匹配,博弈论)

    [BZOJ1443]游戏(二分图匹配,博弈论) 题面 BZOJ 题解 很明显的二分图博弈问题. 发现每次移动一定是从一个黑点到达一个白点,或者反过来. 所以可以对于棋盘进行染色然后连边. 考虑一下必胜 ...

  3. dorado7常用内容

    1.dataset添加数据this.get("#dsProduct").getData().insert();或者this.get("#dsProduct"). ...

  4. JS中如何使用EL表达式中的对象

    JS中如何使用EL表达式中的对象 2017年09月25日 15:33:09 lhpnba 阅读数:4859   1.js中使用el表达式要加双引号或单引号:'${list}' 2.js变量获取el表达 ...

  5. 手脱UPX v0.89.6 - v1.02

    声明: 只为纪录自己的脱壳历程,高手勿喷 这个壳的脱法很多一般都一步直达的,步过我喜欢ESP定律 1.载入OD,在入口下一行ESP定律运行一次 > pushad ; //入口 BE mov es ...

  6. 「Python」35个知识点

    No.1 一切皆对象 众所周知,Java中强调“一切皆对象”,但是Python中的面向对象比Java更加彻底,因为Python中的类(class)也是对象,函数(function)也是对象,而且Pyt ...

  7. mysql 自动记录数据插入及最后修改时间

    总结: `uptime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP 原文 应用场景: 1.在数据 ...

  8. Cochran’s Q Test

    sklearn实战-乳腺癌细胞数据挖掘(博客主亲自录制视频教程) https://study.163.com/course/introduction.htm?courseId=1005269003&a ...

  9. 2015年IPC网络摄像机技术发展现状分析

    网络摄像机将图像转换为基于TCP/IP网络标准的数据包,使摄像机所摄的画面通过RJ-45以太网接口或WIFI WLAN无线接口直接传送到网络上,通过网络即可远端监视画面. 一.网络摄像机的基本原理 网 ...

  10. 2017北京国庆刷题Day5 morning

    期望得分:0+60+60=120 实际得分:0+30+60=90 令g=gcd(X11,X12,X13……) 则行列式可能为D的充要条件为g|D 1.g|D为必要条件: 由定义来算行列式的时候,每一项 ...