<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>博客园-Just do it</title><link>http://www.cnblogs.com/xujiaci/</link><description>

 
</description><language>zh-cn</language><lastBuildDate>Sun, 12 Oct 2008 19:01:40 GMT</lastBuildDate><pubDate>Sun, 12 Oct 2008 19:01:40 GMT</pubDate><ttl>60</ttl><item><title>推荐--jQuery使用手册 </title><link>http://www.cnblogs.com/xujiaci/archive/2008/08/23/1274627.html</link><dc:creator>Jacky_Xu</dc:creator><author>Jacky_Xu</author><pubDate>Sat, 23 Aug 2008 03:58:00 GMT</pubDate><guid>http://www.cnblogs.com/xujiaci/archive/2008/08/23/1274627.html</guid><wfw:comment>http://www.cnblogs.com/xujiaci/comments/1274627.html</wfw:comment><comments>http://www.cnblogs.com/xujiaci/archive/2008/08/23/1274627.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/xujiaci/comments/commentRss/1274627.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/xujiaci/services/trackbacks/1274627.html</trackback:ping><description><![CDATA[摘要: 翻译整理：Young.J官方网站：http://jquery.com jQuery是一款同prototype一样优秀js开发库类，特别是对css和XPath的支持，使我们写js变得更加方便！如果你不是个js高手又想写出优 秀的js效果，jQuery可以帮你达到目的！ 下载地址：Starterkit （http://jquery.bassistance.de/jquery-starterkit.zi&nbsp;&nbsp;<a href='http://www.cnblogs.com/xujiaci/archive/2008/08/23/1274627.html'>阅读全文</a><img src ="http://www.cnblogs.com/xujiaci/aggbug/1274627.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42952/" target="_blank">[新闻]微型博客Twitter取消IM服务 称其ROI差</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>一种理想的在关系数据库中存储树型结构数据的方法</title><link>http://www.cnblogs.com/xujiaci/archive/2008/06/24/1229080.html</link><dc:creator>Jacky_Xu</dc:creator><author>Jacky_Xu</author><pubDate>Tue, 24 Jun 2008 09:05:00 GMT</pubDate><guid>http://www.cnblogs.com/xujiaci/archive/2008/06/24/1229080.html</guid><wfw:comment>http://www.cnblogs.com/xujiaci/comments/1229080.html</wfw:comment><comments>http://www.cnblogs.com/xujiaci/archive/2008/06/24/1229080.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/xujiaci/comments/commentRss/1229080.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/xujiaci/services/trackbacks/1229080.html</trackback:ping><description><![CDATA[ 在各种基于关系数据库的应用系统开发中，我们往往需要存储树型结构的数据，目前有很多流行的方法，如邻接列表模型（The Adjacency List Model），在此基础上也有很多人针对不同的需求做了相应的改进，但总是在某些方面存在的各种各样的缺陷。<br>
&nbsp;&nbsp;&nbsp;
那么理想中的树型结构应具备哪些特点呢？数据存储冗余小、直观性强；方便返回整个树型结构数据；可以很轻松的返回某一子树（方便分层加载）；快整获以某节
点的祖谱路径；插入、删除、移动节点效率高等等。带着这些需求我查找了很多资料，发现了一种理想的树型结构数据存储及操作算法，改进的前序遍历树模型
（The Nested Set Model）。
<h1>一、数据</h1>
<p>&nbsp;&nbsp;&nbsp; 在本文中，举一个在线食品店树形图的例子。这个食品店通过类别、颜色和品种来组织食品。树形图如下：</p>
<p style="text-align: left;"><img src="http://www.cnblogs.com/images/cnblogs_com/reonlyrun/blog/o_TreeData.jpg" alt="" border="0"><br>
</p>
<h1>二、邻接列表模型（The Adjacency List Model）</h1>
<p>在这种模型下，上述数据在关系数据库的表结构数据通常如下图所示：</p>
<p><img alt="" src="http://www.cnblogs.com/images/cnblogs_com/reonlyrun/blog/o_ListDBDesign.jpg" width="154" height="236"><br>
</p>
<p>由于该模型比较简单，在此不再详细介绍其算法，下面列出它的一些不足：</p>
<p>&nbsp;&nbsp;&nbsp;
在大多数编程语言中，他运行很慢，效率很差。这主要是“递归”造成的。我们每次查询节点都要访问数据库。每次数据库查询都要花费一些时间，这让函数处理庞
大的树时会十分慢。造成这个函数不是太快的第二个原因可能是你使用的语言。不像Lisp这类语言，大多数语言不是针对递归函数设计的。对于每个节点造成这
个函数不是太快的第二个原因可能是你使用的语言。不像Lisp这类语言，大多数语言不是针对递归函数设计的。对于每个节点，函数都要调用他自己，产生新的
实例。这样，对于一个4层的树，你可能同时要运行4个函数副本。对于每个函数都要占用一块内存并且需要一定的时间初始化，这样处理大树时递归就很慢了。</p>
<h1>三、改进的前序遍历树模型（The Nested Set Model）</h1>
<p style="font-weight: bold;">原理：</p>
<p>&nbsp;&nbsp;&nbsp;
我们先把树按照水平方式摆开。从根节点开始（“Food”），然后他的左边写上1。然后按照树的顺序（从上到下）给“Fruit”的左边写上2。这样，你
沿着树的边界走啊走（这就是“遍历”），然后同时在每个节点的左边和右边写上数字。最后，我们回到了根节点“Food”在右边写上18。下面是标上了数字
的树，同时把遍历的顺序用箭头标出来了。</p>
<p>&nbsp;<img alt="" src="http://www.cnblogs.com/images/cnblogs_com/reonlyrun/blog/o_NestedTree.jpg"><br>
</p>
<p>&nbsp;&nbsp;&nbsp;
我们称这些数字为左值和右值（如，“Food”的左值是1，右值是18）。正如你所见，这些数字按时了每个节点之间的关系。因为“Red”有3和6两个
值，所以，它是有拥有1-18值的“Food”节点的后续。同样的，我们可以推断所有左值大于2并且右值小于11的节点，都是有2-11的“Fruit”
节点的后续。这样，树的结构就通过左值和右值储存下来了。这种数遍整棵树算节点的方法叫做“改进前序遍历树”算法。</p>
<p style="font-weight: bold;">表结构设计：</p>
<p><img alt="" src="http://www.cnblogs.com/images/cnblogs_com/reonlyrun/blog/o_NestedDBDesign.jpg"><br>
</p>
<p style="font-weight: bold;">常用的操作：</p>

