IT log

moral & concision is my dream.

Archive for May, 2008

PHP的SQL查询缓存

更新时间:2008-05-30 02:54:10 来源:网络 作者:未知
本教程使用MySQL作为数据库。你需要安装MySQL(www.mysql.com下载是有效的)和激活PHP MYSQL扩展(默认情况是激活的)。

由于要查询数据库,你需要知识一些SQL(结构化查询语言)的基本常识。

缓存SQL查询结果

为什么要缓存查询结果?

缓存查询结果能极大地改进脚本执行时间和资源需求。

缓存SQL查询结果也允许你通过后期处理数据。如果你用文件缓存去存储全部脚本的输出结果(HTML输出),这样可能是行不通的。

以上方法非常占用资源并且相反的影响了脚本的性能。只能通过取得的大量返回数据和数据库服务器的位置这二个要素来相互协调。尽管持续连接可以改进连接数据库时的负载,但非常耗费内存资源,如果获取的是大量的数据,那么存储的全部时间会非常短暂。

创建一条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

category_name

category_description
int(10) unsigned

varchar(255)

text
PRI
auto_incremen

在本例中,通过时间触发缓存技术被运用,设定一段时间后让其缓存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);

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));

} 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);

    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

posted by Leon Tsang in Library - Knowledge and Power and have No Comments

QTTabBat log

1.2008-5-27 10:10:22
导出软件设置的方法:
在QTTbarBar工具栏空白处点击鼠标右键,进行“Options”:
然后选择“General”标签,点击“Export settings…”按钮,即可。

posted by Leon Tsang in Default - News and Truth and have No Comments

OpenOffice.org v2.3 log

18:27 2008-1-20
1.在安装了OpenOffice后,C:\Documents and Settings\Administrator\Application Data\Sun目录里会有一个Java Jre的备份安装程序。

2.最近文档、表格、演示等文件自动备份路径:
C:\Documents and Settings\Administrator\Application Data\OpenOffice.org2\user\backup

3.各种自定义设置优化等保存位置:
C:\Documents and Settings\Administrator\Application Data\OpenOffice.org2\user\registry\data

=========================
OpenOffice.org 2.3 Datebase 设置

1. 20:36 2008-1-19
症状:无法打开MS Office的MDB数据库文件。
解决:打开OpenOffice.org Datebase 进入“Database Wizard”界面,在“Connect to an existing database”下拉框选择“Microsoft Access”,然后进行下一步选择mdb文件,最后会要求新建一个odb数据库文件。
以后每次打开这个ODB,就相当于打开了MDB,是利用系统本身的数据库接口连接到MDB文件,所有的更改都体现在MDB里面。

==========================
OpenOffice.org Calc 技巧

1.0:29 2008-1-19
注意:列数据筛选功能在“Data”"Filter""Auto Filter"中,但一个ods文件只能有一个表单启用筛选功能,其他表单启用后,前一个表单的筛选功能将自动取消。

2. 如何较快速的输入当前日期?
方法:在单元格中输入“=today()”,然后按F9,最后回车确认,即可。
第一次使用了today()函数后,以后如在同一文档中,输入=to就会提示today(),这是按回车确认,然后就按F9,最后在回车。
PS:没有了在Office excel很方便的按“Ctrl+;”就可以自动输入日期的功能。

3. 17:05 2008-1-24
对于输入邮件和网址时不像在exce中在文字前输入"’"就可以自动识别为文本,导致被自动识别为链接形式的改正方法:
右击单元格在弹出菜单选择“Default Formatting”,即可。

4. 14:00 2008-1-25
问题:如何取消文本被自动识别为网页链接和邮件链接?
方法:进入工具菜单"Tools"-"AutoCorrect"中,“Options”标签中取消选择“URL Recongnition”项,即可。

5.快速日期格式化和单元格文本垂直对齐:
先调出 Formatting Toolbar (默认显示的 Text Formatting Toolbar),重启 Calc后前者会替代后者来显示。
在Formatting Toolbar 最右边点击向下三角按钮,打开“Visible Buttons”下级菜单,选中“Align Center Vertically” 和“Number Format : Date”。

6.15:37 2008-1-28
在Tools – Customize – Keyboard中可以查看快捷键设置:
快捷键     作用
F2     显示当前的函数公式(只对数值是由公式计算的单元格有效)
F11     预定义表格样式
Insert    选择性粘贴
backspace   删除内容(不弹出对话框)
Ctrl+1    弹出格式化单元格窗口
Ctrl+D    显示当前列的所有值
Ctrl+Shift+Space 恢复默认格式
Ctrl+L    左对齐
Ctrl+R    右对齐
Ctrl+R    居中对齐
Ctrl+J    全文对齐
Shift+Space   选中当前行
Ctrl+Space   选中当前列(与输入法切换冲突)
Shift+Home   选中当前行左部分
Shift+End   选中当前行右部分
Shift+PgUp   选中当前列的上页部分
Shift+PgDn   选中当前列的下页部分