<p>下面列出一些常用操作的SQL语句</p>
返回完整的树（Retrieving a Full Tree）
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: rgb(0, 0, 255);">SELECT</span><span style="color: rgb(0, 0, 0);">&nbsp;node.name<br>
&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">FROM</span><span style="color: rgb(0, 0, 0);">&nbsp;nested_category&nbsp;node,&nbsp;nested_category&nbsp;parent<br>
&nbsp;</span><span style="color: rgb(0, 0, 255);">WHERE</span><span style="color: rgb(0, 0, 0);">&nbsp;node.lft&nbsp;</span><span style="color: rgb(128, 128, 128);">BETWEEN</span><span style="color: rgb(0, 0, 0);">&nbsp;parent.lft&nbsp;</span><span style="color: rgb(128, 128, 128);">AND</span><span style="color: rgb(0, 0, 0);">&nbsp;parent.rgt<br>
&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 128, 128);">AND</span><span style="color: rgb(0, 0, 0);">&nbsp;parent.name&nbsp;</span><span style="color: rgb(128, 128, 128);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(255, 0, 0);">'</span><span style="color: rgb(255, 0, 0);">electronics</span><span style="color: rgb(255, 0, 0);">'</span><span style="color: rgb(0, 0, 0);"><br>
&nbsp;</span><span style="color: rgb(0, 0, 255);">ORDER</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">BY</span><span style="color: rgb(0, 0, 0);">&nbsp;node.lft</span></div>
<br>
返回某结点的子树（Find the Immediate Subordinates of a Node）
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: rgb(0, 0, 255);">SELECT</span><span style="color: rgb(0, 0, 0);">&nbsp;V.</span><span style="color: rgb(128, 128, 128);">*</span><span style="color: rgb(0, 0, 0);"><br>
&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">FROM</span><span style="color: rgb(0, 0, 0);">&nbsp;(</span><span style="color: rgb(0, 0, 255);">SELECT</span><span style="color: rgb(0, 0, 0);">&nbsp;node.name,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="color: rgb(255, 0, 255);">COUNT</span><span style="color: rgb(0, 0, 0);">(parent.name)&nbsp;</span><span style="color: rgb(128, 128, 128);">-</span><span style="color: rgb(0, 0, 0);">&nbsp;(</span><span style="color: rgb(255, 0, 255);">AVG</span><span style="color: rgb(0, 0, 0);">(sub_tree.depth)&nbsp;</span><span style="color: rgb(128, 128, 128);">+</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="font-weight: bold; color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">))&nbsp;depth<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">FROM</span><span style="color: rgb(0, 0, 0);">&nbsp;nested_category&nbsp;node,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nested_category&nbsp;parent,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nested_category&nbsp;sub_parent,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="color: rgb(0, 0, 255);">SELECT</span><span style="color: rgb(0, 0, 0);">&nbsp;V.</span><span style="color: rgb(128, 128, 128);">*</span><span style="color: rgb(0, 0, 0);"><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">FROM</span><span style="color: rgb(0, 0, 0);">&nbsp;(</span><span style="color: rgb(0, 0, 255);">SELECT</span><span style="color: rgb(0, 0, 0);">&nbsp;node.name,&nbsp;(</span><span style="color: rgb(255, 0, 255);">COUNT</span><span style="color: rgb(0, 0, 0);">(parent.name)&nbsp;</span><span style="color: rgb(128, 128, 128);">-</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="font-weight: bold; color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">)&nbsp;depth<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">FROM</span><span style="color: rgb(0, 0, 0);">&nbsp;nested_category&nbsp;node,&nbsp;nested_category&nbsp;parent<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">WHERE</span><span style="color: rgb(0, 0, 0);">&nbsp;node.lft&nbsp;</span><span style="color: rgb(128, 128, 128);">BETWEEN</span><span style="color: rgb(0, 0, 0);">&nbsp;parent.lft&nbsp;</span><span style="color: rgb(128, 128, 128);">AND</span><span style="color: rgb(0, 0, 0);">&nbsp;parent.rgt<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 128, 128);">AND</span><span style="color: rgb(0, 0, 0);">&nbsp;node.name&nbsp;</span><span style="color: rgb(128, 128, 128);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(255, 0, 0);">'</span><span style="color: rgb(255, 0, 0);">portable&nbsp;electronics</span><span style="color: rgb(255, 0, 0);">'</span><span style="color: rgb(0, 0, 0);"><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">GROUP</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">BY</span><span style="color: rgb(0, 0, 0);">&nbsp;node.name)&nbsp;V,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nested_category&nbsp;T<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">WHERE</span><span style="color: rgb(0, 0, 0);">&nbsp;V.name&nbsp;</span><span style="color: rgb(128, 128, 128);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;T.name<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">ORDER</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">BY</span><span style="color: rgb(0, 0, 0);">&nbsp;T.lft)&nbsp;sub_tree<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">WHERE</span><span style="color: rgb(0, 0, 0);">&nbsp;node.lft&nbsp;</span><span style="color: rgb(128, 128, 128);">BETWEEN</span><span style="color: rgb(0, 0, 0);">&nbsp;parent.lft&nbsp;</span><span style="color: rgb(128, 128, 128);">AND</span><span style="color: rgb(0, 0, 0);">&nbsp;parent.rgt<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 128, 128);">AND</span><span style="color: rgb(0, 0, 0);">&nbsp;node.lft&nbsp;</span><span style="color: rgb(128, 128, 128);">BETWEEN</span><span style="color: rgb(0, 0, 0);">&nbsp;sub_parent.lft&nbsp;</span><span style="color: rgb(128, 128, 128);">AND</span><span style="color: rgb(0, 0, 0);">&nbsp;sub_parent.rgt<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 128, 128);">AND</span><span style="color: rgb(0, 0, 0);">&nbsp;sub_parent.name&nbsp;</span><span style="color: rgb(128, 128, 128);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;sub_tree.name<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">GROUP</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">BY</span><span style="color: rgb(0, 0, 0);">&nbsp;node.name)&nbsp;V,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nested_category&nbsp;T<br>
&nbsp;</span><span style="color: rgb(0, 0, 255);">WHERE</span><span style="color: rgb(0, 0, 0);">&nbsp;V.name&nbsp;</span><span style="color: rgb(128, 128, 128);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;T.name<br>
&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 128, 128);">and</span><span style="color: rgb(0, 0, 0);">&nbsp;V.depth&nbsp;</span><span style="color: rgb(128, 128, 128);">&lt;=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="font-weight: bold; color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);"><br>
&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 128, 128);">and</span><span style="color: rgb(0, 0, 0);">&nbsp;V.depth&nbsp;</span><span style="color: rgb(128, 128, 128);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="font-weight: bold; color: rgb(128, 0, 0);">0</span><span style="color: rgb(0, 0, 0);"><br>
&nbsp;</span><span style="color: rgb(0, 0, 255);">ORDER</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">BY</span><span style="color: rgb(0, 0, 0);">&nbsp;T.Lft</span></div>
<br>
返回某结点的祖谱路径（Retrieving a Single Path）
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: rgb(0, 0, 255);">SELECT</span><span style="color: rgb(0, 0, 0);">&nbsp;parent.name<br>
&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">FROM</span><span style="color: rgb(0, 0, 0);">&nbsp;nested_category&nbsp;node,&nbsp;nested_category&nbsp;parent<br>
&nbsp;</span><span style="color: rgb(0, 0, 255);">WHERE</span><span style="color: rgb(0, 0, 0);">&nbsp;node.lft&nbsp;</span><span style="color: rgb(128, 128, 128);">BETWEEN</span><span style="color: rgb(0, 0, 0);">&nbsp;parent.lft&nbsp;</span><span style="color: rgb(128, 128, 128);">AND</span><span style="color: rgb(0, 0, 0);">&nbsp;parent.rgt<br>
&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 128, 128);">AND</span><span style="color: rgb(0, 0, 0);">&nbsp;node.name&nbsp;</span><span style="color: rgb(128, 128, 128);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(255, 0, 0);">'</span><span style="color: rgb(255, 0, 0);">flash</span><span style="color: rgb(255, 0, 0);">'</span><span style="color: rgb(0, 0, 0);"><br>
&nbsp;</span><span style="color: rgb(0, 0, 255);">ORDER</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">BY</span><span style="color: rgb(0, 0, 0);">&nbsp;node.lft</span></div>
<br>
返回所有节点的深度（Finding the Depth of the Nodes）
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: rgb(0, 0, 255);">SELECT</span><span style="color: rgb(0, 0, 0);">&nbsp;V.</span><span style="color: rgb(128, 128, 128);">*</span><span style="color: rgb(0, 0, 0);"><br>
&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">FROM</span><span style="color: rgb(0, 0, 0);">&nbsp;(</span><span style="color: rgb(0, 0, 255);">SELECT</span><span style="color: rgb(0, 0, 0);">&nbsp;node.name,&nbsp;(</span><span style="color: rgb(255, 0, 255);">COUNT</span><span style="color: rgb(0, 0, 0);">(parent.name)&nbsp;</span><span style="color: rgb(128, 128, 128);">-</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="font-weight: bold; color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">)&nbsp;depth<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">FROM</span><span style="color: rgb(0, 0, 0);">&nbsp;nested_category&nbsp;node,&nbsp;nested_category&nbsp;parent<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">WHERE</span><span style="color: rgb(0, 0, 0);">&nbsp;node.lft&nbsp;</span><span style="color: rgb(128, 128, 128);">BETWEEN</span><span style="color: rgb(0, 0, 0);">&nbsp;parent.lft&nbsp;</span><span style="color: rgb(128, 128, 128);">AND</span><span style="color: rgb(0, 0, 0);">&nbsp;parent.rgt<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">GROUP</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">BY</span><span style="color: rgb(0, 0, 0);">&nbsp;node.name)&nbsp;V,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nested_category&nbsp;T<br>
&nbsp;</span><span style="color: rgb(0, 0, 255);">WHERE</span><span style="color: rgb(0, 0, 0);">&nbsp;V.name&nbsp;</span><span style="color: rgb(128, 128, 128);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;T.name<br>
&nbsp;</span><span style="color: rgb(0, 0, 255);">ORDER</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">BY</span><span style="color: rgb(0, 0, 0);">&nbsp;T.Lft</span></div>
<br>
返回子树的深度（Depth of a Sub-Tree）
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: rgb(0, 0, 255);">SELECT</span><span style="color: rgb(0, 0, 0);">&nbsp;V.</span><span style="color: rgb(128, 128, 128);">*</span><span style="color: rgb(0, 0, 0);"><br>
&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">FROM</span><span style="color: rgb(0, 0, 0);">&nbsp;(</span><span style="color: rgb(0, 0, 255);">SELECT</span><span style="color: rgb(0, 0, 0);">&nbsp;node.name,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="color: rgb(255, 0, 255);">COUNT</span><span style="color: rgb(0, 0, 0);">(parent.name)&nbsp;</span><span style="color: rgb(128, 128, 128);">-</span><span style="color: rgb(0, 0, 0);">&nbsp;(</span><span style="color: rgb(255, 0, 255);">AVG</span><span style="color: rgb(0, 0, 0);">(sub_tree.depth)&nbsp;</span><span style="color: rgb(128, 128, 128);">+</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="font-weight: bold; color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">))&nbsp;depth<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">FROM</span><span style="color: rgb(0, 0, 0);">&nbsp;nested_category&nbsp;node,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nested_category&nbsp;parent,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nested_category&nbsp;sub_parent,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="color: rgb(0, 0, 255);">SELECT</span><span style="color: rgb(0, 0, 0);">&nbsp;V.</span><span style="color: rgb(128, 128, 128);">*</span><span style="color: rgb(0, 0, 0);"><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">FROM</span><span style="color: rgb(0, 0, 0);">&nbsp;(</span><span style="color: rgb(0, 0, 255);">SELECT</span><span style="color: rgb(0, 0, 0);">&nbsp;node.name,&nbsp;(</span><span style="color: rgb(255, 0, 255);">COUNT</span><span style="color: rgb(0, 0, 0);">(parent.name)&nbsp;</span><span style="color: rgb(128, 128, 128);">-</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="font-weight: bold; color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">)&nbsp;depth<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">FROM</span><span style="color: rgb(0, 0, 0);">&nbsp;nested_category&nbsp;node,&nbsp;nested_category&nbsp;parent<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">WHERE</span><span style="color: rgb(0, 0, 0);">&nbsp;node.lft&nbsp;</span><span style="color: rgb(128, 128, 128);">BETWEEN</span><span style="color: rgb(0, 0, 0);">&nbsp;parent.lft&nbsp;</span><span style="color: rgb(128, 128, 128);">AND</span><span style="color: rgb(0, 0, 0);">&nbsp;parent.rgt<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 128, 128);">AND</span><span style="color: rgb(0, 0, 0);">&nbsp;node.name&nbsp;</span><span style="color: rgb(128, 128, 128);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(255, 0, 0);">'</span><span style="color: rgb(255, 0, 0);">portable&nbsp;electronics</span><span style="color: rgb(255, 0, 0);">'</span><span style="color: rgb(0, 0, 0);"><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">GROUP</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">BY</span><span style="color: rgb(0, 0, 0);">&nbsp;node.name)&nbsp;V,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nested_category&nbsp;T<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">WHERE</span><span style="color: rgb(0, 0, 0);">&nbsp;V.name&nbsp;</span><span style="color: rgb(128, 128, 128);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;T.name<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">ORDER</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">BY</span><span style="color: rgb(0, 0, 0);">&nbsp;T.lft)&nbsp;sub_tree<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">WHERE</span><span style="color: rgb(0, 0, 0);">&nbsp;node.lft&nbsp;</span><span style="color: rgb(128, 128, 128);">BETWEEN</span><span style="color: rgb(0, 0, 0);">&nbsp;parent.lft&nbsp;</span><span style="color: rgb(128, 128, 128);">AND</span><span style="color: rgb(0, 0, 0);">&nbsp;parent.rgt<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 128, 128);">AND</span><span style="color: rgb(0, 0, 0);">&nbsp;node.lft&nbsp;</span><span style="color: rgb(128, 128, 128);">BETWEEN</span><span style="color: rgb(0, 0, 0);">&nbsp;sub_parent.lft&nbsp;</span><span style="color: rgb(128, 128, 128);">AND</span><span style="color: rgb(0, 0, 0);">&nbsp;sub_parent.rgt<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 128, 128);">AND</span><span style="color: rgb(0, 0, 0);">&nbsp;sub_parent.name&nbsp;</span><span style="color: rgb(128, 128, 128);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;sub_tree.name<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">GROUP</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">BY</span><span style="color: rgb(0, 0, 0);">&nbsp;node.name)&nbsp;V,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nested_category&nbsp;T<br>
&nbsp;</span><span style="color: rgb(0, 0, 255);">WHERE</span><span style="color: rgb(0, 0, 0);">&nbsp;V.name&nbsp;</span><span style="color: rgb(128, 128, 128);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;T.name<br>
&nbsp;</span><span style="color: rgb(0, 0, 255);">ORDER</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">BY</span><span style="color: rgb(0, 0, 0);">&nbsp;T.Lft</span></div>
<br>
返回所有的叶子节点（Finding all the Leaf Nodes）
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: rgb(0, 0, 255);">SELECT</span><span style="color: rgb(0, 0, 0);">&nbsp;name&nbsp;</span><span style="color: rgb(0, 0, 255);">FROM</span><span style="color: rgb(0, 0, 0);">&nbsp;nested_category&nbsp;</span><span style="color: rgb(0, 0, 255);">WHERE</span><span style="color: rgb(0, 0, 0);">&nbsp;rgt&nbsp;</span><span style="color: rgb(128, 128, 128);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;lft&nbsp;</span><span style="color: rgb(128, 128, 128);">+</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="font-weight: bold; color: rgb(128, 0, 0);">1</span></div>
<br>
插入节点（Adding New Nodes）
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: rgb(0, 0, 0);">LOCK&nbsp;</span><span style="color: rgb(0, 0, 255);">TABLE</span><span style="color: rgb(0, 0, 0);">&nbsp;nested_category&nbsp;WRITE;<br>
<br>
</span><span style="color: rgb(0, 0, 255);">SELECT</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 128, 0);">@myRight</span><span style="color: rgb(0, 0, 0);">&nbsp;:</span><span style="color: rgb(128, 128, 128);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;rgt&nbsp;</span><span style="color: rgb(0, 0, 255);">FROM</span><span style="color: rgb(0, 0, 0);">&nbsp;nested_category&nbsp;</span><span style="color: rgb(0, 0, 255);">WHERE</span><span style="color: rgb(0, 0, 0);">&nbsp;name&nbsp;</span><span style="color: rgb(128, 128, 128);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(255, 0, 0);">'</span><span style="color: rgb(255, 0, 0);">TELEVISIONS</span><span style="color: rgb(255, 0, 0);">'</span><span style="color: rgb(0, 0, 0);">;<br>
<br>
</span><span style="color: rgb(0, 0, 255);">UPDATE</span><span style="color: rgb(0, 0, 0);">&nbsp;nested_category&nbsp;</span><span style="color: rgb(0, 0, 255);">SET</span><span style="color: rgb(0, 0, 0);">&nbsp;rgt&nbsp;</span><span style="color: rgb(128, 128, 128);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;rgt&nbsp;</span><span style="color: rgb(128, 128, 128);">+</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="font-weight: bold; color: rgb(128, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">WHERE</span><span style="color: rgb(0, 0, 0);">&nbsp;rgt&nbsp;</span><span style="color: rgb(128, 128, 128);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 128, 0);">@myRight</span><span style="color: rgb(0, 0, 0);">;<br>
</span><span style="color: rgb(0, 0, 255);">UPDATE</span><span style="color: rgb(0, 0, 0);">&nbsp;nested_category&nbsp;</span><span style="color: rgb(0, 0, 255);">SET</span><span style="color: rgb(0, 0, 0);">&nbsp;lft&nbsp;</span><span style="color: rgb(128, 128, 128);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;lft&nbsp;</span><span style="color: rgb(128, 128, 128);">+</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="font-weight: bold; color: rgb(128, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">WHERE</span><span style="color: rgb(0, 0, 0);">&nbsp;lft&nbsp;</span><span style="color: rgb(128, 128, 128);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 128, 0);">@myRight</span><span style="color: rgb(0, 0, 0);">;<br>
<br>
</span><span style="color: rgb(0, 0, 255);">INSERT</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">INTO</span><span style="color: rgb(0, 0, 0);">&nbsp;nested_category<br>
&nbsp;&nbsp;(name,&nbsp;lft,&nbsp;rgt)<br>
</span><span style="color: rgb(0, 0, 255);">VALUES</span><span style="color: rgb(0, 0, 0);"><br>
&nbsp;&nbsp;(</span><span style="color: rgb(255, 0, 0);">'</span><span style="color: rgb(255, 0, 0);">GAME&nbsp;CONSOLES</span><span style="color: rgb(255, 0, 0);">'</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 128, 0);">@myRight</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 128, 128);">+</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="font-weight: bold; color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 128, 0);">@myRight</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 128, 128);">+</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="font-weight: bold; color: rgb(128, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">);<br>
<br>
UNLOCK&nbsp;TABLES;</span></div>
<br>
删除节点（Deleting Nodes）
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: rgb(0, 0, 0);">LOCK&nbsp;</span><span style="color: rgb(0, 0, 255);">TABLE</span><span style="color: rgb(0, 0, 0);">&nbsp;nested_category&nbsp;WRITE;<br>
<br>
</span><span style="color: rgb(0, 0, 255);">SELECT</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 128, 0);">@myLeft</span><span style="color: rgb(0, 0, 0);">&nbsp;:</span><span style="color: rgb(128, 128, 128);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;lft,&nbsp;</span><span style="color: rgb(0, 128, 0);">@myRight</span><span style="color: rgb(0, 0, 0);">&nbsp;:</span><span style="color: rgb(128, 128, 128);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;rgt,&nbsp;</span><span style="color: rgb(0, 128, 0);">@myWidth</span><span style="color: rgb(0, 0, 0);">&nbsp;:</span><span style="color: rgb(128, 128, 128);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;rgt&nbsp;</span><span style="color: rgb(128, 128, 128);">-</span><span style="color: rgb(0, 0, 0);">&nbsp;lft&nbsp;</span><span style="color: rgb(128, 128, 128);">+</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="font-weight: bold; color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);"><br>
&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">FROM</span><span style="color: rgb(0, 0, 0);">&nbsp;nested_category<br>
&nbsp;</span><span style="color: rgb(0, 0, 255);">WHERE</span><span style="color: rgb(0, 0, 0);">&nbsp;name&nbsp;</span><span style="color: rgb(128, 128, 128);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(255, 0, 0);">'</span><span style="color: rgb(255, 0, 0);">GAME&nbsp;CONSOLES</span><span style="color: rgb(255, 0, 0);">'</span><span style="color: rgb(0, 0, 0);">;<br>
<br>
</span><span style="color: rgb(0, 0, 255);">DELETE</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">FROM</span><span style="color: rgb(0, 0, 0);">&nbsp;nested_category&nbsp;</span><span style="color: rgb(0, 0, 255);">WHERE</span><span style="color: rgb(0, 0, 0);">&nbsp;lft&nbsp;</span><span style="color: rgb(128, 128, 128);">BETWEEN</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 128, 0);">@myLeft</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 128, 128);">AND</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 128, 0);">@myRight</span><span style="color: rgb(0, 0, 0);">;<br>
<br>
</span><span style="color: rgb(0, 0, 255);">UPDATE</span><span style="color: rgb(0, 0, 0);">&nbsp;nested_category&nbsp;</span><span style="color: rgb(0, 0, 255);">SET</span><span style="color: rgb(0, 0, 0);">&nbsp;rgt&nbsp;</span><span style="color: rgb(128, 128, 128);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;rgt&nbsp;</span><span style="color: rgb(128, 128, 128);">-</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 128, 0);">@myWidth</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">WHERE</span><span style="color: rgb(0, 0, 0);">&nbsp;rgt&nbsp;</span><span style="color: rgb(128, 128, 128);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 128, 0);">@myRight</span><span style="color: rgb(0, 0, 0);">;<br>
</span><span style="color: rgb(0, 0, 255);">UPDATE</span><span style="color: rgb(0, 0, 0);">&nbsp;nested_category&nbsp;</span><span style="color: rgb(0, 0, 255);">SET</span><span style="color: rgb(0, 0, 0);">&nbsp;lft&nbsp;</span><span style="color: rgb(128, 128, 128);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;lft&nbsp;</span><span style="color: rgb(128, 128, 128);">-</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 128, 0);">@myWidth</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">WHERE</span><span style="color: rgb(0, 0, 0);">&nbsp;lft&nbsp;</span><span style="color: rgb(128, 128, 128);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 128, 0);">@myRight</span><span style="color: rgb(0, 0, 0);">;<br>
<br>
UNLOCK&nbsp;TABLES;</span></div>
<strong></strong>
<p>&nbsp;</p>