7. 15:37 2008-1-28
注意:OpenOffice.org Calc中,函数参数的间隔符为";"而在MS Excel中的参数间隔符为","。
比如:在MS Excel中,IF(A1>100,A1*1.05,100*.105),要在Calc中写为,IF(A1>100;A1*1.05;100*.105)

8. 15:06 2008-4-16
Tip:当输入一两个字符时,可能会出现黑底白字的自动识别提示。
这是按 “Tab” 键就可以在多个可能的自动识别或自动完成中切换所需要的内容。

9.2008-5-26 23:58:34
在筛选某一个值进行Filter过滤后,不要在当前的过滤后的视图中,拖动鼠标来复制行,
注意:这样会导致复制行和被复制行之间的被视图所隐藏的间隔行也被赋予同样的值,这样数据就会出现错误

10.2008-5-27 0:01:48
对表格排序时要以某列为主,当不仅要选择该列,还需要选中其他需要以该列为主键进行排序的列,
否则:只有选中的那一列进行数据排序,而其他列中数据顺序没有改变,使得表格数据混乱错误。

====================
OpenOffice.org Writer 技巧

1.解决打开中文文件时难看的字体问题。
“Tools”"Option"“OpenOffice.org Writer”“Basic Fonts(Asian)”就在这里把"Heading"修改为黑体,其他的都修改为宋体即可。
PS:如是在用右键菜单"新建"的"新建 OpenDocument Text.odt"文档,则之前的字体修改无法生效;一定要通过系统状态栏和开始菜单等方法直接运行“OpenOffice.org Writer”或“Text Document”程序生成的空白文档,才能使得之前修改的字体生效。在C盘没有搜索到其默认的空白模板文件。

2.去掉字母下的红线,即英语拼写检查。
在“Language Settings”“Writing Aids”中不要选择“OpenOffice.org Hunspell SpellChecker”,即可。

3.去掉查看文档时显示的边界线。
取消选择“View”-"Text Boundaries",即可。

4. 症状:图片空白边缘部分压住了表格边框线,调整图片层次到最低也没有作用。
解决:打开图片属性“Picture – Wrap”,改变“Spacing – Bottom”的值从“0.00cm”到"0.01cm",即可。

5.让外部(网页图片)图文混排格式能准确复制粘贴到稳定的方法。
方法:
1.最快的。把网页复制后,先粘贴到Nvu上,然后从Nvu粘贴到Writer中。
2.适合图片少的页面。先只粘贴无格式文本到Writer中,然后在需要插入图片的地方,加入一个硬回车换行,最后把需要图片复制粘贴到硬回车之后,即可。
3.适合想进行复杂的自定义图片排列。在Writer中先建立好table,然后在所需要的地方粘贴文本和图片。

6.设置快捷键–
在Tools – Customize – Keyboard中可以查看快捷键设置:
快捷键     作用
Ctrl+Shift+v 选择性粘贴

7.隐藏(不显示)无边框的表格浅灰色线条(边界):
在常用菜单 Table 中 勾销 Table Boundaries 即可。

8.删除空白表格的方法:
在所要删除的表格中点击右键菜单选择 Row – Delete

9.表格内单元格垂直居中对齐:
选中需要垂直对齐的单元格或行或列
a.在常用菜单 Format – Alignment 中上部分是水平对齐,下部分是垂直对齐的选项;
b.或在右键菜单 Cell 中选择 Center 即可。
ps:右键菜单中的 Alignment 只能调整水平对齐。

10.取消文本自动识别完成;
Tools – AutoCorrect – Word Comletion 勾销Enable word completion和Collect words

11.自动生成预定义的表格样式:
点击常用菜单或工具栏,弹出Insert Table对话框,单击左下角的 AutoFormat… 按钮,然后根据需要选择样式。

12.生成目录索引和链接技巧:
点击常用菜单或工具栏中 Insert – Index and Tables ,对话框默认选择了 "Protected against manual changes",会导致生成后的目录索引无法手动更改。
进入 Entries 标签 中 Structure 的右边是索引的组成结构,点击 “E”(代表索引条目的标题) 按钮左边的空格,然后再点击右下边的“Hyperlink”按钮(会在“E”左边插入 “LS” );点击 “E” 按钮右边的空格,然后再点击右下边的“Hyperlink”按钮(会在“E”左边插入 “LE” )。这样生成的索引条目就才能链接到各部分标题去。
ps:勾选 Additional Styles 后,在其右边的按钮弹出窗口中可选择自定义的样式文本来生成标题.

13.快速插入当前时间和日期:
显示 Insert Toolbar , 就点击 chart(图表)左边的下三角符合,即可选择需要插入的时间或日期。

2009/2/2 21:32:51
14.中文的简繁转换:
常用菜单栏“Tools"-"Language"-"Chinese translation…",然后在弹出对话框选择相应项目即可。

posted by Leon Tsang in Default - News and Truth and have No Comments