<p><span style="font-weight: bold;"><br>
</span></p>
<p><span style="font-weight: bold;">[</span><span style="font-weight: bold;">参考资料]</span><a href="http://dev.mysql.com/tech-resources/articles/hierarchical-data.html"><br>
</a></p>
<p><a href="http://dev.mysql.com/tech-resources/articles/hierarchical-data.html">http://dev.mysql.com/tech-resources/articles/hierarchical-data.html</a></p>
<p><a href="http://www.nirvanastudio.org/php/hierarchical-data-database.html">http://www.nirvanastudio.org/php/hierarchical-data-database.html</a></p><img src ="http://www.cnblogs.com/xujiaci/aggbug/1229080.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42951/" target="_blank">[新闻]用手机聊Gtalk的方法以及应用总结</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>资料收集：高并发 高性能 高扩展性 Web 2.0 站点架构设计及优化策略 </title><link>http://www.cnblogs.com/xujiaci/archive/2008/06/17/1209074.html</link><dc:creator>Jacky_Xu</dc:creator><author>Jacky_Xu</author><pubDate>Tue, 17 Jun 2008 02:29:00 GMT</pubDate><guid>http://www.cnblogs.com/xujiaci/archive/2008/06/17/1209074.html</guid><wfw:comment>http://www.cnblogs.com/xujiaci/comments/1209074.html</wfw:comment><comments>http://www.cnblogs.com/xujiaci/archive/2008/06/17/1209074.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/xujiaci/comments/commentRss/1209074.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/xujiaci/services/trackbacks/1209074.html</trackback:ping><description><![CDATA[<p><a href="http://www.fulin.org/paper/paper.html"><span style="font-family: 宋体;">高并发高流量网站架构</span></a> </p>
<p><span><a href="http://www.toplee.com/blog/71.html">» <span style="font-family: 宋体;">说说大型高并发高负载网站的系统架构</span><span style="font-family: 宋体;">俊麟</span> Michael`s blog</a> </span></p>
<p><a id="rdf:#$Eywor1" href="http://www.example.net.cn/archives/2006/03/olivejournaloio.html"><span style="font-family: 宋体;">从LiveJournal<span style="font-family: 宋体;">后台发展看大规模网站性能优化方法</span>: <span style="font-family: 宋体;">一个藏袍</span></span></a> </p>
<p><a href="http://www.example.net.cn/2006/01/memcached.html"><span style="font-family: 宋体;">使用memcached<span style="font-family: 宋体;">进行内存缓存</span>: <span style="font-family: 宋体;">一个藏袍</span></span></a> </p>
<p><a href="http://www.example.net.cn/2006/06/open_source_high_performance.html"><span style="font-family: 宋体;">使用开源软件，设计高性能可扩展网站: <span style="font-family: 宋体;">一个藏袍</span></span></a> </p>
<p><a href="http://www.example.net.cn/2006/01/bind_dlz.html">bind dlz - <span style="font-family: 宋体;">分布式系统的请求分发工具: <span style="font-family: 宋体;">一个藏袍</span></span></a> </p>
<p><a href="http://www.example.net.cn/2006/09/startup_and_opensource.html"><span style="font-family: 宋体;">初创网站与开源软件: <span style="font-family: 宋体;">一个藏袍</span></span></a> </p>
<p><span><a href="http://www.dbanotes.net/database/craigslist_database_arch.html">Craigslist <span style="font-family: 宋体;">的数据库架构</span> - DBA notes</a> </span></p>
<p><span><a id="rdf:#$kAwor1" href="http://www.dbanotes.net/web/flickr_web_tech.html">Flickr <span style="font-family: 宋体;">的开发者的</span> Web <span style="font-family: 宋体;">应用优化技巧</span> - DBA notes</a> </span></p>
<p><a id="rdf:#$iAwor1" href="http://www.dbanotes.net/opensource/youtube_web_arch.html">YouTube <span style="font-family: 宋体;">的架构扩展 - DBA notes</span></a> </p>
<p><a id="rdf:#$jAwor1" href="http://www.dbanotes.net/web/technorati_db_arch.html"><span style="font-family: 宋体;">了解一下 Technorati <span style="font-family: 宋体;">的后台数据库架构</span> - DBA notes</span></a> </p>
<p><a id="rdf:#$5IbjV1" href="http://blog.csdn.net/guxianga/archive/2007/09/19/1791131.aspx"><span style="font-family: 宋体;">大型Web2.0<span style="font-family: 宋体;">站点构建技术初探</span> - guxianga - CSDNBlog</span></a> </p>
<p><a href="http://live.csdn.net/Issue234/LivePlay.aspx">CSDN<span style="font-family: 宋体;">视频：CSDN SD<span style="font-family: 宋体;">俱乐部与钱宏武探讨如何设计高并发体系架构</span></span></a> <br>你真的明白什么是可伸缩性吗？<br><a href="http://www.infoq.com/cn/news/2007/10/whatisscalability" target="_new">http://www.infoq.com/cn/news/2007/10/whatisscalability</a><br><br>真正的线性可伸缩性需要新的模式和中间件架构吗？——说实话这篇有些难，还没有看明白 <br><a href="http://www.infoq.com/cn/news/2007/08/scalability-patterns" target="_new">http://www.infoq.com/cn/news/2007/08/scalability-patterns</a><br>在高并发、高性能的网站中，缓存的使用是非常重要的，下面有两篇非常不错的文章专门介绍这个主题。<br><br>理解缓存<br><a href="http://blog.joycode.com/ghj/archive/2007/09/01/107863.aspx" target="_new"><font color="#1d58d1">http://blog.joycode.com/ghj/archive/2007/09/01/107863.aspx</font></a><br><br>也说缓存<br><a href="http://blog.joycode.com/peon/archive/2007/09/05/108033.aspx" target="_new"><font color="#1d58d1">http://blog.joycode.com/peon/archive/2007/09/05/108033.aspx</font></a><br>通过了解MySpace的六次重构经历,来认识分布式系统到底该如何创建. <br><a href="/wuxilin/archive/2007/07/17/820482.html" target="_new"><font color="#1d58d1">http://www.cnblogs.com/wuxilin/archive/2007/07/17/820482.html</font></a> <br><br>如何走出海量数据及访问量压力困境 <br><a href="http://tech.it168.com/i/2007-04-24/200704240835046.shtml" target="_new"><font color="#1d58d1">http://tech.it168.com/i/2007-04-24/200704240835046.shtml</font></a> <br><br>奥运订票网站瘫痪 开发商技术能力遭质疑 <br><a href="http://tech.it168.com/i/2007-11-05/200711051858734.shtml" target="_new"><font color="#1d58d1">http://tech.it168.com/i/2007-11-05/200711051858734.shtml</font></a> <br><br>开发大型高负载类网站应用的几个要点 <br><a href="http://tech.it168.com/i/2007-11-13/200711130959718.shtml" target="_new"><font color="#1d58d1">http://tech.it168.com/i/2007-11-13/200711130959718.shtml</font></a> <br><br>SD2.0大会上关于“大型网站架构技术”的讨论(同记) <br><a href="http://space.itpub.net/?uid-7311285-action-viewspace-itemid-103777" target="_new"><font color="#1d58d1">http://space.itpub.net/?uid-7311285-action-viewspace-itemid-103777</font></a> <br><br>如何提高网页的效率 14条建议 <br><a href="http://tech.it168.com/msoft/2007-10-29/200710291906187.shtml" target="_new"><font color="#1d58d1">http://tech.it168.com/msoft/2007-10-29/200710291906187.shtml</font></a> <br>Google背后的IT架构策略揭秘 <br><a href="http://news.csdn.net/n/20071010/109444.html" target="_new"><font color="#1d58d1">http://news.csdn.net/n/20071010/109444.html</font></a> <br><br>eBay 的数据库分布扩展架构 <br><a href="http://www.dbanotes.net/database/ebay_database_scale_out.html" target="_new"><font color="#1d58d1">http://www.dbanotes.net/database/ebay_database_scale_out.html</font></a> <br><br>eBay 的应用服务器规模 <br><a href="http://www.dbanotes.net/web/ebay_application_server.html" target="_new"><font color="#1d58d1">http://www.dbanotes.net/web/ebay_application_server.html</font></a> <br><br>eBay 的存储一瞥 <br><a href="http://www.dbanotes.net/arch/ebay_storage.html" target="_new"><font color="#1d58d1">http://www.dbanotes.net/arch/ebay_storage.html</font></a> <br><br>eBay 的数据量 <br><a href="http://www.dbanotes.net/database/ebay_storage.html" target="_new"><font color="#1d58d1">http://www.dbanotes.net/database/ebay_storage.html</font></a> <br><br>这些大网站都用什么操作系统与 Web 服务器 ? <br><a href="http://www.dbanotes.net/web/bigsite_web_os_and_server.html" target="_new"><font color="#1d58d1">http://www.dbanotes.net/web/bigsite_web_os_and_server.html</font></a> <br><br>Yupoo! 的网站技术架构 <br><a href="http://www.dbanotes.net/arch/yupoo_arch.html" target="_new"><font color="#1d58d1">http://www.dbanotes.net/arch/yupoo_arch.html</font></a> <br><br>性能扩展问题要趁早 <br><a href="http://www.dbanotes.net/arch/scaling_an_early_stage_startup.ht" target="_new"><font color="#1d58d1">http://www.dbanotes.net/arch/scaling_an_early_stage_startup.ht</font></a> <br><br>ml <br><br>37Signals 架构 <br><a href="http://www.dbanotes.net/arch/37signals_arch.html" target="_new"><font color="#1d58d1">http://www.dbanotes.net/arch/37signals_arch.html</font></a> <br><br>Yahoo！社区架构 <br><a href="http://www.dbanotes.net/arch/yahoo_arch.html" target="_new"><font color="#1d58d1">http://www.dbanotes.net/arch/yahoo_arch.html</font></a> <br><br>Flickr 的访问统计实现以及其他 <br><a href="http://www.dbanotes.net/arch/flickr_stats_and_dathan.html" target="_new"><font color="#1d58d1">http://www.dbanotes.net/arch/flickr_stats_and_dathan.html</font></a> <br><br>有关 Alexa 与 AOL 部署集群文件系统 <br><a href="http://www.dbanotes.net/arch/alexa_ibrix_san_file_system.html" target="_new"><font color="#1d58d1">http://www.dbanotes.net/arch/alexa_ibrix_san_file_system.html</font></a> <br><br>微软官网Microsoft.com的一些安全防护数据 <br><a href="http://www.20ju.com/content/V14310.htm" target="_new"><font color="#1d58d1">http://www.20ju.com/content/V14310.htm</font></a> <br><br>豆瓣的 Web 服务器 <br><a href="http://www.dbanotes.net/arch/douban_web_server.html" target="_new"><font color="#1d58d1">http://www.dbanotes.net/arch/douban_web_server.html</font></a> <br><br>WikiPedia 技术架构学习分享 <br><a href="http://www.dbanotes.net/opensource/wikipedia_arch.html" target="_new"><font color="#1d58d1">http://www.dbanotes.net/opensource/wikipedia_arch.html</font></a> <br></p><img src ="http://www.cnblogs.com/xujiaci/aggbug/1209074.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42950/" target="_blank">[新闻]Google开拓美政府机构市场 微软业务受冲击</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>Windows Communication Foundation入门</title><link>http://www.cnblogs.com/xujiaci/archive/2008/06/12/1218242.html</link><dc:creator>Jacky_Xu</dc:creator><author>Jacky_Xu</author><pubDate>Thu, 12 Jun 2008 03:33:00 GMT</pubDate><guid>http://www.cnblogs.com/xujiaci/archive/2008/06/12/1218242.html</guid><wfw:comment>http://www.cnblogs.com/xujiaci/comments/1218242.html</wfw:comment><comments>http://www.cnblogs.com/xujiaci/archive/2008/06/12/1218242.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/xujiaci/comments/commentRss/1218242.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/xujiaci/services/trackbacks/1218242.html</trackback:ping><description><![CDATA[摘要: 前言：WCF是微软基于SOA（Service Oriented Architecture）推出的.Net平台下的框架产品，它代表了软件架构设计与开发的一种发展方向，在微软的战略计划中也占有非常重要的地位。了解和掌握WCF，对于程序员特别是基于微软产品开发的程序员而言，是非常有必要的。对于WCF，笔者也是初窥门径，抱着学习的态度作这样的一个介绍。文中的内容主要参考了微软官方的文档、资料，以及众多介绍&nbsp;&nbsp;<a href='http://www.cnblogs.com/xujiaci/archive/2008/06/12/1218242.html'>阅读全文</a><img src ="http://www.cnblogs.com/xujiaci/aggbug/1218242.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42949/" target="_blank">[新闻]消息称苹果正在开发iTunes网络电视</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>网页加速系列</title><link>http://www.cnblogs.com/xujiaci/archive/2008/06/02/1209082.html</link><dc:creator>Jacky_Xu</dc:creator><author>Jacky_Xu</author><pubDate>Mon, 02 Jun 2008 02:47:00 GMT</pubDate><guid>http://www.cnblogs.com/xujiaci/archive/2008/06/02/1209082.html</guid><wfw:comment>http://www.cnblogs.com/xujiaci/comments/1209082.html</wfw:comment><comments>http://www.cnblogs.com/xujiaci/archive/2008/06/02/1209082.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/xujiaci/comments/commentRss/1209082.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/xujiaci/services/trackbacks/1209082.html</trackback:ping><description><![CDATA[<DIV class=postTitle><A id=AjaxHolder_ctl01_TitleUrl class=postTitle2 href="/Truly/archive/2006/11/09/555889.html">网页加速系列（一）、 网页加速之图形处理篇</A> </DIV>
<P><SPAN class=UNNAMED3><FONT face=宋体>搜集到一些关于网站提速的资料，做一个系列，一些文章可能转或摘自网络。<BR><BR><STRONG>（一）、 网页加速之图形处理篇</STRONG><BR><BR>&nbsp;&nbsp;&nbsp; 在维护网站的过程用，可能遇到过这样的情况：辛辛苦苦做出来的页面，但图片过多，网页结构、表格结构复杂，程序冗长，使得加载速度很慢！网页总是不能完全的展现在浏览者面前。<BR><BR>以后的几篇文章将网页减肥方面的一些经验介绍给大家，希望大家都来讨论，说说自己的观点！ <BR><BR>1、合并图片<BR><BR>尽量把几个可能组合在一起的图片制作成一张图片，这是因为浏览器对网页中的每个图片都会做个别请求，也就是说如果网页中有5张图片，那么浏览器就会向WEB服务器提出5次请求，这必然会增加服务器的负担，从而使得速度变慢！当然大图片除外。<BR><BR>2、指定宽高<BR><BR>在网页中镶入图片的时候，一定注明高度和宽度，如：&lt;IMG src="TEST.GIF" WIDTH=100 HEIGHT=100&gt;，如果没有注明，浏览器在下载完图片以前，将无法确定图片的大小，页面的提交就会延迟，甚至可能重复向WEB服务器提出请求。 <BR><BR>3、选择图片格式<BR><BR>选择适当的图片格式，常见的格式为：JPG和GIF，两种图片分别采用不同的方法压缩图片。JPG支持的颜色数量比较多，一般对于照片或者颜色变化显著的图片用JPG格式，还应该适当的选择压缩比，在基本不损坏效果的前提下尽量压缩。GIF最多支持256种颜色，适合小图片、色彩比较少的图片，对于GIF图片可以在不影响图片效果的前提下尽量减少图片的颜色数量。适当的选择图片的格式，对图片的大小会有不小的影响。可以借助一些图片处理软件。 <BR><BR>4、图片处理<BR><BR>应该采用逐步提交方式提交图片，GIF和JPG两种图片格式都支持逐步提交格式，图片在逐步提交时，在浏览器收到完整图片信息之前就开始显示了。这样看起来快一些。GIF保存为交错格式，JPG选择逐步编码来保存。 <BR><BR>5、替换文字<BR><BR>对于所有图片应该带有文本，用&lt;IMG&gt;ALT标签实现，因为很多朋友为了增加浏览速度关闭了浏览器的图片功能。提供了文本有助于搞清页面的内容。 <BR><BR>最后注意，网页到最后总是以内容来吸引大家的，内容是最重要的！所以，请尽量将一些没有必要的图片去掉！<BR>&nbsp;<BR></P>
<DIV class=postTitle><A id=AjaxHolder_ctl01_TitleUrl class=postTitle2 href="/Truly/archive/2006/11/09/555902.html"><FONT color=#0066cc>网页加速系列（二）、 网页加速之网页结构篇</FONT></A> </DIV>
<P><SPAN class=UNNAMED3><FONT face=宋体><STRONG>（二）、 网页加速之网页结构篇<BR><BR></STRONG><FONT face=宋体>一个网页的结构的好坏，对网页的加载速度有着很大的影响！ <BR><BR>1、关于框架结构<BR><BR>&nbsp;&nbsp;&nbsp; 一般情况下，应尽量避免使用框架结构，因为浏览器必须对框架中的每个页面分别进行请求！这必然会增加服务器的负担。另外，现在还有少数用户使用的浏览器并不支持框架结构显示。 当然在一些地方，框架结构还是显得非常方便，比如：聊天室、论坛、社区、软件下载。<BR><BR>2、关于表格<BR><BR>&nbsp;&nbsp;&nbsp; 表格的应用不仅仅限于，在一些内容列表的时候时候，对于网页的整个布局，表格有着非常重要的作用。为了能使大量的内容在网页上布置的井井有条，一般通过没有边框的来将网页分块，然后将不同的内容放在不同的单元格中。表格的使用是有一些技巧的：首先，尽量避免使用结构复杂的表格，因为结构复杂的表格，有可能使浏览器多次刷新表格。其次，能将一个表格分为两个或两个以上的时候应该分为两个，因为浏览器只有在整个表格的内容全部读入以后再输出显示，如果表格中的内容非常的多，那么在加载过程中，浏览器在表格读入完毕以前将一直显示空白。最后，表格嵌套不要超过3层，层次太多的话在加载表格的时候会使浏览器花大量的时候处理表格结构。<BR>&nbsp;<BR><BR>新浪网的首页页面时候很好的例子，大家可以保存它有编辑软件打开查看其结构。 熟练的使用表格是作出美观的网页所必须的！</FONT> <BR><BR></P>
<DIV class=postTitle><A id=AjaxHolder_ctl01_TitleUrl class=postTitle2 href="/Truly/archive/2006/11/09/555926.html"><FONT color=#0066cc>网页加速系列（三）、 网页加速之网页减肥篇</FONT></A> </DIV>
<P><SPAN class=UNNAMED3><FONT face=宋体><STRONG>（三）、 网页加速之网页减肥篇</STRONG><BR><BR>为完成页面减肥就要先说说HTML语言了，它是一种解释性的脚本语言，更多请参见（<A href="http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/dhtml.asp"><FONT color=#4371a6>http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/dhtml.asp</FONT></A>，英文），那怎样可以“减肥”呢，因为在HTML语言里本来是不用换行，不用大量的空格的，但各种用编辑器写出来的HTML为了便于作者查看程序所以都用上了很多的空格和和换行，好像FP2000这个软件会产生相当多的空格使你网页的内空变得很大。还有一些可以减去的内容就是人为的了，比如你把多个HTML的属性用到一个对像上，而这些属性里有重复的，也会使你的页面变肥了。而一些可以产生同要效果的不同定义也会产生了大量的无用代码。下面看一下具体的减肥方法：<BR><BR>1、软件压缩法<BR>　　最容易的方法就是软件压缩法，用一些专门对HTML减肥的软件来对HTML页面减肥，这个方法很容易且很有效，但对于比如人为造成的冗余HTML代码就不能减了，只能减掉多余的空格和tab。<BR><BR>2、设计减肥法<BR>　　这个方法也很容易的，在这里只讲一部分，更多的要自己积累，方法就是在设计网页时，特别是用一个软件来设计网页时你要用一种良好的操作习惯和正确的方法使你编写出来的页面量优化。例如当你有文字或图片在表格里时需要居中，那么使用单元格居中就会比使用文字居中产生的代码少；例如页面里所有的文字都是小字的时候用CSS的方法来定义文字会比一部份一部份的去写义文字少产生很多的代码；再例如要<BR>给一个表格里的一行定义相同的色彩，那么使用行定义（TR）就会比使用单元格定义色彩产生的代码少；又例如如果你页面里大多数的链接都是要新开一个窗口，那么你把该页面的默认(base)设为开新窗口，这样又会减少很多的开新窗口的定义。类似的代码也是如此。<BR><BR>3、程序减肥法<BR>　　这就是页面减肥的较高的境界了，大家看能看到，页面里有很多的代码是想同的，这些样同的东西如果可以减下来可<BR>就不得了了，怎样做到呢？用程序了，因为现在的网页都可以使用一种程序语言JAVASCRIPT这种程序是插入HTML里面完成<BR>一些动态的东西，那么我们的减肥就用它了，比如做链接的HTML如下：<BR>&lt;TD ALIGN=MIDDLE WIDTH=110&gt;&lt;A href="HTTP://www.qianxun.com"&gt;千寻&lt;/A&gt;&lt;/TD&gt;<BR>&lt;TD ALIGN=MIDDLE WIDTH=110&gt;&lt;A href="HTTP://HDQS.126.COM"&gt;红豆情思&lt;/A&gt;&lt;/TD&gt;<BR>&lt;TD ALIGN=MIDDLE WIDTH=110&gt;&lt;A href="HTTP://STONETIME.126.COM"&gt;STONE时间&lt;/A&gt;&lt;/TD&gt;<BR>&lt;TD ALIGN=MIDDLE WIDTH=110&gt;&lt;A href="HTTP://XIAOKUEN.ON.NET.CN"&gt;恋爱花园&lt;/A&gt;&lt;/TD&gt;<BR>&lt;TD ALIGN=MIDDLE WIDTH=110&gt;&lt;A href="HTTP://LILICAI.YEAH.NET"&gt;味道&lt;/A&gt;&lt;/TD&gt;<BR>&lt;TD ALIGN=MIDDLE WIDTH=110&gt;&lt;A href="HTTP://BROY.126.COM"&gt;风花&lt;/A&gt;&lt;/TD&gt;<BR>内容不少了，但有不少的东西是一样的，那么我们就用程序来动态的生成这些东西程序如下：<BR>&lt;SCRIPT&gt;<BR>FUNCTION LK(URL,TXT){<BR>DOCUMENT.WRITE("&lt;TD ALIGN=MIDDLE WIDTH=110&gt;&lt;A href="+URL+"&gt;"+TXT+"&lt;/A&gt;&lt;/TD&gt;")<BR>}<BR>LK("RONGWW.YEAH.NET","&lt;FONT COLOR=RED&gt;榕儿的家")<BR>LK("HDQS.126.COM","红豆情思")<BR>LK("STONETIME.126.COM","STONE时间")<BR>LK("XIAOKUEN.ON.NET.CN","恋爱花园")<BR>LK("LILICAI.YEAH.NET","味道")<BR>LK("BROY.126.COM","风花")<BR>&lt;/SCRIPT&gt;<BR>这样以来，内容就会减少一些，但如果好像上面的链接有很多很多，这段代码就可以大量的为你减肥了，而且增加了页面的可维护性，这个程序只是一个例子，也许它不合你所需，但这就是我告诉你的方法，你可以自已设计所需的程序，使页面更快更好（比如我的页面上的年月日下拉框就是dw("&lt;option value="+i+"&gt;"+i+"&lt;/option&gt;")，大大减少了页面网络流量）。另一种用程序减肥的方法就是合里的使用.JS程序，.JS的使用不当会使页面速度下降，但如果合理的使用，自己本地的.JS就另有工效了。通过它可以把不同网页里相同的代码用一个.JS文件保存，使<BR>页面的容量减少，同时还便于以后的页面修改。<BR><BR></P>
<DIV class=postTitle><A id=AjaxHolder_ctl01_TitleUrl class=postTitle2 href="/Truly/archive/2006/11/09/555930.html"><FONT color=#0066cc>网页加速系列（四）、 网页加速之CSS辅助减肥篇</FONT></A> </DIV>
<P><SPAN class=UNNAMED3><FONT face=宋体><STRONG><BR>（四）、 网页加速之CSS辅助减肥篇</STRONG></FONT> </P>
<P>WEB网站可用性的关键指标是速度，更确切地说，是页面能以多快的速度出现在访问者的浏览器窗口里。影响速度的因素有很多种，包括WEB服务器的速度、访问者的INTERNET连接情况，以及浏览器必须下载的文件大小。尽管你无法控制服务器和连接的速度，但是你可以控制构成网站WEB页面的文件大小。</P>
<P><BR>为了让网站能够更快，WEB的建设者都会按常规地压缩和优化网站上的每一个图像文件，这常常使得为了将文件的大小减少几个百分点而牺牲了图像的质量。由于CSS样式表是纯文本文件，和图像相比相对较小，所以WEB建设者很少考虑采取措施减少其CSS样式表文件的大小。但是，通过使用CSS缩写以及其他的一些简单技巧，你可以在很大程度上减少样式表的大小。在我对自己样式表的一次非正式的特别测试中，我把文件的大小降低了大约25－50％。</P>
<P>使用CSS的缩写性质<BR>CSS的缩写性质（SHORTHAND PROPERTY）是一些专用的性质名，用来代替多个相关性质的集合。例如，间隙性质（PADDING PROPERTY）是顶部间隙（PADDING-TOP）、右侧间隙（PADDING-RIGHT）、底部间隙（PADDING-BOTTOM）和左侧间隙（PADDING-LEFT）的缩写。</P>
<P>使用速写性质让你能够把多个性质／属性对（PROPERTY/ATTRIBUTE PAIR）压缩进CSS样式表的一行代码里。例如，想一想下面的代码：</P>
<P>.SAMPLE1 {<BR>&nbsp;&nbsp;&nbsp; MARGIN-TOP: 15PX;<BR>&nbsp;&nbsp;&nbsp; MARGIN-RIGHT: 20PX;<BR>&nbsp;&nbsp;&nbsp; MARGIN-BOTTOM: 12PX;<BR>&nbsp;&nbsp;&nbsp; MARGIN-LEFT: 24PX;<BR>&nbsp;&nbsp;&nbsp; PADDING-TOP: 5PX;<BR>&nbsp;&nbsp;&nbsp; PADDING-RIGHT: 10PX;<BR>&nbsp;&nbsp;&nbsp; PADDING-BOTTOM: 4PX;<BR>&nbsp;&nbsp;&nbsp; PADDING-LEFT: 8PX;<BR>&nbsp;&nbsp;&nbsp; BORDER-TOP-WIDTH: THIN;<BR>&nbsp;&nbsp;&nbsp; BORDER-TOP-STYLE: SOLID;<BR>&nbsp;&nbsp;&nbsp; BORDER-TOP-COLOR: #000000;<BR>} </P>
<P>将它用一些缩写性质来替代就能够把代码减少为下面这样，两者的实际效果是完全一样的：</P>
<P>.SAMPLE1 {<BR>&nbsp;&nbsp;&nbsp; MARGIN: 15PX 20PX 12PX 24PX;<BR>&nbsp;&nbsp;&nbsp; PADDING: 5PX 10PX 4PX 8PX;<BR>&nbsp;&nbsp;&nbsp; BORDER-TOP: THIN SOLID #000000;<BR>} </P>
<P>要注意，缩写性质还有多个属性，每一个（属性）都对应一个被组合进入缩写性质的常规性质。属性由空白隔开。</P>
<P>当属性是类似的值的时候，例如用于边框空白性质（MARGIN PROPERTY）的线性测量的时候，接在缩写性质之后的属性的顺序很重要。属性的次序是从顶部（顶部的边框空白）开始，然后围绕格子（BOX）按顺时针次序继续。</P>
<P>如果缩写性质的所有属性都是相同的，那么你可以简单地列出单个属性，然后在前面将它复制四遍。因此，下面的两个性质是相等的：</P>
<P>&nbsp;&nbsp;&nbsp; MARGIN: 5PX 5PX 5PX 5PX;</P>
<P>&nbsp;&nbsp;&nbsp; MARGIN: 5PX; </P>
<P>类似的，你可以使用接在边框空白或者间隔性质之后的两个属性来代表顶部／底部和右侧／左侧属性对。</P>
<P>&nbsp;&nbsp;&nbsp; MARGIN: 5PX 10PX 5PX 10PX;</P>
<P>&nbsp;&nbsp;&nbsp; MARGIN: 5PX 10PX; </P>
<P>属性的顺序在它们是不相似的值的时候是不重要的。因此，边框颜色、边框风格和边框宽度等属性可以以任何顺序接在大纲性质（OUTLINE PROPERTY）之后。忽略某个属性等同于从样式规则里忽略掉对应的常规性质。</P>
<P>CSS缩写性质列表</P>
<P><BR>下面是CSS缩写性质的列表以及它们所表示的常规性质。</P>
<P>BACKGROUND（背景）：背景附件、背景颜色、背景图像、背景位置、背景重复 <BR>BORDER（边框）：边框颜色、边框风格、边框宽度 <BR>BORDER-BOTTOM（底部边框）：底部边框颜色、底部边框样式、底部边框宽度 <BR>BORDER-LEFT（左侧边框）：左侧边框颜色、左侧边框样式、左侧边框宽度 <BR>BORDER-RIGHT（右侧边框）：右侧边框颜色、右侧边框样式、右侧边框宽度 <BR>BORDER-TOP（顶部边框）：顶部边框颜色、顶部边框样式、顶部边框宽度 <BR>CUE（声音提示）：前提示、后提示 <BR>FONT（字体）：字体、字号、字体样式、字体粗细、字体变体、线高度、字体大小调整、字体拉伸 <BR>LIST-STYLE（列表样式）：列表样式图像、列表样式位置、列表样式类型 <BR>MARGIN（空白）：顶部空白、右侧空白、底部空白、左侧空白 <BR>OUTLINE（大纲）：大纲颜色、大纲样式、大纲宽度 <BR>PADDING（间隙）：顶部间隙、右侧间隙、底部间隙、左侧间隙 <BR>PAUSE（暂停）：后暂停、前暂停 <BR>减少空白</P>
<P>减少CSS样式表大小的另一种方法是从文档里删掉大多数无用的空白。换句话说，将每条规则打破放进一行代码里，即把原来插入到代码里用来把每个性质／属性分割到不同行的换行符和缩进符删掉。</P>
<P>例如，下面的代码示例在内容上相同，但是第二个要精炼得多：</P>
<P>H1 {<BR>&nbsp;&nbsp;&nbsp; FONT-SIZE: X-LARGE;<BR>&nbsp;&nbsp;&nbsp; FONT-WEIGHT: BOLD;<BR>&nbsp;&nbsp;&nbsp; COLOR: #FF0000;<BR>} </P>
<P></P>
<P>H1 {FONT-SIZE: X-LARGE; FONT-WEIGHT: BOLD; COLOR: #FF0000} </P>
<P>删掉注释</P>
<P>将注释从你的CSS代码里删掉是减少文件大小的另一种方式。尽管注释对于代码的阅读很有用，但是它无助于浏览器生成你的WEB页面。很多WEB建设者都习惯给每一行代码都加上注释，或者至少给每一条规则声明都加上。这样的慷慨注释在CSS样式表里是极少需要的，因为大多数CSS性质和属性都很容易阅读和理解。如果你对类、ID，以及其他的选择器都使用有意义的名称，你就可以省掉大多数的注释，同时仍然能够保持代码的可读性和可维护性。</P>
<P>H1 {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* HEADING 1 STYLE*/<BR>&nbsp;&nbsp;&nbsp; FONT-SIZE: X-LARGE; /* X-LARGE SIZE */<BR>&nbsp;&nbsp;&nbsp; FONT-WEIGHT: BOLD;&nbsp; /* BOLD */<BR>&nbsp;&nbsp;&nbsp; COLOR: #FF0000;&nbsp;&nbsp;&nbsp;&nbsp; /* RED */<BR>} </P>
<P>使用速写性质、删除无用的空白、省略注释都能够在很大程度上减少你CSS样式表文件的大小。这反过来会对加速你WEB网站速度的总体目标作出小的、但是可能会是显而易见的贡献。<BR><BR></P>
<DIV class=postTitle><A id=AjaxHolder_ctl01_TitleUrl class=postTitle2 href="/Truly/archive/2006/11/09/555934.html"><FONT color=#0066cc>网页加速系列（五）、 网页加速之进阶上篇 </FONT></A></DIV>
<P><SPAN class=UNNAMED3><FONT face=宋体>本文原文地址：<A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndude/html/dude1201.asp"><FONT color=#4371a6>http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndude/html/dude1201.asp</FONT></A>（英文）<BR><BR><STRONG>（五）、 网页加速之进阶上篇 <BR></STRONG><BR>　　WEB开发人员是否必须掌握复杂的组件技术才能加快HTML页面的访问速度？答案是：不一定！实际上，有许多关于HTML与DHTML方面的技巧，它们原理简单而且上手容易。无论是技术高超的老手，还是初涉编程的菜鸟，领会这些都十分必要。<BR><BR><STRONG>减少下载</STRONG><BR><BR>减少WEB页面下载时间的关键就是设法减小文件大小。当多个页面共用一些成分内容时，就可以考虑将这些公用部分单独分离出来。比如：我们可以将多个HTML页面都用到的脚本程序编写成独立存在的.JS文件，然后再在页面中按如下方式调用它：<BR><BR>&lt;SCRIPT src="MYFILE.JS"&gt;&lt;/SCRIPT&gt;<BR><BR>这样，公用文件只需要下载一次，然后就进入缓冲区。等下次再次调用包含公用文件的HTML页面时，下载时间明显减少。<BR><BR><STRONG>让样式表内容进入地下工作</STRONG><BR><BR>CSS是HTML装扮器，一个漂亮的WEB页面不可能没有它。HTML页面中有多种引用CSS的方法，不同的方法导致的效率也不一样。通常，我们可以将定义于&lt;STYLE&gt;&lt;/STYLE&gt;间的样式控制代码提取出来，保存到单独的.CSS文件中，然后在HTML页面中以&lt;LINK&gt;标记或者@IMPORT标记的方式进行引用：<BR><BR>&lt;STYLE&gt; <BR>@IMPORT URL("MYSHEET1.CSS"); <BR>&lt;/STYLE&gt; <BR><LINK rel=STYLESHEET href="MYSHEET2.CSS"><BR><BR>请注意2点：1、.CSS文件中无需包括&lt;STYLE&gt;标记；2、@IMPORT和LINK标记要定义在HTML页面的HEAD部分。<BR><BR><STRONG>宝贵内存节省两法</STRONG><BR><BR>尽量减少HTML页面占用的内存空间是加快页面下载速度的一个有效方法。在这方面，有2个需要注意的问题：<BR><BR>1、使用同一种脚本语言<BR><BR>HTML页面离不开脚本程序的支持，我们经常会在页面中嵌入多种脚本语言，比如JAVASCRIPT与VBSCRIPT。但是，不知你发觉没有：这样的混合使用减慢了页面的访问速度。原因在于：要解释并运行多种脚本代码，就必须在内存中装载多种脚本引擎。所以，请尽量在页面中使用同一种脚本语言编写代码。<BR><BR>2、巧用IFRAME<BR><BR>你使用过&lt;IFRAME&gt;标记吗？它可是一个非常美妙的功能。如果要在一个HTML文档中包含第2个页面的内容，通常的方法是使用&lt;FRAMESET&gt;标记。但是有了&lt;IFRAME&gt;，一切变得简单了。比如，开发一个文档预览页面，可以在左边放置一系列主题，在右边放置一个IFRAME，其中包含要预览的文档；当鼠标掠过左边的每一个主题链接时，就在右边建立一个新的IFRAME以预览文档。这样做，代码效率无疑是高效的，但同时导致了繁重的处理过程，最终是缓慢的速度。<BR><BR>没关系，我们有办法：只使用单一的IFRAME。当鼠标指向一个新主题时，只需要修改IFRAME元素的SRC属性即可。这样，任何时间内只会有一个预览文档保留在内存。<BR><BR><STRONG>择优选用动画定位属性</STRONG><BR><BR>每天上网浏览页面，你一定会看到许多动画效果。比如，一个可爱的小兔子在页面上来回地走动 ... 实现这个效果的核心技术就是CCS定位。通常，我们是使用ELEMENT.STYLE.LEFT和ELEMENT.STYLE.TOP2个属性来达到图形定位的目的。但是，这样做会产生一些问题：LEFT属性返回一个字符串，并且其中包含了度量单位（比如100PX)。因此，要设定新的位置坐标，就必须首先对这个字符串返回值进行处理，然后才能赋值，象下面一样：<BR><BR>DIM STRINGLEFT, INTLEFT <BR><BR>STRINGLEFT = ELEMENT.STYLE.LEFT <BR><BR>INTLEFT = PARSEINT(STRINGLEFT) <BR><BR>INTLEFT = INTLEFT + 10 <BR><BR>ELEMENT.STYLE.LEFT = INTLEFT; <BR><BR>你一定会感觉做这么点事情竟要编写这么复杂的代码，是否有更简洁的方法？当然有！请看这4个属性：POSLEFT、POSTOP、POSWIDTH 和 POSHEIGHT，它们对应于相应字符串返回值的点数数值。好了，使用这些属性重新编写代码实现上面代码实现的功能：<BR><BR>ELEMENT.STYLE.POSLEFT += 10<BR><BR>代码短小、速度却更快！</FONT></SPAN> <BR></P>
<DIV class=postTitle><A id=AjaxHolder_ctl01_TitleUrl class=postTitle2 href="/Truly/archive/2006/11/09/555939.html"><FONT color=#0066cc>网页加速系列（六）、 网页加速之进阶下篇 </FONT></A></DIV>
<P><SPAN class=UNNAMED3><FONT face=宋体>本文可参考以下网址：<BR><A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndude/html/dude1201.asp"><FONT color=#4371a6>http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndude/html/dude1201.asp</FONT></A><BR><A href="http://msdn.microsoft.com/library/default.asp?url=/workshop/author/perf/perftips.asp"><FONT color=#4371a6>http://msdn.microsoft.com/library/default.asp?url=/workshop/author/perf/perftips.asp</FONT></A><BR><BR><STRONG>（六）、 网页加速之进阶下篇</STRONG> <BR><BR>循环控制多个动画<BR><BR>说到制作动画效果，当然离不开定时器的运用。通常的方法就是使用WINDOW.SETTIMEOUT来不断地定位页面上的元素。但是，如果页面上有多个动画要显示，是不是就要设定多个定时器呢？答案是NO！原因很简单：定时器功能将消耗掉大量宝贵的系统资源。可是我们仍能在页面上控制多个动画，技巧就是使用一个循环。在循环中根据不同的变量值控制相应动画的位置，整个循环中只使用一个WINDOW.SETTIMEOUT()函数调用。<BR><BR>VISIBILITY快于DISPLAY<BR><BR>让图画时隐时现会创造很有趣的效果，有2种方法可以实现这个目的：使用CSS的VISIBILITY属性或者DISPLAY属性。对于绝对位置元素，DIAPLAY和VISIBILITY具有同样的效果。两者的区别在于：设置为DISPLAY:NONE的元素将不再占用文档流的空间，而设置为VISIBILITY:HIDDEN的元素仍然保留原位置。<BR><BR>但是如果要处理绝对位置的元素，使用VISIBILITY会更快。<BR><BR>从小处着手<BR><BR>编写DHTML网页的一个重要提示是：从小处着手。初次编写DHTML页面时，一定不要试图在页面中使用你了解到的全部DHTML功能。每次可以只使用一个单一的新特征，并且仔细地观察由此产生的变化。如果发现性能有所下降，就可以快速地找到为什么。<BR><BR>脚本的DEFER化<BR><BR>DEFER是脚本程序强大功能中的一个“无名英雄”。你可能从没有使用过它，但是看完这里的介绍后，相信你就离不开它。它告诉浏览器SCRIPT段包含了无需立即执行的代码，并且，与SRC属性联合使用，它还可以使这些脚本在后台被下载，前台的内容则正常显示给用户。<BR><BR><BR>最后请注意两点：<BR><BR>1、不要在DEFER型的脚本程序段中调用DOCUMENT.WRITE命令，因为DOCUMENT.WRITE将产生直接输出效果。<BR><BR>2、而且，不要在DEFER型脚本程序段中包括任何立即执行脚本要使用的全局变量或者函数。<BR><BR>保持同一URL的大小写一致性<BR><BR>我们都知道UNIX服务器是大小写敏感的，但是你知道吗：INTERNET EXPLORER的缓冲区也是区别对待大小写字符串的。因此，作为WEB开发者，一定要记住保持相同链接的URL字符串在不同位置的大小写的一致性。否则，就会在浏览器的缓冲区中存放同一位置的不同文件备份，也增加了下载同一位置内容的请求次数。这些都无疑降低了WEB访问效率。所以请谨记：同一位置的URL，在不同页面中请保持URL字符串的大小写一致性。<BR><BR>让标记有始有终<BR><BR>自己编写或者查看他人的HTML代码时，我们一定都遇到过标记有头无尾的情况。比如：<BR><BR>&lt;P&gt;有头无尾标记举例 <BR>&lt;UL&gt; <BR>&lt;LI&gt;第一个<BR>&lt;LI&gt;第二个<BR>&lt;LI&gt;第三个<BR>&lt;/UL&gt; <BR><BR>很明显，上面的代码中缺少三个&lt;/LI&gt;结束标记。但是这并不妨碍它的正确执行。在HTML中，这样的标记还有一些，例如FRAME、IMG和P。 <BR><BR>可是请不要偷懒，请将结束标记写完整，这样做不仅使HTML代码格式规范，更可以加速页面的显示速度。因为INTERNET EXPLORER将不会花费时间判断和计算段落或者列表项目在哪里结束。<BR><BR>&lt;P&gt;有头有尾标记举例&lt;/P&gt; <BR>&lt;UL&gt; <BR>&lt;LI&gt;第一个&lt;/LI&gt; <BR>&lt;LI&gt;第二个&lt;/LI&gt; <BR>&lt;LI&gt;第三个&lt;/LI&gt; <BR>&lt;/UL&gt; <BR><BR>OK，以上列举了有关加速HTML页面的10个处理技巧，描述这些很简单，但是只有真正领会并掌握其中的本质，并且举一反三，才会编写出更快、更好的程序。</FONT></SPAN> </P></SPAN></FONT></SPAN></FONT></SPAN></FONT></SPAN><img src ="http://www.cnblogs.com/xujiaci/aggbug/1209082.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42948/" target="_blank">[新闻]微软周一开电话会议 预计将发布Silverlight2.0</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>用VS.NET中的测试工具测试ASP.NET程序</title><link>http://www.cnblogs.com/xujiaci/archive/2008/05/29/1209754.html</link><dc:creator>Jacky_Xu</dc:creator><author>Jacky_Xu</author><pubDate>Thu, 29 May 2008 02:40:00 GMT</pubDate><guid>http://www.cnblogs.com/xujiaci/archive/2008/05/29/1209754.html</guid><wfw:comment>http://www.cnblogs.com/xujiaci/comments/1209754.html</wfw:comment><comments>http://www.cnblogs.com/xujiaci/archive/2008/05/29/1209754.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/xujiaci/comments/commentRss/1209754.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/xujiaci/services/trackbacks/1209754.html</trackback:ping><description><![CDATA[在编写ASP.NET应用程序的时候，你会花费多长的时间来考虑性能的问题？很不幸，大多数开发者都对性能问题感到很后悔。性能的规划和设计真的需要放在前面和中心位置。你需要考虑自己的目标，并且确保把良好的性能作为目标之一；接着你需要评估自己的程序，评估的方面越多，改善性能的机会就越大。<BR><BR>　　在本文中我将解释微软Visual Studio企业 版中包含的一个重要工具：微软Application Center Test。严肃的Web开发者都应该把这个工具放在自己的工具包中。<BR><STRONG>Application Center Test<BR><BR></STRONG>　　在离开微软之前，我参加了12个城市的ASP.NET说明会。其中一个覆盖了性能问题，并且给很多开发者介绍了微软Application Center Test。这个工具总是生成大量的有趣的信息，我对它有很多疑问。<BR><BR>　　你会发现Application Center Test是Application Center（可以在旧的MSDN CD或DVD中找到）的一部分，或者安装在Visual Studio .NET企业版的Visual Studio .NET 2003\Visual Studio .NET Enterprise Features目录下面。当你第一次打开Application Center Test的时候，你可以看到一个用于导航可用的测试、结果和用户的树视图。首先，我希望显示出很容易建立测试。<BR><BR>　　<B>使用Application Center Test</B><BR><BR>　　首先，建立一个简单的Web应用程序。例如，我将使用图1所示的页面（请注意，我使用了一些联机编写ASP.NET页面的小技巧，你不需要编写完整的Page_Load事件声明）。<BR><BR>　　示例Web应用程序<BR><BR>
<TABLE border=1 borderColor=#ffcc66 width="90%" bgColor=#dadacf align=center>
<TBODY>
<TR>
<TD>＜%@ Page Language="C#" %＞<BR>＜%@ Import Namespace="System.Data " %＞<BR>＜%@ Import Namespace="System.Data.SqlClient" %＞<BR>＜%@ Import Namespace=" System.Configuration" %＞<BR><BR>＜script runat="server"＞<BR>public void Page_Load() {<BR>　using(SqlConnection connection = <BR>　　new SqlConnection(ConfigurationSettings.AppSettings["Northwind"]))<BR>　{<BR>　　SqlCommand command = new SqlCommand("SELECT * FROM Products", connection);<BR>　　connection.Open();<BR><BR>　　DataGrid1.DataSource = command.ExecuteReader();<BR>　　DataGrid1.DataBind();<BR>　}<BR>}<BR>＜/script＞<BR><BR>＜form runat="server"＞<BR>＜asp:DataGrid id="DataGrid1" runat="server" /＞<BR>＜/form＞</TD></TR></TBODY></TABLE><BR>　　上面的代码虽然不是推荐的用于构造应用程序的方法，但是它也足够简单，我们能够在它上面执行一些基本的测试。在Web<A class=akey href="http://tech.sina.com.cn/it/2004-08-19/1131408183.shtml" target=_blank>浏览器</A>中打开这个页面会返回一个填充了的数据表格，它显示为HTML表格。<BR><BR>　　现在你知道这个页面可以工作了，把链接复制到剪贴板上，你还需要使用它的。在我的计算机上这个例子的链接是http://localhost/blackbelt/outputcache/test.aspx。<BR><BR>　　下一步，导航到Application Center Test，右键点击"Tests（测试）"并选择"New Test（新建测试）"。它会打开"新建测试向导"欢迎页面。点击"下一步"选择新测试的源代码，并选中"记录新测试"。再次点击"下一步"以选择测试类型，提示选择脚本语言（我们不修改默认值）的时候，点击"下一步"，出现了图1所示的界面：<BR><BR>
<TABLE border=0 width="90%" align=center>
<TBODY>
<TR>
<TD>
<DIV align=center><IMG border=0 alt=用VS.NET中的测试工具测试ASP.NET程序 src="http://image2.sina.com.cn/IT/cr/2005/0622/2277294725.gif"><BR>图1：新建测试向导</DIV></TD></TR></TBODY></TABLE><BR>　　"记录测试"使Application Center Test易于使用。点击"开始记录"会打开一个新的浏览器实例。不要在地址栏中输入URL（应该为about:blank）。我们的操作是，在这个新的浏览器实例中选择Tools | Internet选择，并浏览"连接"属性页。接着点击"局域网设置"按钮，会看到图2所示的界面：<BR><BR>
<TABLE border=0 width="90%" align=center>
<TBODY>
<TR>
<TD>
<DIV align=center><IMG border=0 alt=用VS.NET中的测试工具测试ASP.NET程序 src="http://image2.sina.com.cn/IT/cr/2005/0622/1238436877.gif"><BR>图2：连接设置</DIV></TD></TR></TBODY></TABLE><BR>　　你会发现代理服务器（proxy）设置信息被填充了，并且与正常值不同。这是因为Application Center Test打开了一个新的浏览器实例并指示它使用Application Center Test运行的专用代理服务器。经过浏览器的任何请求都会被Application Center Test代理捕捉到。<BR><BR>　　为了完成测试，请关闭浏览器对话框并把用于测试的ASP.NET页面的链接粘贴到地址栏中。点击浏览器的"转到"按钮或直接按下回车键，再次出现了数据表格。下一步，关闭浏览器，你可能看到与图3类似的信息：<BR><BR>
<TABLE border=0 width="90%" align=center>
<TBODY>
<TR>
<TD height=17>
<DIV align=center><IMG border=0 alt=用VS.NET中的测试工具测试ASP.NET程序 src="http://image2.sina.com.cn/IT/cr/2005/0622/1872788617.gif"><BR>图3：捕捉到的请求</DIV></TD></TR></TBODY></TABLE><BR>　　上面的对话框中的请求的详细信息部分现在被Application Center Test代理捕捉到的请求所填充了。这也是浏览器发送的HTTP请求。现在点击"停止记录"，接着点击"下一步"。你会得到一个提示，需要给该测试输入一个名称（我用的是"My Test"），接着你可以点击"完成"关闭向导。<BR><BR>　　恭喜你！你现在是一个性能测试工程师了--很容易，对吗？<BR><BR>　　你还可以选择很多其它的设置信息和配置选项。你右键点击"测试"列表中的"My Test"节点并选择"属性" 可以看到这些设置。在这些选项中你可以模拟多个浏览器、多个用户、"热身"时间的参数（不会被报告其结果）以及测试的持续时间。你可以以后研究这些设置并阅读一些讨论测试原理和测试策略的文章。我们不在细节上花费太多时间，直接运行测试吧。<BR><STRONG>运行测试并建立基线<BR><BR></STRONG>　　要运行刚才建立的测试，只需要简单地右键点击该测试并选择"开始测试"。测试开始以后，点击"显示详细信息"按钮。细节框中将显示正在运行的测试的一个图表，同时显示在运行测试过程中可能出现的任何错误（图5所示）。第一次运行这个测试建立了基线，我们可以把它与当前的和未来的性能进行对比。图4显示的基线是每秒大约90个请求。<BR><BR>
<TABLE border=0 width="90%" align=center>
<TBODY>
<TR>
<TD>
<DIV align=center><IMG border=0 alt=用VS.NET中的测试工具测试ASP.NET程序(2) src="http://image2.sina.com.cn/IT/cr/2005/0622/656212935.gif"><BR>图4：基线图表</DIV></TD></TR></TBODY></TABLE><BR>　　现在你拥有了一个确定的基线了，你可以对应用程序作一些修改以测量修改所引起的性能提升或降低。的确，我使用的测试示例极其简单，但是我会显示出对这一小段代码进行少量的修改可能对应用程序的性能产生很大的影响。<BR><BR>　　<B>了解改善的部分</B><BR><BR>　　评估的方面越多，改善的机会就越大。在例子中我将对应用程序作一些小的修改，并在每个修改之后进行评估。尽管在现实情况下你不可能每步修改都进行这样的测试，但是你应该有周期性检查性能的习惯。对于我们公司的Community Server产品，我们拥有一套用于评估总体应用程序开销的基线。如果进行了重大的修改，开发者就可以使用前面的测试数据来研究性能的提升或降低。<BR><BR>　　我对示例应用程序的第一处修改是改变返回数据量的限制。我把SQL查询SELECT * FROM Products改变为SELECT TOP 25 * FROM Products。这好像只是对代码进行了微小的修改。毕竟我只是限制屏幕中输出的数据量，但是其结果却是惊人的。其性能从每秒90个请求上升到200以上--性能提高了100％以上。由于你拥有基线，你知道了限制绑定到数据表格的数据量一定会影响性能。我还要修改其它一些东西。<BR><BR>　　下一步，修改＜asp:DataGrid/＞服务器控件，添加EnableViewState="false"：<BR><BR>
<TABLE border=1 borderColor=#ffcc66 width="90%" bgColor=#dadacf align=center>
<TBODY>
<TR>
<TD>＜asp:DataGrid EnableViewState="false" id="DataGrid1" runat="server" /＞</TD></TR></TBODY></TABLE><BR>　　ViewState是ASP.NET的一个重要的特性，但是并非总是需要的。实际上，大多数使用了ViewState的数据表格都是不需要它的。在例子中，通过禁止ViewState，我可以提高166％的性能。我们继续！<BR><BR>　　下一步，添加下面的代码以激活输出缓冲（OutputCaching）：<BR><BR>
<TABLE border=1 borderColor=#ffcc66 width="90%" bgColor=#dadacf align=center>
<TBODY>
<TR>
<TD>＜%@ OutputCache Duration="60" VaryByParam="none" %＞</TD></TR></TBODY></TABLE><BR>
<TABLE border=0 width="90%" align=center>
<TBODY>
<TR>
<TD>
<DIV align=center><IMG border=0 alt=用VS.NET中的测试工具测试ASP.NET程序(2) src="http://image2.sina.com.cn/IT/cr/2005/0622/3845717686.gif"><BR>图5：输出缓冲</DIV></TD></TR></TBODY></TABLE><BR>　　现在重新运行该测试。太惊人了！性能提高了600％，如图5所示。你可以调整OutputCache的持续数值，例如把OutputCache的持续值设置为1秒--你可以看到性能再次有很大的变化。<BR><BR>　　<B>建立测试环境</B><BR><BR>　　测试操作是CPU密集型的事务，因此在运行测试的时候，你可能看到CPU的占用率接近100％。它在与测试部件分享CPU时间的时候会拿走正在测试的应用程序的资源。所有的配置选项都会影响测试结果，其中一部分模拟现实世界要真实一些。例如，如果SQL Server和ASP.NET在同一台计算机上，就无法模拟网络I/O的开销。大多数应用程序使用的数据库都不在Web服务器上。<BR><BR>　　为了建立真实的测试环境，把大量的旧的用于开发的计算机作为客户端使用。不要使用虚拟机。在这些计算机上运行Application Center Test。下一步尽可能地模拟现实世界。在一个没有运行其它任何应用程序的服务器操作系统上运行该Web应用程序，并且连接到另一台服务器的数据库。<BR><BR>　　需要说明的是，在开发环境中运行"烟幕"测试也没有什么错误。烟幕测试不能模拟现实世界，但是仍然可以提供大量的有价值的数据，并且可以用于预计在现实世界中同样的测试产生的结果。<BR><BR>　　<B>后续的步骤和测试覆盖</B><BR><BR>　　现在你对如何测试和评估有了一些了解了，我推荐你在自己的应用程序上使用Application Center Test。了解你的用户在典型情况下如何使用应用程序是有好处的：哪些页面执行得更好，哪些页面没有改善？<BR><BR>　　例如，在Community Server中我们运行了多种类型的性能测试。主线（Mainline）测试包含了匿名和验证的情况。在大量个性化的应用程序中这一点可能显著的改变性能情况。<BR><BR>　　主线测试还包含了贯穿系统的通用路径，例如网络日志、图表、论坛的主视图，以及每个屏幕的不同视图。很明显，这些主线情形良好的执行情况是非常重要的，最好在这儿花费大量的时间以确保其正确性。<BR><BR>　　如果你管理或运行那些必须支持两个或多个并发用户的项目，并且你不知道自己的主页面每秒钟可以处理多少个请求，那么就遇到问题了。<BR><BR>　　如果你拥有性能测试脚本，那么在每次重要的修改之后都应该进行评估。如果实际上是你自己构造的代码，那么就可以经常深入源代码并且评价各部分和重新编译。这可以帮助你检查出问题在于程序编写得不好还是其它的原因。其它的原因有90％都出在数据访问代码部分。<BR>你还可以测试应用程序中的通用路径。记录测试的时候，只需要输入用户可能使用的通用导航路径。Application Center Test将记录下这些信息，并且你可以重新播放准确的脚本。如果你喜欢，可以编辑生成的VBScript文件，给你的测试脚本引入延迟或其它有意义的输入信息。<BR><BR>　　我推荐的最后的测试需要做很多工作。例如，在Community Server中我们的开发者希望测试应用程序可以每分钟可以支持多少个post（张贴）操作。为了测试它，我们不是把内容写入窗体，而是建立一个新ASP.NET页面，它使用API来输入内容。接着这个页面在Application Center Test中运行，应用程序支持的每秒钟张贴操作的数量就产生了。换句话说，有时候为了测试所有的情形，你可能需要多做一些工作。<BR><BR>　　<B>结论</B><BR><BR>　　我没有解释Application Center Test提供的所有信息，但是我希望本文给了你足够的使用Application Center Test的知识，这样你才能够使用它来评估和改善自己的应用程序。请记住，建立基线、频繁的评估（至少在每次重大的修改之后）并识别出关键的部分。遵循这些简单的规则，你会对应用程序有更好的理解，并且很有希望找到提高性能的机会。<img src ="http://www.cnblogs.com/xujiaci/aggbug/1209754.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42947/" target="_blank">[新闻]开心网即将启用”shejiao.com”?</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>【转载】优化ASP.NET应用程序性能研究与探讨 </title><link>http://www.cnblogs.com/xujiaci/archive/2008/05/28/1209069.html</link><dc:creator>Jacky_Xu</dc:creator><author>Jacky_Xu</author><pubDate>Wed, 28 May 2008 03:45:00 GMT</pubDate><guid>http://www.cnblogs.com/xujiaci/archive/2008/05/28/1209069.html</guid><wfw:comment>http://www.cnblogs.com/xujiaci/comments/1209069.html</wfw:comment><comments>http://www.cnblogs.com/xujiaci/archive/2008/05/28/1209069.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/xujiaci/comments/commentRss/1209069.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/xujiaci/services/trackbacks/1209069.html</trackback:ping><description><![CDATA[<STRONG>摘 要</STRONG> 本文从页面、数据访问、字符串操作三方面探讨如何提高ASP.NET应用程序的性能，并提供了几种测试工具用于检测ASP.NET网站性能。<BR><BR>　　<B>关键词</B> ASP.NET 应用程序 性能 优化 <BR><BR>　　网站的性能对于ASP.NET程序开发人员来说非常重要。一个优秀的网站虽然有美观的页面设计，完善的服务功能，但是打开网页时有长时间的延迟，用户最终将会无法忍受。尤其对于大型的电子商务网站而言，每秒钟有数万用户同时访问，没有良好的网站性能，根本无法满足庞大的需求。<BR><BR>　　ASP.NET作为全新一代的动态网页生成系统，它在平台性能方面与原有的ASP相比已有了一个本质的提高。但要在此基础上开发出专业水准的、符合生产标准的、受用户欢迎的web应用程序，还需要开发人员从编程的角度在页面、数据访问和字符串处理等各方面进行优化处理，以提高网站的总体性能。<BR><BR>　　本文将主要探讨在ASP.NET中与此相关的几种进行性能优化的方法及注意问题。<BR><BR>　　<B>页面性能优化</B><BR><BR>　　1、会话状态的恰当选择<BR><BR>　　HTTP协议是一种无状态的通信协议，无法记录和识别来自不同客户端的请求，但在实际应用中系统却要维护来自客户端的不同请求之间的会话状态信息。ASP.NET通过将会话状态信息存储在进程、状态服务器或SQL Server数据库中来解决这个问题。<BR><BR>　　将会话状态信息保存在WEB服务器的内存中具有最佳的性能，速度很快，但是却缺乏会话状态信息跨越多个服务器的能力。若要在多个WEB服务器之间维护会话信息，可以使用状态服务器进行存储，这种方式由于可以将应用程序部署到多台服务器上而提高了系统的伸缩性和可靠性，但是以降低性能为代价。对于极其重要的会话信息，需要使用SQL Server存储方式，从而避免丢失重要的会话信息，但由此产生的工作负载比前两者大得多。<BR><BR>　　若不考虑状态信息的保留和多个服务器共享，应尽量选择保存在服务器的进程中，从而得到最佳的性能。<BR><BR>　　会话状态信息的存储方式选择通过web.config文件：<BR><BR>
<TABLE border=1 borderColor=#ffcc66 width="90%" bgColor=#dadacf align=center>
<TBODY>
<TR>
<TD>＜sessionState<BR>mode="InProc/StateServer/SqlServer" //存储方式由此行选择<BR>stateConnectionString="tcpip=127.0.0.1:42424"<BR>……<BR>timeout="20"/＞</TD></TR></TBODY></TABLE><BR>　　2、服务器控件的优化选择<BR><BR>　　2.1 减少不必要的服务器控件<BR><BR>　　服务器控件带来的方便和功能是html控件所不能比拟的。但是每一个服务器控件都需要在服务器端创建相应的对象，是以牺牲服务器端的资源为代价的，过多的使用服务器控件会极大的影响程序性能。<BR><BR>　　很多情况下，简单地使用html标记或数据绑定即能够实现所需功能。比如＜asp:Label＞控件，若使用它来显示静态信息，则完全可用简单的标记来实现。如果html控件达不到所要实现的功能，而且在脚本语言如javascript、vbscript也不能实现的情况下，才考虑选择服务器控件。<BR><BR>　　2.2 禁用不必要的状态视图<BR><BR>　　服务器控件的状态视图属性能够自动的在页面往返过程中维护服务器控件的状态，减少开发者的工作量，但是需要占用大量的服务器内存资源。因此，在不需要服务器控件状态视图的情况下，应将其EnableViewState属性设置为false，如常用的＜asp:Lable＞和＜asp:Button＞控件。<BR><BR>　　2.3 Page.IsPostBack的运用<BR><BR>　　Page.IsPostBack用于记录页面是否从客户端返回，若为false表示初次运行，否则表示从客户端再次返回该页面。Page.IsPostBack的合理应用可以避免页面在往返过程中的一些不必要的操作。在Page_Load函数及一些只需要初始化一次的事件函数中均可以使用该属性来提高应用程序性能。<BR><BR>
<TABLE border=1 borderColor=#ffcc66 width="90%" bgColor=#dadacf align=center>
<TBODY>
<TR>
<TD>void Page_Load(Object o, EventArgs e)<BR>{<BR>　if(! Page.IsPostBack)<BR>　{<BR>　　conn=new SqlConnection("server=localhost;uid=sa;pwd=;database=data");<BR>　　String sql="select * from student";<BR>　　cmd.Fill(ds,"stu");<BR>　　mydataGrid.DataBind();<BR>　}<BR>}</TD></TR></TBODY></TABLE><BR>　　以上代码将保证只有在首次访问该页面时对数据库进行读取并绑定。<BR><BR>　　2.4 合理使用DataGrid控件<BR><BR>　　DataGrid控件带有最强大的数据显示功能，还内置了对数据的修改、删除、添加、分页等很多功能。如果只需简单的显示数据， DataGrid并非最佳选择。DataGrid控件的分页功能，数据的存储方式（存储在viewstate中）等，虽然让程序开发者使用方便快捷，但由此产生的性能开销不容小视。<BR><BR>　　DataList控件比DataGrid功能少了很多。但自定义性强了很多。特有的多行数据显示还是比较方便的。DataGrid能实现的功能，它基本能实现。<BR><BR>　　Repeater控件功能最少，但自定义性非常强。由于减少了很多功能，对服务器的性能带来消耗最小。<BR><BR>　　因此，在只需简单显示数据列表时，选择Repeater或DataList控件同样可以达到目的，而且减轻了性能上的开销。<BR><BR>　　<B>数据库访问性能优化</B><BR><BR>　　1、数据库的连接和关闭<BR><BR>　　访问数据库资源需要创建连接、打开连接和关闭连接几个操作。这些过程需要多次与数据库交换信息以通过身份验证，比较耗费服务器资源。ASP.NET中提供了连接池（Connection Pool）改善打开和关闭数据库对性能的影响。系统将用户的数据库连接放在连接池中，需要时取出，关闭时收回连接，等待下一次的连接请求。<BR><BR>　　连接池的大小是有限的，如果在连接池达到最大限度后仍要求创建连接，必然大大影响性能。因此，在建立数据库连接后只有在真正需要操作时才打开连接，使用完毕后马上关闭，从而尽量减少数据库连接打开的时间，避免出现超出连接限制的情况。<BR><BR>　　2、使用存储过程<BR><BR>　　存储过程是存储在服务器上的一组预编译的SQL语句，类似于DOS系统中的批处理文件。存储过程具有对数据库立即访问的功能，信息处理极为迅速。使用存储过程可以避免对命令的多次编译，在执行一次后其执行规划就驻留在高速缓存中，以后需要时只需直接调用缓存中的二进制代码即可。<BR><BR>　　另外，存储过程在服务器端运行，独立于ASP.NET程序，便于修改，最重要的是它可以减少数据库操作语句在网络中的传输。<BR><BR>　　3、优化查询语句<BR><BR>　　ASP.NET中ADO连接消耗的资源相当大，SQL语句运行的时间越长，占用系统资源的时间也越长。因此，尽量使用优化过的SQL语句以减少执行时间。比如，不在查询语句中包含子查询语句，充分利用索引等。<BR><BR>　　<B>字符串操作性能优化</B><BR><BR>　　1、使用值类型的ToString方法<BR><BR>　　在连接字符串时，经常使用"+"号直接将数字添加到字符串中。这种方法虽然简单，也可以得到正确结果，但是由于涉及到不同的数据类型，数字需要通过装箱操作转化为引用类型才可以添加到字符串中。但是装箱操作对性能影响较大，因为在进行这类处理时，将在托管堆中分配一个新的对象，原有的值复制到新创建的对象中。 <BR><BR>　　使用值类型的ToString方法可以避免装箱操作，从而提高应用程序性能。<BR><BR>　　2、运用StringBuilder类<BR><BR>　　String类对象是不可改变的，对于String对象的重新赋值在本质上是重新创建了一个String对象并将新值赋予该对象，其方法ToString对性能的提高并非很显著。<BR><BR>　　在处理字符串时，最好使用StringBuilder类，其.NET 命名空间是System.Text。该类并非创建新的对象，而是通过Append，Remove，Insert等方法直接对字符串进行操作，通过ToString方法返回操作结果。<BR><BR>　　其定义及操作语句如下所示：<BR><BR>
<TABLE border=1 borderColor=#ffcc66 width="90%" bgColor=#dadacf align=center>
<TBODY>
<TR>
<TD>int num;<BR>System.Text.StringBuilder str=new System.Text.StringBuilder(); //创建字符串<BR>str.Append(num.ToString()); //添加数值num<BR>Response.Write(str.ToString); //显示操作结果</TD></TR></TBODY></TABLE><BR>　　<B>ASP.NET应用程序性能测试</B><BR><BR>　　在对ASP.NET应用程序进行性能测试之前，应确保应用程序没有错误，而且功能正确。具体的性能测试可以采用以下工具进行：<BR>Web Application Strees Tool (WAS)是Microsoft发布的一个免费测试工具，可以从http://webtool.rte.microsoft.com/上下载。它可以模拟成百上千个用户同时对web应用程序进行访问请求，在服务器上形成流量负载，从而达到测试的目的，可以生成平均TTFB、平均TTLB等性能汇总报告。 <BR><BR>　　Application Center Test (ACT) 是一个测试工具，附带于Visual Studio.NET的企业版中，是Microsoft正式支持的web应用程序测试工具。它能够直观地生成图表结果，功能比WAS多，但不具备多个客户机同时测试的能力。<BR><BR>　　服务器操作系统"管理工具"中的"性能"计数器，可以对服务器进行监测以了解应用程序性能。<BR><BR>　　<B>结论</B><BR><BR>　　对于网站开发人员来说，在编写ASP.NET应用程序时注意性能问题，养成良好的习惯，提高应用程序性能，至少可以推迟必需的硬件升级，降低网站的成本。<img src ="http://www.cnblogs.com/xujiaci/aggbug/1209069.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42945/" target="_blank">[新闻]Google股价跌破329美元 61%员工期权价值归零</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>负载均衡技术全攻略</title><link>http://www.cnblogs.com/xujiaci/archive/2008/05/28/1208138.html</link><dc:creator>Jacky_Xu</dc:creator><author>Jacky_Xu</author><pubDate>Wed, 28 May 2008 03:44:00 GMT</pubDate><guid>http://www.cnblogs.com/xujiaci/archive/2008/05/28/1208138.html</guid><wfw:comment>http://www.cnblogs.com/xujiaci/comments/1208138.html</wfw:comment><comments>http://www.cnblogs.com/xujiaci/archive/2008/05/28/1208138.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/xujiaci/comments/commentRss/1208138.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/xujiaci/services/trackbacks/1208138.html</trackback:ping><description><![CDATA[Internet的规模每一百天就会增长一倍，客户希望获得7天24小时的不间断可用性及较快的系统反应时间，而不愿屡次看到某个站点“Server Too Busy”及频繁的系统故障。 <BR><BR>　　网络的各个核心部分随着业务量的提高、访问量和数据流量的快速增长，其处理能力和计算强度也相应增大，使得单一设备根本无法承担。在此情况下，如果扔掉现有设备去做大量的硬件升级，这样将造成现有资源的浪费，而且如果再面临下一次业务量的提升，这又将导致再一次硬件升级的高额成本投入，甚至性能再卓越的设备也不能满足当前业务量的需求。于是，负载均衡机制应运而生。 <BR><BR>　　负载均衡（Load Balance）建立在现有网络结构之上，它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。 <BR><BR>　　负载均衡有两方面的含义：首先，大量的并发访问或数据流量分担到多台节点设备上分别处理，减少用户等待响应的时间；其次，单个重负载的运算分担到多台节点设备上做并行处理，每个节点设备处理结束后，将结果汇总，返回给用户，系统处理能力得到大幅度提高。 <BR><BR>　　本文所要介绍的负载均衡技术主要是指在均衡服务器群中所有服务器和应用程序之间流量负载的应用，目前负载均衡技术大多数是用于提高诸如在Web服务器、FTP服务器和其它关键任务服务器上的Internet服务器程序的可用性和可伸缩性。 <BR><BR>负载均衡技术分类 <BR><BR>　　目前有许多不同的负载均衡技术用以满足不同的应用需求，下面从负载均衡所采用的设备对象、应用的网络层次（指OSI参考模型）及应用的地理结构等来分类。 <BR><BR>软/硬件负载均衡 <BR>　　软件负载均衡解决方案是指在一台或多台服务器相应的操作系统上安装一个或多个附加软件来实现负载均衡，如DNS Load Balance，CheckPoint Firewall-1 ConnectControl等，它的优点是基于特定环境，配置简单，使用灵活，成本低廉，可以满足一般的负载均衡需求。 <BR><BR>　　软件解决方案缺点也较多，因为每台服务器上安装额外的软件运行会消耗系统不定量的资源，越是功能强大的模块，消耗得越多，所以当连接请求特别大的时候，软件本身会成为服务器工作成败的一个关键；软件可扩展性并不是很好，受到操作系统的限制；由于操作系统本身的Bug，往往会引起安全问题。 <BR><BR>　　硬件负载均衡解决方案是直接在服务器和外部网络间安装负载均衡设备，这种设备我们通常称之为负载均衡器，由于专门的设备完成专门的任务，独立于操作系统，整体性能得到大量提高，加上多样化的负载均衡策略，智能化的流量管理，可达到最佳的负载均衡需求。 <BR><BR>　　负载均衡器有多种多样的形式，除了作为独立意义上的负载均衡器外，有些负载均衡器集成在交换设备中，置于服务器与Internet链接之间，有些则以两块网络适配器将这一功能集成到PC中，一块连接到Internet上，一块连接到后端服务器群的内部网络上。 <BR><BR>　　一般而言，硬件负载均衡在功能、性能上优于软件方式，不过成本昂贵。 <BR><BR>本地/全局负载均衡 <BR>　　负载均衡从其应用的地理结构上分为本地负载均衡(Local Load Balance)和全局负载均衡(Global Load Balance，也叫地域负载均衡)，本地负载均衡是指对本地的服务器群做负载均衡，全局负载均衡是指对分别放置在不同的地理位置、有不同网络结构的服务器群间作负载均衡。 <BR><BR>　　本地负载均衡能有效地解决数据流量过大、网络负荷过重的问题，并且不需花费昂贵开支购置性能卓越的服务器，充分利用现有设备，避免服务器单点故障造成数据流量的损失。其有灵活多样的均衡策略把数据流量合理地分配给服务器群内的服务器共同负担。即使是再给现有服务器扩充升级，也只是简单地增加一个新的服务器到服务群中，而不需改变现有网络结构、停止现有的服务。 <BR><BR>　　全局负载均衡主要用于在一个多区域拥有自己服务器的站点，为了使全球用户只以一个IP地址或域名就能访问到离自己最近的服务器，从而获得最快的访问速度，也可用于子公司分散站点分布广的大公司通过Intranet（企业内部互联网）来达到资源统一合理分配的目的。 <BR><BR>　　全局负载均衡有以下的特点： <BR><BR>实现地理位置无关性，能够远距离为用户提供完全的透明服务。 <BR>除了能避免服务器、数据中心等的单点失效，也能避免由于ISP专线故障引起的单点失效。 <BR>解决网络拥塞问题，提高服务器响应速度，服务就近提供，达到更好的访问质量。 <BR>网络层次上的负载均衡 <BR>　　针对网络上负载过重的不同瓶颈所在，从网络的不同层次入手，我们可以采用相应的负载均衡技术来解决现有问题。 <BR><BR>　　随着带宽增加，数据流量不断增大，网络核心部分的数据接口将面临瓶颈问题，原有的单一线路将很难满足需求，而且线路的升级又过于昂贵甚至难以实现，这时就可以考虑采用链路聚合（Trunking）技术。 <BR><BR>　　链路聚合技术（第二层负载均衡）将多条物理链路当作一条单一的聚合逻辑链路使用，网络数据流量由聚合逻辑链路中所有物理链路共同承担，由此在逻辑上增大了链路的容量，使其能满足带宽增加的需求。 <BR><BR>　　现代负载均衡技术通常操作于网络的第四层或第七层。第四层负载均衡将一个Internet上合法注册的IP地址映射为多个内部服务器的IP地址，对每次TCP连接请求动态使用其中一个内部IP地址，达到负载均衡的目的。在第四层交换机中，此种均衡技术得到广泛的应用，一个目标地址是服务器群VIP（虚拟IP，Virtual IP address）连接请求的数据包流经交换机，交换机根据源端和目的IP地址、TCP或UDP端口号和一定的负载均衡策略，在服务器IP和VIP间进行映射，选取服务器群中最好的服务器来处理连接请求。 <BR><BR>　　第七层负载均衡控制应用层服务的内容，提供了一种对访问流量的高层控制方式，适合对HTTP服务器群的应用。第七层负载均衡技术通过检查流经的HTTP报头，根据报头内的信息来执行负载均衡任务。 <BR><BR>　　第七层负载均衡优点表现在如下几个方面： <BR><BR>通过对HTTP报头的检查，可以检测出HTTP400、500和600系列的错误信息，因而能透明地将连接请求重新定向到另一台服务器，避免应用层故障。 <BR>可根据流经的数据类型（如判断数据包是图像文件、压缩文件或多媒体文件格式等），把数据流量引向相应内容的服务器来处理，增加系统性能。 <BR>能根据连接请求的类型，如是普通文本、图象等静态文档请求，还是asp、cgi等的动态文档请求，把相应的请求引向相应的服务器来处理，提高系统的性能及安全性。 <BR>　　第七层负载均衡受到其所支持的协议限制（一般只有HTTP），这样就限制了它应用的广泛性，并且检查HTTP报头会占用大量的系统资源，势必会影响到系统的性能，在大量连接请求的情况下，负载均衡设备自身容易成为网络整体性能的瓶颈。 <BR><BR>负载均衡策略 <BR><BR>　　在实际应用中，我们可能不想仅仅是把客户端的服务请求平均地分配给内部服务器，而不管服务器是否宕机。而是想使Pentium III服务器比Pentium II能接受更多的服务请求，一台处理服务请求较少的服务器能分配到更多的服务请求，出现故障的服务器将不再接受服务请求直至故障恢复等等。 <BR><BR>　　选择合适的负载均衡策略，使多个设备能很好的共同完成任务，消除或避免现有网络负载分布不均、数据流量拥挤反应时间长的瓶颈。在各负载均衡方式中，针对不同的应用需求，在OSI参考模型的第二、三、四、七层的负载均衡都有相应的负载均衡策略。 <BR><BR>　　负载均衡策略的优劣及其实现的难易程度有两个关键因素：一、负载均衡算法，二、对网络系统状况的检测方式和能力。 <BR><BR>　　考虑到服务请求的不同类型、服务器的不同处理能力以及随机选择造成的负载分配不均匀等问题，为了更加合理的把负载分配给内部的多个服务器，就需要应用相应的能够正确反映各个服务器处理能力及网络状态的负载均衡算法： <BR><BR>轮循均衡（Round Robin）：每一次来自网络的请求轮流分配给内部中的服务器，从1至N然后重新开始。此种均衡算法适合于服务器组中的所有服务器都有相同的软硬件配置并且平均服务请求相对均衡的情况。 <BR><BR>权重轮循均衡（Weighted Round Robin）：根据服务器的不同处理能力，给每个服务器分配不同的权值，使其能够接受相应权值数的服务请求。例如：服务器A的权值被设计成1，B的权值是3，C的权值是6，则服务器A、B、C将分别接受到10%、30％、60％的服务请求。此种均衡算法能确保高性能的服务器得到更多的使用率，避免低性能的服务器负载过重。 <BR><BR>随机均衡（Random）：把来自网络的请求随机分配给内部中的多个服务器。 <BR><BR>权重随机均衡（Weighted Random）：此种均衡算法类似于权重轮循算法，不过在处理请求分担时是个随机选择的过程。 <BR><BR>响应速度均衡（Response Time）：负载均衡设备对内部各服务器发出一个探测请求（例如Ping），然后根据内部中各服务器对探测请求的最快响应时间来决定哪一台服务器来响应客户端的服务请求。此种均衡算法能较好的反映服务器的当前运行状态，但这最快响应时间仅仅指的是负载均衡设备与服务器间的最快响应时间，而不是客户端与服务器间的最快响应时间。 <BR><BR>最少连接数均衡（Least Connection）：客户端的每一次请求服务在服务器停留的时间可能会有较大的差异，随着工作时间加长，如果采用简单的轮循或随机均衡算法，每一台服务器上的连接进程可能会产生极大的不同，并没有达到真正的负载均衡。最少连接数均衡算法对内部中需负载的每一台服务器都有一个数据记录，记录当前该服务器正在处理的连接数量，当有新的服务连接请求时，将把当前请求分配给连接数最少的服务器，使均衡更加符合实际情况，负载更加均衡。此种均衡算法适合长时处理的请求服务，如FTP。 <BR><BR>处理能力均衡：此种均衡算法将把服务请求分配给内部中处理负荷（根据服务器CPU型号、CPU数量、内存大小及当前连接数等换算而成）最轻的服务器，由于考虑到了内部服务器的处理能力及当前网络运行状况，所以此种均衡算法相对来说更加精确，尤其适合运用到第七层（应用层）负载均衡的情况下。 <BR><BR>DNS响应均衡（Flash DNS）：在Internet上，无论是HTTP、FTP或是其它的服务请求，客户端一般都是通过域名解析来找到服务器确切的IP地址的。在此均衡算法下，分处在不同地理位置的负载均衡设备收到同一个客户端的域名解析请求，并在同一时间内把此域名解析成各自相对应服务器的IP地址（即与此负载均衡设备在同一位地理位置的服务器的IP地址）并返回给客户端，则客户端将以最先收到的域名解析IP地址来继续请求服务，而忽略其它的IP地址响应。在种均衡策略适合应用在全局负载均衡的情况下，对本地负载均衡是没有意义的。 <BR><BR><BR>　　尽管有多种的负载均衡算法可以较好的把数据流量分配给服务器去负载，但如果负载均衡策略没有对网络系统状况的检测方式和能力，一旦在某台服务器或某段负载均衡设备与服务器网络间出现故障的情况下，负载均衡设备依然把一部分数据流量引向那台服务器，这势必造成大量的服务请求被丢失，达不到不间断可用性的要求。所以良好的负载均衡策略应有对网络故障、服务器系统故障、应用服务故障的检测方式和能力： <BR><BR>Ping侦测：通过ping的方式检测服务器及网络系统状况，此种方式简单快速，但只能大致检测出网络及服务器上的操作系统是否正常，对服务器上的应用服务检测就无能为力了。 <BR><BR>TCP Open侦测：每个服务都会开放某个通过TCP连接，检测服务器上某个TCP端口（如Telnet的23口，HTTP的80口等）是否开放来判断服务是否正常。 <BR><BR>HTTP URL侦测：比如向HTTP服务器发出一个对main.html文件的访问请求，如果收到错误信息，则认为服务器出现故障。 <BR>　　负载均衡策略的优劣除受上面所讲的两个因素影响外，在有些应用情况下，我们需要将来自同一客户端的所有请求都分配给同一台服务器去负担，例如服务器将客户端注册、购物等服务请求信息保存的本地数据库的情况下，把客户端的子请求分配给同一台服务器来处理就显的至关重要了。有两种方式可以解决此问题，一是根据IP地址把来自同一客户端的多次请求分配给同一台服务器处理，客户端IP地址与服务器的对应信息是保存在负载均衡设备上的；二是在客户端浏览器cookie内做独一无二的标识来把多次请求分配给同一台服务器处理，适合通过代理服务器上网的客户端。 <BR><BR>　　还有一种路径外返回模式（Out of Path Return），当客户端连接请求发送给负载均衡设备的时候，中心负载均衡设备将请求引向某个服务器，服务器的回应请求不再返回给中心负载均衡设备，即绕过流量分配器，直接返回给客户端，因此中心负载均衡设备只负责接受并转发请求，其网络负担就减少了很多，并且给客户端提供了更快的响应时间。此种模式一般用于HTTP服务器群，在各服务器上要安装一块虚拟网络适配器，并将其IP地址设为服务器群的VIP，这样才能在服务器直接回应客户端请求时顺利的达成三次握手。 <BR>Internet的规模每一百天就会增长一倍，客户希望获得7天24小时的不间断可用性及较快的系统反应时间，而不愿屡次看到某个站点“Server Too Busy”及频繁的系统故障。<BR>　　<BR><IMG alt="" width=9 height=9> <IMG alt="" width=1 height=1> <IMG alt="" width=9 height=9> <IMG alt="" width=1 height=1> <!-- frame contents --><!-- /frame contents --><IMG alt="" width=1 height=1> <IMG alt="" width=9 height=9> <IMG alt="" width=1 height=1> <IMG alt="" width=9 height=9><!-- /PPC Frame -->　　网络的各个核心部分随着业务量的提高、访问量和数据流量的快速增长，其处理能力和计算强度也相应增大，使得单一设备根本无法承担。在此情况下，假如扔掉现有设备去做大量的硬件升级，这样将造成现有资源的浪费，而且假如再面临下一次业务量的提升，这又将导致再一次硬件升级的高额成本投入，甚至性能再卓越的设备也不能满足当前业务量的需求。于是，负载均衡机制应运而生。<BR>　　<BR>　　负载均衡（Load Balance）建立在现有网络结构之上，它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。<BR>　　<BR>　　负载均衡有两方面的含义：首先，大量的并发访问或数据流量分担到多台节点设备上分别处理，减少用户等待响应的时间；其次，单个重负载的运算分担到多台节点设备上做并行处理，每个节点设备处理结束后，将结果汇总，返回给用户，系统处理能力得到大幅度提高。<BR>　　<BR>　　本文所要介绍的负载均衡技术主要是指在均衡服务器群中所有服务器和应用程序之间流量负载的应用，目前负载均衡技术大多数是用于提高诸如在Web服务器、FTP服务器和其它要害任务服务器上的Internet服务器程序的可用性和可伸缩性。 <BR>　　<BR>　　 <BR>　　<BR>　　负载均衡实施要素 <BR>　　<BR>　　负载均衡方案应是在网站建设初期就应考虑的问题，不过有时随着访问流量的爆炸性增长，超出决策者的意料，这也就成为不得不面对的问题。当我们在引入某种负载均衡方案乃至具体实施时，像其他的许多方案一样，首先是确定当前及将来的应用需求，然后在代价与收效之间做出权衡。<BR>　　<BR>　　针对当前及将来的应用需求，分析网络瓶颈的不同所在，我们就需要确立是采用哪一类的负载均衡技术，采用什么样的均衡策略，在可用性、兼容性、安全性等等方面要满足多大的需求，如此等等。<BR>　　<BR>　　不管负载均衡方案是采用花费较少的软件方式，还是购买代价高昂在性能功能上更强的第四层交换机、负载均衡器等硬件方式来实现，亦或其他种类不同的均衡技术，下面这几项都是我们在引入均衡方案时可能要考虑的问题： <BR>　　<BR>　　性能：性能是我们在引入均衡方案时需要重点考虑的问题，但也是一个最难把握的问题。衡量性能时可将每秒钟通过网络的数据包数目做为一个参数，另一个参数是均衡方案中服务器群所能处理的最大并发连接数目，但是，假设一个均衡系统能处理百万计的并发连接数，可是却只能以每秒2个包的速率转发，这显然是没有任何作用的。 性能的优劣与负载均衡设备的处理能力、采用的均衡策略息息相关，并且有两点需要注重：一、均衡方案对服务器群整体的性能，这是响应客户端连接请求速度的要害；二、负载均衡设备自身的性能，避免有大量连接请求时自身性能不足而成为服务瓶颈。 有时我们也可以考虑采用混合型负载均衡策略来提升服务器群的总体性能，如DNS负载均衡与NAT负载均衡相结合。另外，针对有大量静态文档请求的站点，也可以考虑采用高速缓存技术，相对来说更节省费用，更能提高响应性能；对有大量ssl/<A class=ReplaceKeyword href="http://www.knowsky.com/xml.asp" target=_blank><FONT color=#f03331>XML</FONT></A>内容传输的站点，更应考虑采用ssl/xml加速技术。 <BR>　　<BR>　　<BR>　　可扩展性：IT技术日新月异，一年以前最新的产品，现在或许已是网络中性能最低的产品；业务量的急速上升，一年前的网络，现在需要新一轮的扩展。合适的均衡解决方案应能满足这些需求，能均衡不同<A class=ReplaceKeyword href="http://www.knowsky.com/system.asp" target=_blank><FONT color=#f03331>操作系统</FONT></A>和硬件平台之间的负载，能均衡HTTP、邮件、新闻、代理、<A class=ReplaceKeyword href="http://www.knowsky.com/sql.asp" target=_blank><FONT color=#f03331>数据库</FONT></A>、防火墙和 Cache等不同服务器的负载，并且能以对客户端完全透明的方式动态增加或删除某些资源。 <BR>　　<BR>　　<BR>　　灵活性：均衡解决方案应能灵活地提供不同的应用需求，满足应用需求的不断变化。在不同的服务器群有不同的应用需求时，应有多样的均衡策略提供更广泛的选择。 <BR>　　<BR>　　<BR>　　可靠性：在对服务质量要求较高的站点，负载均衡解决方案应能为服务器群提供完全的容错性和高可用性。但在负载均衡设备自身出现故障时，应该有良好的冗余解决方案，提高可靠性。使用冗余时，处于同一个冗余单元的多个负载均衡设备必须具有有效的方式以便互相进行监控，保护系统尽可能地避免遭受到重大故障的损失。 <BR>　　<BR>　　<BR>　　易治理性：不管是通过软件还是硬件方式的均衡解决方案，我们都希望它有灵活、直观和安全的治理方式，这样便于安装、配置、维护和监控，提高工作效率，避免差错。在硬件负载均衡设备上，目前主要有三种治理方式可供选择：一、命令行接口（CLI：Command Line Interface），可通过超级终端连接负载均衡设备串行接口来治理，也能telnet远程登录治理，在初始化配置时，往往要用到前者；二、图形用户接口（GUI：Graphical User Interfaces），有基于普通web页的治理，也有通过Java Applet 进行安全治理，一般都需要治理端安装有某个版本的浏览器；三、SNMP（Simple Network Management Protocol，简单网络治理协议）支持，通过第三方网络治理软件对符合SNMP标准的设备进行治理。 <BR>　　负载均衡配置实例 <BR>　　<BR>　　DNS负载均衡 <BR>　　DNS负载均衡技术是在DNS服务器中为同一个主机名配置多个IP地址，在应答DNS查询时，DNS服务器对每个查询将以DNS文件中主机记录的IP地址按顺序返回不同的解析结果，将客户端的访问引导到不同的机器上去，使得不同的客户端访问不同的服务器，从而达到负载均衡的目的。<BR>　　<BR>　　DNS负载均衡的优点是经济简单易行，并且服务器可以位于internet上任意的位置。但它也存在不少缺点： <BR>　　<BR>　　为了使本DNS服务器和其他DNS服务器及时交互，保证DNS数据及时更新，使地址能随机分配，一般都要将DNS的刷新时间设置的较小，但太小将会使DNS流量大增造成额外的网络问题。 <BR>　　<BR>　　<BR>　　一旦某个服务器出现故障，即使及时修改了DNS设置，还是要等待足够的时间（刷新时间）才能发挥作用，在此期间，保存了故障服务器地址的客户计算机将不能正常访问服务器。 <BR>　　<BR>　　<BR>　　DNS负载均衡采用的是简单的轮循负载算法，不能区分服务器的差异，不能反映服务器的当前运行状态，不能做到为性能较好的服务器多分配请求，甚至会出现客户请求集中在某一台服务器上的情况。 <BR>　　<BR>　　<BR>　　要给每台服务器分配一个internet上的IP地址，这势必会占用过多的IP地址。 <BR>　　判定一个站点是否采用了DNS负载均衡的最简单方式就是连续的ping这个域名，假如多次解析返回的IP地址不相同的话，那么这个站点就很可能采用的就是较为普遍的DNS负载均衡。但也不一定，因为假如采用的是DNS响应均衡，多次解析返回的IP地址也可能会不相同。不妨试试Ping一下www.yesky.com，www.sohu.com，www.yahoo.com。<BR>　　<BR>　　现假设有三台服务器来应对www.test.com的请求。在采用BIND 8.x DNS服务器的unix系统上实现起来比较简单，只需在该域的数据记录中添加类似下面的结果： <BR>　　<BR>　　www1　　IN　　A　　　　　192.1.1.1 <BR>　　www2　　IN　　A　　　　　192.1.1.2 <BR>　　www3　　IN　　A　　　　　192.1.1.3 <BR>　　www　　 IN　　CNAME　　　www1<BR>　　www　　 IN　　CNAME　　　www2<BR>　　www　　 IN