﻿<?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>BlogJava-心有多大舞台便有多大-文章分类-转载的文章</title><link>http://www.blogjava.net/jjwwhmm/category/30259.html</link><description>Embrace changes, pursue excellence, share niceness. 
</description><language>zh-cn</language><lastBuildDate>Thu, 17 Jun 2010 04:44:38 GMT</lastBuildDate><pubDate>Thu, 17 Jun 2010 04:44:38 GMT</pubDate><ttl>60</ttl><item><title>鲜血的教训：美国空军3块钢板的反思</title><link>http://www.blogjava.net/jjwwhmm/articles/323524.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Sun, 13 Jun 2010 08:05:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/articles/323524.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/323524.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/articles/323524.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/323524.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/323524.html</trackback:ping><description><![CDATA[兵器诞生的目的就是为了赢得战争。但是，战争又是极端奇妙而复杂的，无论多么高明的兵器设计师，都无法预想到战争中会发生什么意外。这让兵器的故事
充满了惊险曲折，许多看似不起眼的细节里，都蕴含着让人再三反思的东西。二战期间，在美国空军中曾流传过3块钢板的故事。
<div class="AddTxInfo">http://club.china.com/data/thread/12171906/2713/97/22/1_1.html<br />
</div>
&nbsp;
<p>&nbsp;&nbsp;&nbsp;&nbsp;第一块钢板的故事是运输机飞行员讲的。在飞越驼峰航线支援中国抗战时，美军的运输机队常常遭到日军战斗机的偷袭。C-47运输机只有一层铝
皮，日军的零式战斗机在屁股后面紧追，一通机枪扫射，飞机上就是一串透明窟窿，有时子弹甚至能穿透飞行座椅，夺去飞行员的生命。情急之下，一些美军飞行员
在座椅背后焊上一块钢板。实际上，在与日本飞机激战时，中国空军的飞行员早就用过这个办法。就是靠着这块钢板，他们从日本飞机的火舌下夺回了自己的性命。</p>
&nbsp;
<p>&nbsp;&nbsp;&nbsp;&nbsp;第二块钢板的故事来自一位将军。看过好莱坞大片《拯救大兵瑞恩》的观众也许还记得，片中出现过一个死在滑翔机里的美国将军。这是一段真实的
故事。诺曼底登陆中，美军第101空降师副师长唐.普拉特准将乘坐滑翔机实施空降作战。起飞前，有些人自作聪明，在机头位置副师长的座位下装上厚厚的钢
板，用来防弹。但他们没有想到，由于滑翔机自身没有动力，与牵引的运输机脱钩后，必须保持平衡滑翔降落，而沉重的钢板让滑翔机头重脚轻，一头扎向地面，普
拉特准将也摔断了脖子，成为美军在D日阵亡的唯一将领。</p>
&nbsp;
<p>&nbsp;&nbsp;&nbsp;&nbsp;第三块钢板的故事来自一位数学家。二战后期，美军对德国和日本法西斯展开了大规模战略轰炸，每天都有成千架轰炸机呼啸而去，返回时往往损失
惨重。美国空军对此十分头疼：如果要降低损失，就要往飞机上焊防弹钢板；但如果整个飞机都焊上钢板，速度航程载弹量什么都要受影响。</p>
&nbsp;
<p>&nbsp;&nbsp;&nbsp;&nbsp;怎么办？空军请来数学家亚伯拉罕.沃尔德。沃尔德的方法十分简单。他把统计表发给地勤技师，让他们把飞机上弹洞的位置报上来，然后自己铺开
一张大白纸，画出飞机的轮廓，再把那些小窟窿一个个添上去。画完之后大家一看，飞机浑身上下都是窟窿，只有飞行员座舱和尾翼两个地方几乎是空白。</p>
&nbsp;
<p>&nbsp;&nbsp;&nbsp;&nbsp;沃尔德告诉大家：从数学家的眼光来看，这张图明显不符合概率分布的规律，而明显违反规律的地方往往就是问题的关键。飞行员们一看就明白了：
如果座舱中弹，飞行员就完了；尾翼中弹，飞机失去平衡就要坠落——这两处中弹，轰炸机多半就回不来了，难怪统计数据是一片空白。因此，结论很简单：只需要
给这两个部位焊上钢板就行了。</p>
&nbsp;
<p>&nbsp;&nbsp;&nbsp;&nbsp;第一块钢板是传奇，机智的飞行员用它挽救了自己的生命，战场上曾有过许多这样的传奇故事，但这种传奇往往像火花一闪即逝；第二块钢板则是教
训，是用宝贵的生命换回来的教训，谁都知道焊钢板的人也是好心，但结果却完全相反；而第三块钢板是升华，它用科学的方法，从实战经验中提炼出规律，你可能
想像不到，这块讲科学的钢板挽救了数以万计的飞行员的生命。</p>
&nbsp;
<p>&nbsp;&nbsp;&nbsp;&nbsp;小小的钢板背后，凝聚着多少智慧和鲜血，值得每一位军人去用心体会。一旦战争和你正面相对的时候，你准备把钢板放在哪里？</p>
<img src ="http://www.blogjava.net/jjwwhmm/aggbug/323524.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2010-06-13 16:05 <a href="http://www.blogjava.net/jjwwhmm/articles/323524.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转载]从一则笑话分析需求的陷阱 </title><link>http://www.blogjava.net/jjwwhmm/articles/218314.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Tue, 29 Jul 2008 03:39:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/articles/218314.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/218314.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/articles/218314.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/218314.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/218314.html</trackback:ping><description><![CDATA[<span style="font-size: 12px; font-family: ������">某日，老师在课堂上想考考学生们的智商，就问一个男孩:&#8220;树上有十只鸟，开枪打死一只，还剩几只？&#8221;&nbsp;<br />
男孩反问:&#8220;是无声枪么？&#8221;&nbsp;<br />
&#8220;不是。&#8221;&nbsp;<br />
&#8220;枪声有多大？&#8221;&nbsp;<br />
&#8220;80~100分贝。&#8221;&nbsp;<br />
&#8220;那就是说会震的耳朵疼？&#8221;&nbsp;<br />
&#8220;是。&#8221;&nbsp;<br />
&#8220;在这个城市里打鸟犯不犯法？&#8221;&nbsp;<br />
&#8216;不犯。&#8221;&nbsp;<br />
&#8220;您确定那只鸟真的被打死啦？&#8221;&nbsp;<br />
&#8220;确定。&#8221;老师已经不耐烦了，&#8221;拜托，你告诉我还剩几只就行了，OK？&#8221;&nbsp;<br />
&#8220;OK。鸟里有没有聋子？&#8221;&nbsp;<br />
&#8220;没有。&#8221;&nbsp;<br />
&#8220;有没有关在笼子里的？&#8221;&nbsp;<br />
&#8220;没有。&#8221;&nbsp;<br />
&#8220;边上还有没有其他的树，树上还有没有其他鸟？&#8221;&nbsp;<br />
&#8220;没有。&#8221;&nbsp;<br />
&#8220;方圆十里呢？&#8221;&nbsp;<br />
&#8220;就这么一棵树!&#8221;&nbsp;<br />
&#8220;有没有残疾或饿的飞不动的鸟？&#8221;&nbsp;<br />
&#8220;没有，都身体倍棒。&#8221;&nbsp;<br />
&#8220;算不算怀孕肚子里的小鸟？&#8221;&nbsp;<br />
&#8220;都是公的。&#8221;&nbsp;<br />
&#8220;都不可能怀孕？&#8221;&nbsp;<br />
&#8220;&#8230;&#8230;&#8230;，决不可能。&#8221;&nbsp;<br />
&#8220;打鸟的人眼里有没有花？保证是十只？&#8221;&nbsp;<br />
&#8220;没有花，就十只。&#8221;&nbsp;<br />
老师脑门上的汗已经流下来了，下课铃响起，但男孩仍继续问:&#8220;有没有傻的不怕死的？&#8221;&nbsp;<br />
&#8220;都怕死。&#8221;&nbsp;<br />
&#8220;有没有因为情侣被打中，自己留下来的？&#8221;&nbsp;<br />
&#8220;笨蛋，之前不是说都是公的嘛!&#8221;&nbsp;<br />
&#8220;同志可不可以啊!&#8221;&nbsp;<br />
&#8220;&#8230;&#8230;&#8230;&#8230;，性取向都很正常!&#8221;&nbsp;<br />
&#8220;会不会一枪打死两只？&#8221;&nbsp;<br />
&#8220;不会。&#8221;&nbsp;<br />
&#8220;一枪打死三只呢？&#8221;&nbsp;<br />
&#8220;不会。&#8221;&nbsp;<br />
&#8220;四只呢？&#8221;&nbsp;<br />
&#8220;更不会!&#8221;&nbsp;<br />
&#8220;五只呢？&#8221;&nbsp;<br />
&#8220;绝对不会!!!&#8221;&nbsp;<br />
&#8220;那六只总有可能吧？&#8221;&nbsp;<br />
&#8220;除非你他妈的是猪生的才有可能!&#8221;&nbsp;<br />
&#8220;&#8230;好吧，那么所有的鸟都可以自由活动么？&#8221;&nbsp;<br />
&#8220;完全可以。&#8221;&nbsp;<br />
&#8220;它们受到惊吓起飞时会不会惊慌失措而互相撞上？&#8221;&nbsp;<br />
&#8220;不会，每只鸟都装有卫星导航系统，而且可以自动飞行。&#8221;&nbsp;<br />
&#8220;恩，如果您的回答没有骗人，&#8221;学生满怀信心的回答，&#8220;打死的鸟要是挂在树上没掉下来，那么就剩一只，如果掉下来，就一只不剩。&#8221;&nbsp;<br />
老师当即倒!&nbsp;<br />
</span>
<img src ="http://www.blogjava.net/jjwwhmm/aggbug/218314.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-07-29 11:39 <a href="http://www.blogjava.net/jjwwhmm/articles/218314.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(转载)openssl的man中文文档</title><link>http://www.blogjava.net/jjwwhmm/articles/195853.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Fri, 25 Apr 2008 02:07:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/articles/195853.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/195853.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/articles/195853.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/195853.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/195853.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 发信站:&#160;BBS&#160;水木清华站&#160;(Fri&#160;Nov&#160;10&#160;20:19:30&#160;2000)&#160;&#160;[/b:631992e780] &#160;&#160;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;不久前接到有关ssl的活，&#...&nbsp;&nbsp;<a href='http://www.blogjava.net/jjwwhmm/articles/195853.html'>阅读全文</a><img src ="http://www.blogjava.net/jjwwhmm/aggbug/195853.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-04-25 10:07 <a href="http://www.blogjava.net/jjwwhmm/articles/195853.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(转载 )中国人不能不看，英法等国抵制北京奥运的真实原因！</title><link>http://www.blogjava.net/jjwwhmm/articles/194304.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Sun, 20 Apr 2008 05:20:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/articles/194304.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/194304.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/articles/194304.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/194304.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/194304.html</trackback:ping><description><![CDATA[<p class="font14g">西方国家这次为什么会如次的团结？欧洲的德国、法国，一般是不会冒着这样的风险得罪中国这个经济大国的。伊拉克战
争时德国和法国都和中国站在一边，不支持美国对伊动武。为伊拉克而得罪美国，不符合他们的国家利益啊。法国10年前为了不得罪中国，终止了对台军售，损失
了几十亿的收入。而为什么今天会冒着这么大的风险公然与中国为敌？难到就是为了和自己根本不相干的西藏和奥运？ </p>
<p class="font14g">
<br />
</p>
<p class="font14g">而另一个值得让人思考的问题是，一向是西方老大的美国，为什么这一次这么低调？让英、法、德在前
台唱主角？对于西藏，西方国家很清楚，再怎么闹，中国也不可能做出让步。对于奥运，他们也很清楚，就算西方国家没有一个领导人出席北京奥运会，中国也就是
面子上过不去罢了，对中国有实质影响吗？没有。所以，西藏只是一个幌子，奥运也只是一个幌子。那么他们到底想从中国得到什么？
</p>
<p class="font14g">
<br />
</p>
<p class="font14g">西方国家正面临着10年来经济陷入衰退的危险，他们需要有一个有实力的国家为这次西方经济的衰退
买单。不言而喻，他们不约而同的想到了中国。
做为一个普通老百姓，我对国际经济没有什么研究，但08年一开始我还是隐约到中国经济面临的危险，现在也就想起了温总理说过的一句话：08年也许是中国经
济最困难的一年。现在想起正在进行的这场闹剧，真的有点让人毛骨耸然了。美国不是低调，是很冷静，他们早已经不露声色的出招了： </p>
<p class="font14g">
<br />
</p>
<p class="font14g">1、美元贬值。因为美元贬值，人民币升值，中国16000亿美元的外汇储备已经人间蒸发了
3000亿美元，而且还在继续蒸发中。更要命的是，由于人民币升值，中国出口产品成本增加，沉重的打击中国的出口，许多企业面临倒闭的危险。因为中国企业
的倒闭，西方国家生产企业就可以开始生产复苏。 </p>
<p class="font14g">
<br />
</p>
<p class="font14g">2、通过高油价以拖跨中国经济。中国经济的高速发展需要大量的进品原油，而西方国家则不断的提高石油储备，造成高油价一直持续，以增加中国经济建设的成本。这就是美国为什么要打伊拉克、打伊朗的原因：控制石油就是控制了经济命脉。
</p>
<p class="font14g">
<br />
</p>
<p class="font14g">3、足涨中国金融泡沫。人民币升值，大量热钱自然要涌入中国，造成中国高成本、高币值的经济泡
沫。或许这就是为什么政府就算是背着千夫所指都绝不救市的原因，就是为了打击国际投机资本在中国的恶意圈钱行为，而另一方面却不得不面对成千上万痛不欲生
的股民的唾骂而有可能造成国内社会动荡的危险。现在看了，什么西藏事件、抵制奥运都是不足为道的事。 </p>
<p class="font14g">
<br />
</p>
<p class="font14g">所以，&#8220;西藏&#8221;和&#8220;奥运&#8221;只是西方国家绑架的两个&#8220;人质&#8221;，他们真正的目的不是西藏，也不是奥运，而是以此为要挟，要中国为他们的经济衰退买单。不买单：搞乱你，要死大家一起死。买单：坐下来谈，你答应我我就息事宁人！
</p>
<div style="overflow: hidden; font-size: 1px; color: #f9f9f9; width: 1px; height: 1px; display: inline; float: right;">[ 转自铁血社区 http://bbs.tiexue.net/ ]</div>
<p class="font14g">
<br />
</p>
<p class="font14g">中国政府的冷静是对的，死死抓住经济建设这个中心不动摇才是关键。经济如果一跨，那就什么都跨
了。
国民要冷静，要相互理解，不要给政府出难题。还是那句话：发展才是硬道理，压倒一切的是稳定。一个普通的中国人都能预料到，我相信政府能从容应对。我们要
支持政府打赢这场表面上看起来是舆论战，而事实上是经济的战争 </p>
<p class="font14g">
<br />
</p>
<p class="font14g">我们需要更团结 希望大家奔走先告
</p>
<p class="font14g">
<br />
</p>
<p class="font14g">1、多省油 多乘坐公共交通出行 能做车就不要开车 能开窗户就不要开 空调
</p>
<p class="font14g">
<br />
</p>
<p class="font14g">2、多省电 路灯不用就关掉， 能用耳机就不要开音箱，家电不用就要把整个开关拔下来 又省电又安全 希望政府把夜景工程的灯光就关掉
</p>
<p class="font14g">
<br />
</p>
<p class="font14g">3、支持国货 能买到国货就不要买外国货 促进内需 钱要给自己人赚
</p>
<p class="font14g">
<br />
</p>
<p class="font14g">4、努力工作 多开发和制造更好的产品 实业才是救国之本
</p>
<div style="overflow: hidden; font-size: 1px; color: #f9f9f9; width: 1px; height: 1px; display: inline; float: right;">[ 转自铁血社区 http://bbs.tiexue.net/ ]</div>
<p class="font14g">
<br />
</p>
<p class="font14g">5、尊重自己 尊重国人 不要崇洋媚外
</p>
<p class="font14g">
<br />
</p>
<p class="font14g">6、告诉台湾 西藏 包括其他民族的青年 为什么我们现在还这么痛苦别的国家看不起，因为我们的祖辈太喜欢窝里斗，。
</p>
<p class="font14g">
<br />
</p>
<p class="font14g">7、告诉身边的每一个人 中国只有强大才会有更好的家 ，落后就要挨打挨骂
</p>
<p class="font14g">
<br />
</p>
<p class="font14g">8、政府在进步 督促政府更快的进步 而不是推到他 那样高兴的是美日 痛苦的是自己
</p>
<p class="font14g">
<br />
</p>
<p class="font14g">
<br />
</p>
<p class="font14g">
<br />
</p>
<p class="font14g">如果你是一个爱国的中国人，如果你愿意与所有中国人一起渡过这段艰难的岁月，请在自己恪守以上原则的同时，将本文发给更多的朋友。有我们，中国一定强！
</p>
<img src ="http://www.blogjava.net/jjwwhmm/aggbug/194304.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-04-20 13:20 <a href="http://www.blogjava.net/jjwwhmm/articles/194304.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Mysql 优化的资料(收集转载)</title><link>http://www.blogjava.net/jjwwhmm/articles/194128.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Fri, 18 Apr 2008 16:37:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/articles/194128.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/194128.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/articles/194128.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/194128.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/194128.html</trackback:ping><description><![CDATA[<div class="blog_content">
<p>Mysql 百万级数据优化资料 </p>
<p>一、我们可以且应该优化什么？ </p>
<p>硬件 </p>
<p>操作系统/软件库 </p>
<p>SQL服务器(设置和查询) </p>
<p>应用编程接口(API) </p>
<p>应用程序 </p>
<p>-------------------------------------------------------------------------------- </p>
<p>二、优化硬件 </p>
<p>如果你需要庞大的数据库表(&gt;2G)，你应该考虑使用64位的硬件结构，像Alpha、Sparc或即将推出的IA64。因为MySQL内部使用大量64位的整数，64位的CPU将提供更好的性能。 </p>
<p>对大数据库，优化的次序一般是RAM、快速硬盘、CPU能力。 </p>
<p>更多的内存通过将最常用的键码页面存放在内存中可以加速键码的更新。 </p>
<p>如果不使用事务安全(transaction-safe)的表或有大表并且想避免长文件检查，一台UPS就能够在电源故障时让系统安全关闭。 </p>
<p>对于数据库存放在一个专用服务器的系统，应该考虑1G的以太网。延迟与吞吐量同样重要。 </p>
<p>-------------------------------------------------------------------------------- </p>
<p>三、优化磁盘 </p>
<p>为系统、程序和临时文件配备一个专用磁盘，如果确是进行很多修改工作，将更新日志和事务日志放在专用磁盘上。<br />
低寻道时间对数据库磁盘非常重要。对与大表，你可以估计你将需要log(行数)/log(索引块长度/3*2/(键码长度 +
数据指针长度))+1次寻到才能找到一行。对于有500000行的表，索引Mediun int类型的列，需要log(500000) /
log(1024/3*2/(3 +
2))+1=4次寻道。上述索引需要500000*7*3/2=5.2M的空间。实际上，大多数块将被缓存，所以大概只需要1-2次寻道。<br />
然而对于写入（如上），你将需要4次寻道请求来找到在哪里存放新键码，而且一般要2次寻道来更新索引并写入一行。<br />
对于非常大的数据库，你的应用将受到磁盘寻道速度的限制，随着数据量的增加呈N log N数据级递增。<br />
将数据库和表分在不同的磁盘上。在MySQL中，你可以为此而使用符号链接。<br />
条列磁盘(RAID 0)将提高读和写的吞吐量。<br />
带镜像的条列(RAID 0+1)将更安全并提高读取的吞吐量。写入的吞吐量将有所降低。<br />
不要对临时文件或可以很容易地重建的数据所在的磁盘使用镜像或RAID(除了RAID 0)。<br />
在Linux上，在引导时对磁盘使用命令hdparm -m16 -d1以启用同时读写多个扇区和DMA功能。这可以将响应时间提高5~50%。<br />
在Linux上，用async (默认)和noatime挂载磁盘(mount)。<br />
对于某些特定应用，可以对某些特定表使用内存磁盘，但通常不需要。 </p>
<p>-------------------------------------------------------------------------------- </p>
<p>四、优化操作系统 </p>
<p>不要交换区。如果内存不足，增加更多的内存或配置你的系统使用较少内存。<br />
不要使用NFS磁盘(会有NFS锁定的问题)。<br />
增加系统和MySQL服务器的打开文件数量。(在safe_mysqld脚本中加入ulimit -n #)。<br />
增加系统的进程和线程数量。<br />
如果你有相对较少的大表，告诉文件系统不要将文件打碎在不同的磁道上(Solaris)。<br />
使用支持大文件的文件系统(Solaris)。<br />
选择使用哪种文件系统。在Linux上的Reiserfs对于打开、读写都非常快。文件检查只需几秒种。 </p>
<p>-------------------------------------------------------------------------------- </p>
<p>五、选择应用编程接口 </p>
<p>PERL<br />
可在不同的操作系统和数据库之间移植。<br />
适宜快速原型。<br />
应该使用DBI/DBD接口。<br />
PHP<br />
比PERL易学。<br />
使用比PERL少的资源。<br />
通过升级到PHP4可以获得更快的速度。<br />
C<br />
MySQL的原生接口。<br />
较快并赋予更多的控制。<br />
低层，所以必须付出更多。<br />
C++<br />
较高层次，给你更多的时间来编写应用。<br />
仍在开发中<br />
ODBC<br />
运行在Windows和Unix上。<br />
几乎可在不同的SQL服务器间移植。<br />
较慢。MyODBC只是简单的直通驱动程序，比用原生接口慢19%。<br />
有很多方法做同样的事。很难像很多ODBC驱动程序那样运行，在不同的领域还有不同的错误。<br />
问题成堆。Microsoft偶尔还会改变接口。<br />
不明朗的未来。(Microsoft更推崇OLE而非ODBC)<br />
ODBC<br />
运行在Windows和Unix上。<br />
几乎可在不同的SQL服务器间移植。<br />
较慢。MyODBC只是简单的直通驱动程序，比用原生接口慢19%。<br />
有很多方法做同样的事。很难像很多ODBC驱动程序那样运行，在不同的领域还有不同的错误。<br />
问题成堆。Microsoft偶尔还会改变接口。<br />
不明朗的未来。(Microsoft更推崇OLE而非ODBC)<br />
JDBC<br />
理论上可在不同的操作系统何时据库间移植。<br />
可以运行在web客户端。<br />
Python和其他<br />
可能不错，可我们不用它们。 </p>
<p>-------------------------------------------------------------------------------- </p>
<p>六、优化应用 </p>
<p>应该集中精力解决问题。<br />
在编写应用时，应该决定什么是最重要的：<br />
速度<br />
操作系统间的可移植性<br />
SQL服务器间的可移植性<br />
使用持续的连接。.<br />
缓存应用中的数据以减少SQL服务器的负载。<br />
不要查询应用中不需要的列。<br />
不要使用SELECT * FROM table_name...<br />
测试应用的所有部分，但将大部分精力放在在可能最坏的合理的负载下的测试整体应用。通过以一种模块化的方式进行，你应该能用一个快速&#8220;哑模块&#8221;替代找到的瓶颈，然后很容易地标出下一个瓶颈。<br />
如果在一个批处理中进行大量修改，使用LOCK TABLES。例如将多个UPDATES或DELETES集中在一起。 </p>
<p>-------------------------------------------------------------------------------- </p>
<p>七、应该使用可移植的应用 </p>
<p>Perl DBI/DBD<br />
ODBC<br />
JDBC<br />
Python(或其他有普遍SQL接口的语言)<br />
你应该只使用存在于所有目的SQL服务器中或可以很容易地用其他构造模拟的SQL构造。www.mysql.com上的Crash-me页可以帮助你。<br />
为操作系统/SQL服务器编写包装程序来提供缺少的功能。 </p>
<p>-------------------------------------------------------------------------------- </p>
<p>八、如果你需要更快的速度，你应该： </p>
<p>找出瓶颈(CPU、磁盘、内存、SQL服务器、操作系统、API或应用)并集中全力解决。<br />
使用给予你更快速度/灵活性的扩展。<br />
逐渐了解SQL服务器以便能为你的问题使用可能最快的SQL构造并避免瓶颈。<br />
优化表布局和查询。<br />
使用复制以获得更快的选择(select)速度。<br />
如果你有一个慢速的网络连接数据库，使用压缩客户/服务器协议。<br />
不要害怕时应用的第一个版本不能完美地移植，在你解决问题时，你总是可以在以后优化它。 </p>
<p>-------------------------------------------------------------------------------- </p>
<p>九、优化MySQL </p>
<p>挑选编译器和编译选项。<br />
位你的系统寻找最好的启动选项。<br />
通读MySQL参考手册并阅读Paul DuBios的《MySQL》一书。(已有中文版-译注)<br />
多用EXPLAIN SELECT、SHOW VARIABLES、SHOW STATUS和SHOW PROCESSLIST。<br />
了解查询优化器的工作原理。<br />
优化表的格式。<br />
维护你的表(myisamchk、CHECK TABLE、 OPTIMIZE TABLE)<br />
使用MySQL的扩展功能以让一切快速完成。<br />
如果你注意到了你将在很多场合需要某些函数，编写MySQL UDF函数。<br />
不要使用表级或列级的GRANT，除非你确实需要。<br />
购买MySQL技术支持以帮助你解决问题憨笑 </p>
<p>-------------------------------------------------------------------------------- </p>
<p>十、编译和安装MySQL </p>
<p>通过位你的系统挑选可能最好的编译器，你通常可以获得10-30%的性能提高。<br />
在Linux/Intel平台上，用pgcc(gcc的奔腾芯片优化版)编译MySQL。然而，二进制代码将只能运行在Intel奔腾CPU上。<br />
对于一种特定的平台，使用MySQL参考手册上推荐的优化选项。<br />
一般地，对特定CPU的原生编译器(如Sparc的Sun Workshop)应该比gcc提供更好的性能，但不总是这样。<br />
用你将使用的字符集编译MySQL。<br />
静态编译生成mysqld的执行文件(用--with-mysqld-ldflags=all-static)并用strip sql/mysqld整理最终的执行文件。<br />
注意，既然MySQL不使用C++扩展，不带扩展支持编译MySQL将赢得巨大的性能提高。<br />
如果操作系统支持原生线程，使用原生线程(而不用mit-pthreads)。<br />
用MySQL基准测试来测试最终的二进制代码。 </p>
<p>-------------------------------------------------------------------------------- </p>
<p>十一、维护 </p>
<p>如果可能，偶尔运行一下OPTIMIZE table，这对大量更新的变长行非常重要。<br />
偶尔用myisamchk -a更新一下表中的键码分布统计。记住在做之前关掉MySQL。<br />
如果有碎片文件，可能值得将所有文件复制到另一个磁盘上，清除原来的磁盘并拷回文件。<br />
如果遇到问题，用myisamchk或CHECK table检查表。<br />
用mysqladmin -i10 precesslist extended-status监控MySQL的状态。<br />
用MySQL GUI客户程序，你可以在不同的窗口内监控进程列表和状态。<br />
使用mysqladmin debug获得有关锁定和性能的信息。 </p>
<p>-------------------------------------------------------------------------------- </p>
<p>十二、优化SQL </p>
<p>扬SQL之长，其它事情交由应用去做。使用SQL服务器来做： </p>
<p>找出基于WHERE子句的行。<br />
JOIN表<br />
GROUP BY<br />
ORDER BY<br />
DISTINCT </p>
<p>不要使用SQL来做： </p>
<p>检验数据(如日期)<br />
成为一只计算器 </p>
<p>技巧： </p>
<p>明智地使用键码。<br />
键码适合搜索，但不适合索引列的插入/更新。<br />
保持数据为数据库第三范式，但不要担心冗余信息或这如果你需要更快的速度，创建总结表。<br />
在大表上不做GROUP BY，相反创建大表的总结表并查询它。<br />
UPDATE table set count=count+1 where key_column=constant非常快。<br />
对于大表，或许最好偶尔生成总结表而不是一直保持总结表。<br />
充分利用INSERT的默认值。 </p>
<p>-------------------------------------------------------------------------------- </p>
<p>十三、不同SQL服务器的速度差别（以秒计） </p>
<p>+--------------------------+--------+---------+<br />
|通过键码读取2000000行： | NT | Linux |<br />
+--------------------------+--------+---------+<br />
|mysql | 367 | 249 |<br />
+--------------------------+--------+---------+<br />
|mysql_odbc | 464 | |<br />
+--------------------------+--------+---------+　<br />
|db2_odbc | 1206 | |<br />
+--------------------------+--------+---------+　<br />
|informix_odbc | 121126 | |<br />
+--------------------------+--------+---------+　<br />
|ms-sql_odbc 　 | 1634 | |<br />
+--------------------------+--------+---------+<br />
|oracle_odbc | 20800 | |<br />
+--------------------------+--------+---------+　<br />
|solid_odbc | 877 　 | |<br />
+--------------------------+--------+---------+<br />
|sybase_odbc | 17614 | |<br />
+--------------------------+--------+---------+　 </p>
<p>+--------------------------+--------+---------+　<br />
|插入350768行： | NT | Linux |<br />
+--------------------------+--------+---------+<br />
|mysql | 381 | 206 |<br />
+--------------------------+--------+---------+<br />
|mysql_odbc | 619 　 | |<br />
+--------------------------+--------+---------+<br />
|db2_odbc | 3460 　| |<br />
+--------------------------+--------+---------+<br />
|informix_odbc | 2692 　| |<br />
+--------------------------+--------+---------+<br />
|ms-sql_odbc | 4012 　| |<br />
+--------------------------+--------+---------+<br />
|oracle_odbc | 11291 | |<br />
+--------------------------+--------+---------+　<br />
|solid_odbc | 1801 　| |<br />
+--------------------------+--------+---------+<br />
|sybase_odbc | 4802 　| |<br />
+--------------------------+--------+---------+ </p>
<p>在上述测试中，MySQL配置8M高速缓存运行，其他数据库以默认安装运行。 </p>
<p>-------------------------------------------------------------------------------- </p>
<p>十四、重要的MySQL启动选项 </p>
<p>back_log 如果需要大量新连接，修改它。<br />
thread_cache_size 如果需要大量新连接，修改它。<br />
key_buffer_size 索引页池，可以设成很大。<br />
bdb_cache_size BDB表使用的记录和键吗高速缓存。<br />
table_cache 如果有很多的表和并发连接，修改它。<br />
delay_key_write 如果需要缓存所有键码写入，设置它。<br />
log_slow_queries 找出需花大量时间的查询。<br />
max_heap_table_size 用于GROUP BY<br />
sort_buffer 用于ORDER BY和GROUP BY<br />
myisam_sort_buffer_size 用于REPAIR TABLE<br />
join_buffer_size 在进行无键吗的联结时使用。 </p>
<p>-------------------------------------------------------------------------------- </p>
<p>十五、优化表 </p>
<p>MySQL拥有一套丰富的类型。你应该对每一列尝试使用最有效的类型。<br />
ANALYSE过程可以帮助你找到表的最优类型：SELECT * FROM table_name PROCEDURE ANALYSE()。<br />
对于不保存NULL值的列使用NOT NULL，这对你想索引的列尤其重要。<br />
将ISAM类型的表改为MyISAM。<br />
如果可能，用固定的表格式创建表。<br />
不要索引你不想用的东西。<br />
利用MySQL能按一个索引的前缀进行查询的事实。如果你有索引INDEX(a,b)，你不需要在a上的索引。<br />
不在长CHAR/VARCHAR列上创建索引，而只索引列的一个前缀以节省存储空间。CREATE TABLE table_name (hostname CHAR(255) not null, index(hostname(10)))<br />
对每个表使用最有效的表格式。<br />
在不同表中保存相同信息的列应该有同样的定义并具有相同的列名。 </p>
<p>-------------------------------------------------------------------------------- </p>
<p>十六、MySQL如何次存储数据 </p>
<p>数据库以目录存储。<br />
表以文件存储。<br />
列以变长或定长格式存储在文件中。对BDB表，数据以页面形式存储。<br />
支持基于内存的表。<br />
数据库和表可在不同的磁盘上用符号连接起来。<br />
在Windows上，MySQL支持用.sym文件内部符号连接数据库。 </p>
<p>-------------------------------------------------------------------------------- </p>
<p>十七、MySQL表类型 </p>
<p>HEAP表：固定行长的表，只存储在内存中并用HASH索引进行索引。<br />
ISAM表：MySQL 3.22中的早期B-tree表格式。<br />
MyIASM：IASM表的新版本，有如下扩展：<br />
二进制层次的可移植性。<br />
NULL列索引。<br />
对变长行比ISAM表有更少的碎片。<br />
支持大文件。<br />
更好的索引压缩。<br />
更好的键吗统计分布。<br />
更好和更快的auto_increment处理。<br />
来自Sleepcat的Berkeley DB(BDB)表：事务安全(有BEGIN WORK/COMMIT|ROLLBACK)。 </p>
<p>-------------------------------------------------------------------------------- </p>
<p>十八、MySQL行类型（专指IASM/MyIASM表） </p>
<p>如果所有列是定长格式(没有VARCHAR、BLOB或TEXT)，MySQL将以定长表格式创建表，否则表以动态长度格式创建。<br />
定长格式比动态长度格式快很多并更安全。<br />
动态长度行格式一般占用较少的存储空间，但如果表频繁更新，会产生碎片。<br />
在某些情况下，不值得将所有VARCHAR、BLOB和TEXT列转移到另一个表中，只是获得主表上的更快速度。<br />
利用myiasmchk（对ISAM，pack_iasm），可以创建只读压缩表，这使磁盘使用率最小，但使用慢速磁盘时，这非常不错。压缩表充分地利用将不再更新的日志表 </p>
<p>-------------------------------------------------------------------------------- </p>
<p>十九、MySQL高速缓存（所有线程共享，一次性分配） </p>
<p>键码缓存：key_buffer_size，默认8M。<br />
表缓存：table_cache，默认64。<br />
线程缓存：thread_cache_size，默认0。<br />
主机名缓存：可在编译时修改，默认128。<br />
内存映射表：目前仅用于压缩表。<br />
注意：MySQL没有运行高速缓存，而让操作系统处理。 </p>
<p>-------------------------------------------------------------------------------- </p>
<p>二十、MySQL缓存区变量（非共享，按需分配） </p>
<p>sort_buffer：ORDER BY/GROUP BY<br />
record_buffer：扫描表。<br />
join_buffer_size：无键联结<br />
myisam_sort_buffer_size：REPAIR TABLE<br />
net_buffer_length:对于读SQL语句并缓存结果。<br />
tmp_table_size：临时结果的HEAP表大小。 </p>
<p>-------------------------------------------------------------------------------- </p>
<p>二十一、MySQL表高速缓存工作原理 </p>
<p>每个MyISAM表的打开实例(instance)使用一个索引文件和一个数据文件。如果表被两个线程使用或在同一条查询中使用两次，MyIASM将共享索引文件而是打开数据文件的另一个实例。<br />
如果所有在高速缓存中的表都在使用，缓存将临时增加到比表缓存尺寸大些。如果是这样，下一个被释放的表将被关闭。<br />
你可以通过检查mysqld的Opened_tables变量以检查表缓存是否太小。如果该值太高，你应该增大表高速缓存。 </p>
<p>-------------------------------------------------------------------------------- </p>
<p>二十二、MySQL扩展/优化-提供更快的速度 </p>
<p>使用优化的表类型（HEAP、MyIASM或BDB表）。<br />
对数据使用优化的列。<br />
如果可能使用定长行。<br />
使用不同的锁定类型（SELECT HIGH_PRIORITY，INSERT LOW_PRIORITY）<br />
Auto_increment<br />
REPLACE (REPLACE INTO table_name VALUES (...))<br />
INSERT DELAYED<br />
LOAD DATA INFILE / LOAD_FILE()<br />
使用多行INSERT一次插入多行。<br />
SELECT INTO OUTFILE<br />
LEFT JOIN, STRAIGHT JOIN<br />
LEFT JOIN ，结合IS NULL<br />
ORDER BY可在某些情况下使用键码。<br />
如果只查询在一个索引中的列，将只使用索引树解决查询。<br />
联结一般比子查询快（对大多数SQL服务器亦如此）。<br />
LIMIT<br />
SELECT * from table1 WHERE a &gt; 10 LIMIT 10,20<br />
DELETE * from table1 WHERE a &gt; 10 LIMIT 10<br />
foo IN (常数列表) 高度优化。<br />
GET_LOCK()/RELEASE_LOCK()<br />
LOCK TABLES<br />
INSERT和SELECT可同时运行。<br />
UDF函数可装载进一个正在运行的服务器。<br />
压缩只读表。<br />
CREATE TEMPORARY TABLE<br />
CREATE TABLE .. SELECT<br />
带RAID选项的MyIASM表将文件分割成很多文件以突破某些文件系统的2G限制。<br />
Delay_keys<br />
复制功能 </p>
<p>-------------------------------------------------------------------------------- </p>
<p>二十二、MySQL何时使用索引 </p>
<p>对一个键码使用&gt;, &gt;=, =, &lt;, &lt;=, IF NULL和BETWEEN<br />
SELECT * FROM table_name WHERE key_part1=1 and key_part2 &gt; 5;<br />
SELECT * FROM table_name WHERE key_part1 IS NULL; </p>
<p>当使用不以通配符开始的LIKE<br />
SELECT * FROM table_name WHERE key_part1 LIKE 'jani%' </p>
<p>在进行联结时从另一个表中提取行时<br />
SELECT * from t1,t2 where t1.col=t2.key_part </p>
<p>找出指定索引的MAX()或MIN()值<br />
SELECT MIN(key_part2),MAX(key_part2) FROM table_name where key_part1=10 </p>
<p>一个键码的前缀使用ORDER BY或GROUP BY<br />
SELECT * FROM foo ORDER BY key_part1,key_part2,key_part3 </p>
<p>在所有用在查询中的列是键码的一部分时间<br />
SELECT key_part3 FROM table_name WHERE key_part1=1 </p>
<p>-------------------------------------------------------------------------------- </p>
<p>二十三、MySQL何时不使用索引 </p>
<p>如果MySQL能估计出它将可能比扫描整张表还要快时，则不使用索引。例如如果key_part1均匀分布在1和100之间，下列查询中使用索引就不是很好：<br />
SELECT * FROM table_name where key_part1 &gt; 1 and key_part1 &lt; 90 </p>
<p>如果使用HEAP表且不用=搜索所有键码部分。 </p>
<p>在HEAP表上使用ORDER BY。 </p>
<p>如果不是用键码第一部分<br />
SELECT * FROM table_name WHERE key_part2=1 </p>
<p>如果使用以一个通配符开始的LIKE<br />
SELECT * FROM table_name WHERE key_part1 LIKE '%jani%' </p>
<p>搜索一个索引而在另一个索引上做ORDER BY<br />
SELECT * from table_name WHERE key_part1 = # ORDER BY key2 </p>
<p>-------------------------------------------------------------------------------- </p>
<p>二十四、学会使用EXPLAIN </p>
<p>对于每一条你认为太慢的查询使用EXPLAIN! </p>
<p>mysql&gt; explain select t3.DateOfAction, t1.TransactionID<br />
-&gt; from t1 join t2 join t3<br />
-&gt; where t2.ID = t1.TransactionID and t3.ID = t2.GroupID<br />
-&gt; order by t3.DateOfAction, t1.TransactionID;<br />
+-------+--------+---------------+---------+---------+------------------+------+---------------------------------+<br />
| table | type | possible_keys | key | key_len | ref | rows | Extra |<br />
+-------+--------+---------------+---------+---------+------------------+------+---------------------------------+<br />
| t1 | ALL | NULL | NULL | NULL | NULL | 11 | Using temporary; Using filesort |<br />
| t2 | ref | ID | ID | 4 | t1.TransactionID | 13 | |<br />
| t3 | eq_ref | PRIMARY | PRIMARY | 4 | t2.GroupID | 1 | |<br />
+-------+--------+---------------+---------+---------+------------------+------+---------------------------------+ </p>
<p>ALL和范围类型提示一个潜在的问题。 </p>
<p>-------------------------------------------------------------------------------- </p>
<p>二十五、学会使用SHOW PROCESSLIST </p>
<p>使用SHOW processlist来发现正在做什么：<br />
+----+-------+-----------+----+---------+------+--------------+-------------------------------------+<br />
| Id | User | Host | db | Command | Time | State | Info |<br />
+----+-------+-----------+----+---------+------+--------------+-------------------------------------+<br />
| 6 | monty | localhost | bp | Query | 15 | Sending data | select * from station,station as s1 |<br />
| 8 | monty | localhost | | Query | 0 | | show processlist |<br />
+----+-------+-----------+----+---------+------+--------------+-------------------------------------+ </p>
<p>在mysql或mysqladmin中用KILL来杀死溜掉的线程。<br />
-------------------------------------------------------------------------------- </p>
<p>二十六、如何知晓MySQL解决一条查询 </p>
<p>运行项列命令并试图弄明白其输出：<br />
SHOW VARIABLES;<br />
SHOW COLUMNS FROM ...\G<br />
EXPLAIN SELECT ...\G<br />
FLUSH STATUS;<br />
SELECT ...;<br />
SHOW STATUS; </p>
<p>-------------------------------------------------------------------------------- </p>
<p>二十七、MySQL非常不错 </p>
<p>日志<br />
在进行很多连接时，连接非常快。<br />
同时使用SELECT和INSERT的场合。<br />
在不把更新与耗时太长的选择结合时。<br />
在大多数选择/更新使用唯一键码时。<br />
在使用没有长时间冲突锁定的多个表时。<br />
在用大表时(MySQL使用一个非常紧凑的表格式)。 </p>
<p>-------------------------------------------------------------------------------- </p>
<p>二十八、MySQL应避免的事情 </p>
<p>用删掉的行更新或插入表，结合要耗时长的SELECT。<br />
在能放在WHERE子句中的列上用HAVING。<br />
不使用键码或键码不够唯一而进行JOIN。<br />
在不同列类型的列上JOIN。<br />
在不使用=匹配整个键码时使用HEAP表。<br />
在MySQL监控程序中忘记在UPDATE或DELETE中使用一条WHERE子句。如果想这样做，使用mysql客户程序的--i-am-a-dummy选项。 </p>
<p>-------------------------------------------------------------------------------- </p>
<p>二十九、MySQL各种锁定 </p>
<p>内部表锁定<br />
LOCK TABLES（所有表类型适用）<br />
GET LOCK()/RELEASE LOCK()<br />
页面锁定（对BDB表）<br />
ALTER TABLE也在BDB表上进行表锁定<br />
LOCK TABLES允许一个表有多个读者和一个写者。<br />
一般WHERE锁定具有比READ锁定高的优先级以避免让写入方干等。对于不重要的写入方，可以使用LOW_PRIORITY关键字让锁定处理器优选读取方。<br />
UPDATE LOW_PRIORITY SET value=10 WHERE id=10; </p>
<p>-------------------------------------------------------------------------------- </p>
<p>三十、给MySQL更多信息以更好地解决问题的技巧 </p>
<p>注意你总能去掉(加注释)MySQL功能以使查询可移植： </p>
<p>SELECT /*! SQL_BUFFER_RESULTS */ ...<br />
SELECT SQL_BUFFER_RESULTS ...<br />
将强制MySQL生成一个临时结果集。只要所有临时结果集生成后，所有表上的锁定均被释放。这能在遇到表锁定问题时或要花很长时间将结果传给客户端时有所帮助。<br />
SELECT SQL_SMALL_RESULT ... GROUP BY ...<br />
告诉优化器结果集将只包含很少的行。<br />
SELECT SQL_BIG_RESULT ... GROUP BY ...<br />
告诉优化器结果集将包含很多行。<br />
SELECT STRAIGHT_JOIN ...<br />
强制优化器以出现在FROM子句中的次序联结表。<br />
SELECT ... FROM table_name [USE INDEX (index_list) | IGNORE INDEX (index_list)] table_name2<br />
强制MySQL使用/忽略列出的索引。 </p>
<p>-------------------------------------------------------------------------------- </p>
<p>三十一、事务的例子 </p>
<p>MyIASM表如何进行事务处理:<br />
mysql&gt; LOCK TABLES trans READ, customer WRITE;<br />
mysql&gt; select sum(value) from trans where customer_id=some_id;<br />
mysql&gt; update customer set total_value=sum_from_previous_statement<br />
where customer_id=some_id;<br />
mysql&gt; UNLOCK TABLES; </p>
<p>BDB表如何进行事务:<br />
mysql&gt; BEGIN WORK;<br />
mysql&gt; select sum(value) from trans where customer_id=some_id;<br />
mysql&gt; update customer set total_value=sum_from_previous_statement<br />
where customer_id=some_id;<br />
mysql&gt; COMMIT; </p>
<p>注意你可以通过下列语句回避事务:<br />
UPDATE customer SET value=value+new_value WHERE customer_id=some_id; </p>
<p>-------------------------------------------------------------------------------- </p>
<p>三十二、使用REPLACE的例子 </p>
<p>REPLACE的功能极像INSERT，除了如果一条老记录在一个唯一索引上具有与新纪录相同的值，那么老记录在新纪录插入前则被删除。不使用 </p>
<p>SELECT 1 FROM t1 WHERE key=#<br />
IF found-row<br />
LOCK TABLES t1<br />
DELETE FROM t1 WHERE key1=#<br />
INSERT INTO t1 VALUES (...)<br />
UNLOCK TABLES t1;<br />
ENDIF </p>
<p>而用<br />
REPLACE INTO t1 VALUES (...) </p>
<p>-------------------------------------------------------------------------------- </p>
<p>三十三、一般技巧 </p>
<p>使用短主键。联结表时使用数字而非字符串。<br />
当使用多部分键码时，第一部分应该时最常用的部分。<br />
有疑问时，首先使用更多重复的列以获得更好地键码压缩。<br />
如果在同一台机器上运行MySQL客户和服务器，那么在连接MySQL时则使用套接字而不是TCP/IP（这可以提高性能7.5%）。可在连接MySQL服务器时不指定主机名或主机名为localhost来做到。<br />
如果可能，使用--skip-locking(在某些OS上为默认)，这将关闭外部锁定并将提高性能。<br />
使用应用层哈希值而非长键码：<br />
SELECT * FROM table_name WHERE hash=MD5(concat(col1,col2)) AND<br />
col_1='constant' AND col_2='constant' </p>
<p>在文件中保存需要以文件形式访问的BLOB，在数据库中只保存文件名。<br />
删除所有行比删除一大部分行要快。<br />
如果SQL不够快，研究一下访问数据的较底层接口。 </p>
<p>-------------------------------------------------------------------------------- </p>
<p>三十四、使用MySQL 3.23的好处 </p>
<p>MyISAM：可移植的大表格式<br />
HEAP：内存中的表<br />
Berkeley DB：支持事务的表。<br />
众多提高的限制<br />
动态字符集<br />
更多的STATUS变量<br />
CHECK和REPAIR表<br />
更快的GROUP BY和DISTINCT<br />
LEFT JOIN ... IF NULL的优化<br />
CREATE TABLE ... SELECT<br />
CREATE TEMPORARY table_name (...)<br />
临时HEAP表到MyISAM表的自动转换<br />
复制<br />
mysqlhotcopy脚本 </p>
<p>-------------------------------------------------------------------------------- </p>
<p>三十五、正在积极开发的重要功能 </p>
<p>改进事务处理<br />
失败安全的复制<br />
正文搜索<br />
多个表的删除(之后完成多个表的更新)<br />
更好的键码缓存<br />
原子RENAME (RENAME TABLE foo as foo_old, foo_new as foo)<br />
查询高速缓存<br />
MERGE TABLES<br />
一个更好的GUI客户程序 </p>
<p>MySQL优化简明指南 </p>
<p>-------------------------------------------------------------------------------- </p>
<p>2004-05-25 </p>
<p>一、在编译时优化MySQL<br />
如果你从源代码分发安装MySQL，要注意，编译过程对以后的目标程序性能有重要的影响，不同的编译方式可能得到类似的目标文件，但性能可能相差很大，因
此，在编译安装MySQL适应仔细根据你的应用类型选择最可能好的编译选项。这种定制的MySQL可以为你的应用提供最佳性能。 </p>
<p>技巧：选用较好的编译器和较好的编译器选项，这样应用可提高性能10-30%。（MySQL文档如是说） </p>
<p>1.1、使用pgcc（Pentium GCC)编译器<br />
该编译器（<a href="http://www.goof.com/pcg/%EF%BC%89%E9%92%88%E5%AF%B9%E8%BF%90%E8%A1%8C?...%E7%BB%A7%E8%B0%99%E4%BD%8E%E6%88%90%E6%9D%93%E9%A2%91%E6%91%B9?">http://www.goof.com/pcg/）针对运行?...继谙低成杓频摹?</a> </p>
<p>1.2、仅使用你想使用的字符集编译MySQL<br />
MySQL目前提供多达24种不同的字符集，为全球用户以他们自己的语言插入或查看表中的数据。却省情况下，MySQL安装所有者这些字符集，热然而，最好的选择是指选择一种你需要的。如，禁止除Latin1字符集以外的所有其它字符集： </p>
<p>--------------------------------------------------------------------------------<br />
%&gt;./configure -with-extra-charsets=none [--other-configuration-options]<br />
-------------------------------------------------------------------------------- </p>
<p>1.3、将mysqld编译成静态执行文件<br />
将mysqld编译成静态执行文件而无需共享库也能获得更好的性能。通过在配置时指定下列选项，可静态编译mysqld。 </p>
<p>--------------------------------------------------------------------------------<br />
%&gt;./configure -with-mysqld-ldflags=-all-static [--other-configuration-options]<br />
-------------------------------------------------------------------------------- </p>
<p>1.4、配置样本<br />
下列配置命令常用于提高性能： </p>
<p>--------------------------------------------------------------------------------<br />
%&gt;CFLAGS="-O6 -mpentiumpro -fomit-frame-pointer" CXX=gcc
CXXFLAGS="-O6 -mpentiumpro -fomit-frame-pointer -felide-constructors
-fno-exceptions -fno-rtti" ./configure --prefix=/usr/local
--enable-assembler --with-mysqld-ldflags=-all-static --disable-shared<br />
-------------------------------------------------------------------------------- </p>
<p>二、调整服务器<br />
确保运用正确的编译固然重要，但这只是成功的第一步，配置众多的MySQL变量同样对服务器的正常运行起关键作用。你可以将这些变量的赋值存在一个配置文件中，以确保它们在每次启动MySQL时均起作用，这个配置文件就是my.cnf文件。 </p>
<p>MySQL已经提供了几个my.cnf文件的样本，可在/usr/local/mysqld/share/mysql/目录下找到。这些文件分别命
名为 my-small.cnf、
my-medium.cnf、my-large.cnf和my-huge.cnf，规模说明可在描述配置文件适用的系统类型标题中找到。如果在只有相当少
内存的系统上运行MySQL，而且只是偶尔的用一下，那么my-small.cnf会比较理想，因为它命令mysqld只使用最少的资源。类似地，如果你
计划构建电子商务超市，而且系统拥有2G内存，那么你可能要用到mysql-huge.cnf文件了。 </p>
<p>为了利用这些文件中的一个，你需要复制一个最适合需求的文件，改名为my.cnf。你可以选择使用配置文件三种作用范围的一种： </p>
<p>Global：将my.cnf文件复制到服务器的/etc目录下，这使得配置文件中的变量作用于全局，即对所有服务器上的MySQL数据库服务器有效。<br />
Local：将my.cnf文件复制到[MYSQL-INSTALL-DIR]/var/目录下，使得my.cnf作用于特定的服务器。[MYSQL-INSTALL-DIR]表示MySQL安装目录。<br />
User：你可以再限制作用于特定的用户，将my.cnf复制到用户的根目录下。<br />
究竟如何设置my.cnf中的这些变量呢？更进一步说，你可以设置哪一个变量。虽然所用变量对MySQL服务器相对通用，每一个变量与MySQL的的某些组件有更特定的关系。如变量max_connects归在mysqld类别下。执行下列命令即可知道： </p>
<p>--------------------------------------------------------------------------------<br />
%&gt;/usr/local/mysql/libexec/mysqld --help<br />
-------------------------------------------------------------------------------- </p>
<p>它显示大量的选项及与mysqld相关的变量。你可以很容易地在该行文字之下找出变量： </p>
<p>--------------------------------------------------------------------------------<br />
Possible variables for option --set-variable (-O) are<br />
-------------------------------------------------------------------------------- </p>
<p>然后你可以如下设置my.cnf中的那些变量： </p>
<p>--------------------------------------------------------------------------------<br />
set-variable = max_connections=100<br />
-------------------------------------------------------------------------------- </p>
<p>它设置MySQL服务器的最大并发连接数为100。要确保在my.cnf文件中的[mysqld]标题下插入变量设置。<br />
三、表类型 </p>
<p>很多MySQL用户可能很惊讶，MySQL确实为用户提供5种不同的表类型，称为DBD、HEAP、ISAM、MERGE和MyIASM。DBD归为事务安全类，而其他为非事务安全类。 </p>
<p>3.1、事务安全 </p>
<p>DBD<br />
Berkeley DB(DBD)表是支持事务处理的表，由Sleepycat软件公司(<a href="http://www.sleepycat.com%29%e5%bc%80%e5%8f%91%e3%80%82%e5%ae%83%e6%8f%90%e4%be%9bmysql%e7%94%a8%e6%88%b7%e6%9c%9f%e5%be%85%e5%b7%b2%e4%b9%85%e7%9a%84%e5%8a%9f%e8%83%bd-%e4%ba%8b%e5%8a%a1%e6%8e%a7%e5%88%b6%e3%80%82%e4%ba%8b%e5%8a%a1%e6%8e%a7%e5%88%b6%e5%9c%a8%e4%bb%bb%e4%bd%95%e6%95%b0%e6%8d%ae%e5%ba%93%e7%b3%bb%e7%bb%9f%e4%b8%ad%e9%83%bd%e6%98%af%e4%b8%80%e4%b8%aa%e6%9e%81%e6%9c%89%e4%bb%b7%e5%80%bc%e7%9a%84%e5%8a%9f%e8%83%bd%ef%bc%8c%e5%9b%a0%e4%b8%ba%e5%ae%83%e4%bb%ac%e7%a1%ae%e4%bf%9d%e4%b8%80%e7%bb%84%e5%91%bd%e4%bb%a4%e8%83%bd%e6%88%90%e5%8a%9f%e5%9c%b0%e6%89%a7%e8%a1%8c%e3%80%82/">http://www.sleepycat.com)开发。它提供MySQL用户期待已久的功能-事务控制。事务控制在任何数据库系统中都是一个极有价值的功能，因为它们确保一组命令能成功地执行。</a> </p>
<p>3.2、非事务安全 </p>
<p>HEAP </p>
<p>HEAP表是MySQL中存取数据最快的表。这是因为他们使用存储在动态内存中的一个哈希索引。另一个要点是如果MySQL或服务器崩溃，数据将丢失。 </p>
<p>ISAM </p>
<p>ISAM表是早期MySQL版本的缺省表类型，直到MyIASM开发出来。建议不要再使用它。 </p>
<p>MERGE </p>
<p>MERGE是一个有趣的新类型，在3.23.25之后出现。一个MERGE表实际上是一个相同MyISAM表的集合，合并成一个表，主要是为了效率原因。这样可以提高速度、搜索效率、修复效率并节省磁盘空间。 </p>
<p>MyIASM </p>
<p>这是MySQL的缺省表类型。它基于IASM代码，但有很多有用的扩展。MyIASM比较好的原因： </p>
<p>MyIASM表小于IASM表，所以使用较少资源。<br />
MyIASM表在不同的平台上二进制层可移植。<br />
更大的键码尺寸，更大的键码上限。<br />
3.3、指定表类型 </p>
<p>你可在创建表时指定表的类型。下例创建一个HEAP表： </p>
<p>-------------------------------------------------------------------------------- </p>
<p>mysql&gt;CREATE TABLE email_addresses TYPE=HEAP (<br />
-&gt;email char(55) NOT NULL,<br />
-&gt;name char(30) NOT NULL,<br />
-&gt;PRIMARY KEY(email) ); </p>
<p>-------------------------------------------------------------------------------- </p>
<p>BDB表需要一些配置工作，参见http://www.mysql.com/doc/B/D/BDB_overview.html。 </p>
<p>3.4、更多的表类型 </p>
<p>为了使MySQL管理工作更有趣，即将发布的MySQL 4.0将提供两种新的表类型，称为Innobase和Gemeni。 </p>
<p>4、优化工具 </p>
<p>MySQL服务器本身提供了几条内置命令用于帮助优化。 </p>
<p>4.1、SHOW </p>
<p>你可能有兴趣知道MySQL服务器究竟更了什么，下列命令给出一个总结： </p>
<p>--------------------------------------------------------------------------------<br />
mysql&gt;show status;<br />
-------------------------------------------------------------------------------- </p>
<p>它给出了一个相当长的状态变量及其值的列表。有些变量包含了异常终止客户的数量、异常终止连接的数量、连接尝试的次数、最大并发连接数和大量其他有用的信息。这些信息对找出系统问题和低效极具价值。<br />
SHOW还能做更多的事情。它可以显示关于日志文件、特定数据库、表、索引、进程和权限表中有价值的信息。详见MySQL手册。 </p>
<p>4.2、EXPLAIN </p>
<p>当你面对SELECT语句时，EXPLAIN解释SELECT命令如何被处理。这不仅对决定是否应该增加一个索引，而且对决定一个复杂的Join如何被MySQL处理都是有帮助的。 </p>
<p>4.3、OPTIMIZE </p>
<p>OPTIMIZE语句允许你恢复空间和合并数据文件碎片，对包含变长行的表进行了大量更新和删除后，这样做特别重要。OPTIMIZE目前只工作于MyIASM和BDB表。</p>
</div>
<img src ="http://www.blogjava.net/jjwwhmm/aggbug/194128.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-04-19 00:37 <a href="http://www.blogjava.net/jjwwhmm/articles/194128.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(转)Java中的字符集编码</title><link>http://www.blogjava.net/jjwwhmm/articles/188758.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Wed, 26 Mar 2008 07:11:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/articles/188758.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/188758.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/articles/188758.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/188758.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/188758.html</trackback:ping><description><![CDATA[转载自:<span  style="font-family: 'Lucida Grande'; font-size: 12px; white-space: pre; ">http://china.manufacturer.com/article/study_for_character_encoding_java.htm</span>
<div><font  face="'Lucida Grande'" size="3"><span  style="font-size: 12px; white-space: pre;">这是我看到的最全的介绍字符集编码的文章,尤其是关于<span  style="font-family: 'Times New Roman'; font-size: 16px; white-space: normal; ">setCharacterEncoding()这个方法的解释以及GET方式与POST方式的区别,以前确实是没注意到这一点.<span  style="font-family: 'Lucida Grande'; font-size: 12px; white-space: pre; ">谢谢作者!</span></span></span></font></div>
<div>
<div><font  face="'Lucida Grande'" size="3"><span  style="font-size: 12px; white-space: pre;"><span  style="font-family: 'Times New Roman'; font-size: 16px; white-space: normal; ">
<p class="1">1. 概述</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">本文主要包括以下几个方面：编码基本知识，java，系统软件，url，工具软件等。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">在下面的描述中，将以"中文"两个字为例，经查表可以知道其GB2312编码是"<u>d6d0 cec4</u>"，Unicode编码为"<u>4e2d 6587</u>"，UTF编码就是"<u>e4b8ad e69687</u>"。注意，这两个字没有iso8859-1编码，但可以用iso8859-1编码来"表示"。</p>
<p class="1">2. 编码基本知识</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">最早的编码是iso8859-1，和ascii编码相似。但为了方便表示各种各样的语言，逐渐出现了很多标准编码，重要的有如下几个。</p>
<p class="2">2.1. iso8859-1</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">属于单字节编码，最多能表示的字符范围是0-255，应用于英文系列。比如，字母'a'的编码为0x61=97。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">很明显，iso8859-1编码表示的字符范围很窄，无法表示中文字符。但是，由于是单字节编码，和计算机最基础的表示单位一致，所以很多时候，仍旧使用iso8859-1编码来表示。而且在很多协议上，默认使用该编码。比如，虽然"中文"两个字不存在iso8859-1编码，以gb2312编码为例，应该是"<u>d6d0 cec4</u>"两个字符，使用iso8859-1编码的时候则将它拆开为4个字节来表示："<u>d6 d0 ce c4</u>"（事实上，在进行存储的时候，也是以字节为单位处理的）。而如果是UTF编码，则是6个字节"<u>e4 b8 ad e6 96 87</u>"。很明显，这种表示方法还需要以另一种编码为基础。</p>
<p class="2">2.2. GB2312/GBK</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">这就是汉子的国标码，专门用来表示汉字，是双字节编码，而英文字母和iso8859-1一致（兼容iso8859-1编码）。其中gbk编码能够用来同时表示繁体字和简体字，而gb2312只能表示简体字，gbk是兼容gb2312编码的。</p>
<p class="2">2.3. unicode</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">这是最统一的编码，可以用来表示所有语言的字符，而且是定长双字节（也有四字节的）编码，包括英文字母在内。所以可以说它是不兼容iso8859-1编码的，也不兼容任何编码。不过，相对于iso8859-1编码来说，uniocode编码只是在前面增加了一个0字节，比如字母'a'为"<u>00 61</u>"。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">需要说明的是，定长编码便于计算机处理（注意GB2312/GBK不是定长编码），而unicode又可以用来表示所有字符，所以在很多软件内部是使用unicode编码来处理的，比如java。</p>
<p class="2">2.4. UTF</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">考虑到unicode编码不兼容iso8859-1编码，而且容易占用更多的空间：因为对于英文字母，unicode也需要两个字节来表示。所以unicode不便于传输和存储。因此而产生了utf编码，utf编码兼容iso8859-1编码，同时也可以用来表示所有语言的字符，不过，utf编码是不定长编码，每一个字符的长度从1-6个字节不等。另外，utf编码自带简单的校验功能。一般来讲，英文字母都是用一个字节表示，而汉字使用三个字节。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">注意，虽然说utf是为了使用更少的空间而使用的，但那只是相对于unicode编码来说，如果已经知道是汉字，则使用GB2312/GBK无疑是最节省的。不过另一方面，值得说明的是，虽然utf编码对汉字使用3个字节，但即使对于汉字网页，utf编码也会比unicode编码节省，因为网页中包含了很多的英文字符。</p>
<p class="1">3. java对字符的处理</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">在java应用软件中，会有多处涉及到字符集编码，有些地方需要进行正确的设置，有些地方需要进行一定程度的处理。</p>
<p class="2">3.1. getBytes(charset)</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">这是java字符串处理的一个标准函数，其作用是将字符串所表示的字符按照charset编码，并以字节方式表示。注意字符串在java内存中总是按unicode编码存储的。比如"中文"，正常情况下（即没有错误的时候）存储为"<u>4e2d 6587</u>"，如果charset为"gbk"，则被编码为"<u>d6d0 cec4</u>"，然后返回字节"<u>d6 d0 ce c4</u>"。如果charset为"utf8"则最后是"<u>e4 b8 ad e6 96 87</u>"。如果是"iso8859-1"，则由于无法编码，最后返回 "<u>3f 3f</u>"（两个问号）。</p>
<p class="2">3.2. new String(charset)</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">这是java字符串处理的另一个标准函数，和上一个函数的作用相反，将字节数组按照charset编码进行组合识别，最后转换为unicode存储。参考上述getBytes的例子，"gbk" 和"utf8"都可以得出正确的结果"<u>4e2d 6587</u>"，但iso8859-1最后变成了"<u>003f 003f</u>"（两个问号）。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">因为utf8可以用来表示/编码所有字符，所以new String( str.getBytes( "utf8" ), "utf8" ) === str，即完全可逆。</p>
<p class="2">3.3. setCharacterEncoding()</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">该函数用来设置http请求或者相应的编码。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">对于request，是指提交内容的编码，指定后可以通过getParameter()则直接获得正确的字符串，如果不指定，则默认使用iso8859-1编码，需要进一步处理。参见下述"表单输入"。值得注意的是在执行setCharacterEncoding()之前，不能执行任何getParameter()。java doc上说明：This method must be called prior to reading request parameters or reading input using getReader()。而且，该指定只对POST方法有效，对GET方法无效。分析原因，应该是在执行第一个getParameter()的时候，java将会按照编码分析所有的提交内容，而后续的getParameter()不再进行分析，所以setCharacterEncoding()无效。而对于GET方法提交表单是，提交的内容在URL中，一开始就已经按照编码分析所有的提交内容，setCharacterEncoding()自然就无效。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">对于response，则是指定输出内容的编码，同时，该设置会传递给浏览器，告诉浏览器输出内容所采用的编码。</p>
<p class="2">3.4. 处理过程</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">下面分析两个有代表性的例子，说明java对编码有关问题的处理方法。</p>
<p class="3">3.4.1. 表单输入</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">User input<u>&#160; *(gbk:d6d0 cec4)&#160;&#160;</u>browser<u>&#160; *(gbk:d6d0 cec4)&#160;&#160;</u>web server<u>&#160; iso8859-1(00d6 00d 000ce 00c4)&#160;&#160;</u>class，需要在class中进行处理：getbytes("iso8859-1")为<u>d6 d0 ce c4</u>，new String("gbk")为<u>d6d0 cec4</u>，内存中以unicode编码则为<u>4e2d 6587</u>。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; "><span lang="EN-US" style="font-size: 11pt; font-family: Wingdings; ">l</span>&#160;用户输入的编码方式和页面指定的编码有关，也和用户的操作系统有关，所以是不确定的，上例以gbk为例。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; "><span lang="EN-US" style="font-size: 11pt; font-family: Wingdings; ">l</span>&#160;从browser到web server，可以在表单中指定提交内容时使用的字符集，否则会使用页面指定的编码。而如果在url中直接用?的方式输入参数，则其编码往往是操作系统本身的编码，因为这时和页面无关。上述仍旧以gbk编码为例。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; "><span lang="EN-US" style="font-size: 11pt; font-family: Wingdings; ">l</span>&#160;Web server接收到的是字节流，默认时（getParameter）会以iso8859-1编码处理之，结果是不正确的，所以需要进行处理。但如果预先设置了编码（通过request. setCharacterEncoding ()），则能够直接获取到正确的结果。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; "><span lang="EN-US" style="font-size: 11pt; font-family: Wingdings; ">l</span>&#160;在页面中指定编码是个好习惯，否则可能失去控制，无法指定正确的编码。</p>
<p class="3">3.4.2. 文件编译</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">假设文件是gbk编码保存的，而编译有两种编码选择：gbk或者iso8859-1，前者是中文windows的默认编码，后者是linux的默认编码，当然也可以在编译时指定编码。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">Jsp<u>&#160; *(gbk:d6d0 cec4)&#160;&#160;</u>java file<u>&#160; *(gbk:d6d0 cec4)&#160;&#160;</u>compiler read<u>&#160; uincode(gbk: 4e2d 6587; iso8859-1: 00d6 00d 000ce 00c4)&#160;&#160;</u>compiler write<u>&#160; utf(gbk: e4b8ad e69687; iso8859-1: *)&#160;&#160;</u>compiled file<u>&#160; unicode(gbk: 4e2d 6587; iso8859-1: 00d6 00d 000ce 00c4)&#160;&#160;</u>class。所以用gbk编码保存，而用iso8859-1编译的结果是不正确的。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">class<u>&#160; unicode(4e2d 6587)&#160;&#160;</u>system.out / jsp.out<u>&#160; gbk(d6d0 cec4)&#160;&#160;</u>os console / browser。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; "><span lang="EN-US" style="font-size: 11pt; font-family: Wingdings; ">l</span>&#160;文件可以以多种编码方式保存，中文windows下，默认为ansi/gbk。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; "><span lang="EN-US" style="font-size: 11pt; font-family: Wingdings; ">l</span>&#160;编译器读取文件时，需要得到文件的编码，如果未指定，则使用系统默认编码。一般class文件，是以系统默认编码保存的，所以编译不会出问题，但对于jsp文件，如果在中文windows下编辑保存，而部署在英文linux下运行/编译，则会出现问题。所以需要在jsp文件中用pageEncoding指定编码。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; "><span lang="EN-US" style="font-size: 11pt; font-family: Wingdings; ">l</span>&#160;Java编译的时候会转换成统一的unicode编码处理，最后保存的时候再转换为utf编码。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; "><span lang="EN-US" style="font-size: 11pt; font-family: Wingdings; ">l</span>&#160;当系统输出字符的时候，会按指定编码输出，对于中文windows下，System.out将使用gbk编码，而对于response（浏览器），则使用jsp文件头指定的contentType，或者可以直接为response指定编码。同时，会告诉browser网页的编码。如果未指定，则会使用iso8859-1编码。对于中文，应该为browser指定输出字符串的编码。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; "><span lang="EN-US" style="font-size: 11pt; font-family: Wingdings; ">l</span>&#160;browser显示网页的时候，首先使用response中指定的编码（jsp文件头指定的contentType最终也反映在response上），如果未指定，则会使用网页中meta项指定中的contentType。</p>
<p class="2">3.5. 几处设置</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">对于web应用程序，和编码有关的设置或者函数如下。</p>
<p class="3">3.5.1. jsp编译</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">指定文件的存储编码，很明显，该设置应该置于文件的开头。例如：&lt;%@page pageEncoding="GBK"%>。另外，对于一般class文件，可以在编译的时候指定编码。</p>
<p class="3">3.5.2. jsp输出</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">指定文件输出到browser是使用的编码，该设置也应该置于文件的开头。例如：&lt;%@ page contentType="text/html; charset= GBK" %>。该设置和response.setCharacterEncoding("GBK")等效。</p>
<p class="3">3.5.3. meta设置</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">指定网页使用的编码，该设置对静态网页尤其有作用。因为静态网页无法采用jsp的设置，而且也无法执行response.setCharacterEncoding()。例如：&lt;<st1:place w:st="on">META http-equiv="Content-Type" content="text/html; charset=GBK" /></st1:place></p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">如果同时采用了jsp输出和meta设置两种编码指定方式，则jsp指定的优先。因为jsp指定的直接体现在response中。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">需要注意的是，apache有一个设置可以给无编码指定的网页指定编码，该指定等同于jsp的编码指定方式，所以会覆盖静态网页中的meta指定。所以有人建议关闭该设置。</p>
<p class="3">3.5.4. form设置</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">当浏览器提交表单的时候，可以指定相应的编码。例如：&lt;form accept-charset= "gb2312">。一般不必不使用该设置，浏览器会直接使用网页的编码。</p>
<p class="1">4. 系统软件</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">下面讨论几个相关的系统软件。</p>
<p class="2">4.1. mysql数据库</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">很明显，要支持多语言，应该将数据库的编码设置成utf或者unicode，而utf更适合与存储。但是，如果中文数据中包含的英文字母很少，其实unicode更为适合。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">数据库的编码可以通过mysql的配置文件设置，例如default-character-set=utf8。还可以在数据库链接URL中设置，例如： useUnicode=true&amp;characterEncoding=UTF-8。注意这两者应该保持一致，在新的sql版本里，在数据库链接URL里可以不进行设置，但也不能是错误的设置。</p>
<p class="2">4.2. apache</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">appache和编码有关的配置在httpd.conf中，例如AddDefaultCharset UTF-8。如前所述，该功能会将所有静态页面的编码设置为UTF-8，最好关闭该功能。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">另外，apache还有单独的模块来处理网页响应头，其中也可能对编码进行设置。</p>
<p class="2">4.3. linux默认编码</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">这里所说的linux默认编码，是指运行时的环境变量。两个重要的环境变量是LC_ALL和LANG，默认编码会影响到java URLEncode的行为，下面有描述。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">建议都设置为"zh_CN.UTF-8"。</p>
<p class="2">4.4. 其它</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">为了支持中文文件名，linux在加载磁盘时应该指定字符集，例如：mount /dev/hda5 /mnt/hda5/ -t ntfs -o iocharset=gb2312。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">另外，如前所述，使用GET方法提交的信息不支持request.setCharacterEncoding()，但可以通过tomcat的配置文件指定字符集，在tomcat的server.xml文件中，形如：&lt;Connector ... URIEncoding="GBK"/>。这种方法将统一设置所有请求，而不能针对具体页面进行设置，也不一定和browser使用的编码相同，所以有时候并不是所期望的。</p>
<p class="1">5. URL地址</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">URL地址中含有中文字符是很麻烦的，前面描述过使用GET方法提交表单的情况，使用GET方法时，参数就是包含在URL中。</p>
<p class="2">5.1. URL编码</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">对于URL中的一些特殊字符，浏览器会自动进行编码。这些字符除了"/?&amp;"等外，还包括unicode字符，比如汉子。这时的编码比较特殊。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">IE有一个选项"总是使用UTF-8发送URL"，当该选项有效时，IE将会对特殊字符进行UTF-8编码，同时进行URL编码。如果改选项无效，则使用默认编码"GBK"，并且不进行URL编码。但是，对于URL后面的参数，则总是不进行编码，相当于UTF-8选项无效。比如"中文.html?a=中文"，当UTF-8选项有效时，将发送链接"%<u>e4%b8%ad%e6%96%87.html?a=\x4e\x2d\x65\x87</u>"；而UTF-8选项无效时，将发送链接"<u>\x4e\x2d\x65\x87.html?a=\x4e\x2d\x65\x87</u>"。注意后者前面的"中文"两个字只有4个字节，而前者却有18个字节，这主要时URL编码的原因。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">当web server（tomcat）接收到该链接时，将会进行URL解码，即去掉"%"，同时按照ISO8859-1编码（上面已经描述，可以使用URLEncoding来设置成其它编码）识别。上述例子的结果分别是"<u>\ue4\ub8\uad\ue6\u96\u87.html?a=\u4e\u2d\u65\u87</u>"和"<u>\u4e\u2d\u65\u87.html?a=\u4e\u2d\u65\u87</u>"，注意前者前面的"中文"两个字恢复成了6个字符。这里用"\u"，表示是unicode。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">所以，由于客户端设置的不同，相同的链接，在服务器上得到了不同结果。这个问题不少人都遇到，却没有很好的解决办法。所以有的网站会建议用户尝试关闭UTF-8选项。不过，下面会描述一个更好的处理办法。</p>
<p class="2">5.2. rewrite</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">熟悉的人都知道，apache有一个功能强大的rewrite模块，这里不描述其功能。需要说明的是该模块会自动将URL解码（去除%），即完成上述web server（tomcat）的部分功能。有相关文档介绍说可以使用[NE]参数来关闭该功能，但我试验并未成功，可能是因为版本（我使用的是apache&#160;<st1:chsdate year="1899" month="12" day="30" islunardate="False" isrocdate="False" w:st="on">2.0.54）问题。另外，当参数中含有"?&amp; "等符号的时候，该功能将导致系统得不到正常结果。</st1:chsdate></p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">rewrite本身似乎完全是采用字节处理的方式，而不考虑字符串的编码，所以不会带来编码问题。</p>
<p class="2">5.3. URLEncode.encode()</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">这是Java本身提供对的URL编码函数，完成的工作和上述UTF-8选项有效时浏览器所做的工作相似。值得说明的是，java已经不赞成不指定编码来使用该方法（deprecated）。应该在使用的时候增加编码指定。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">当不指定编码的时候，该方法使用系统默认编码，这会导致软件运行结果得不确定。比如对于"中文"，当系统默认编码为"gb2312"时，结果是"%<u>4e%2d%65%87</u>"，而默认编码为"UTF-8"，结果却是"%<u>e4%b8%ad%e6%96%87</u>"，后续程序将难以处理。另外，这儿说的系统默认编码是由运行tomcat时的环境变量LC_ALL和LANG等决定的，曾经出现过tomcat重启后就出现乱码的问题，最后才郁闷的发现是因为修改修改了这两个环境变量。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">建议统一指定为"UTF-8"编码，可能需要修改相应的程序。</p>
<p class="2">5.4. 一个解决方案</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">上面说起过，因为浏览器设置的不同，对于同一个链接，web server收到的是不同内容，而软件系统有无法知道这中间的区别，所以这一协议目前还存在缺陷。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">针对具体问题，不应该侥幸认为所有客户的IE设置都是UTF-8有效的，也不应该粗暴的建议用户修改IE设置，要知道，用户不可能去记住每一个web server的设置。所以，接下来的解决办法就只能是让自己的程序多一点智能：根据内容来分析编码是否UTF-8。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">比较幸运的是UTF-8编码相当有规律，所以可以通过分析传输过来的链接内容，来判断是否是正确的UTF-8字符，如果是，则以UTF-8处理之，如果不是，则使用客户默认编码（比如"GBK"），下面是一个判断是否UTF-8的例子，如果你了解相应规律，就容易理解。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">public static boolean isValidUtf8(byte[] b,int aMaxCount){</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">&#160;&#160;&#160;&#160;&#160;&#160; int lLen=b.length,lCharCount=0;</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">&#160;&#160;&#160;&#160;&#160;&#160; for(int i=0;i&lt;lLen &amp;&amp; lCharCount&lt;aMaxCount;++lCharCount){</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; byte lByte=b[i++];//to fast operation, ++ now, ready for the following for(;;)</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if(lByte>=0) continue;//>=0 is normal ascii</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if(lByte&lt;(byte)0xc0 || lByte>(byte)0xfd) return false;</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; int lCount=lByte>(byte)0xfc?5:lByte>(byte)0xf8?4</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; :lByte>(byte)0xf0?3:lByte>(byte)0xe0?2:1;</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if(i+lCount>lLen) return false;</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; for(int j=0;j&lt;lCount;++j,++i) if(b[i]>=(byte)0xc0) return false;</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">&#160;&#160;&#160;&#160;&#160;&#160; return true;</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">}</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">相应地，一个使用上述方法的例子如下：</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">public static String getUrlParam(String aStr,String aDefaultCharset)</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">throws UnsupportedEncodingException{</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">&#160;&#160;&#160;&#160;&#160;&#160; if(aStr==null) return null;</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">&#160;&#160;&#160;&#160;&#160;&#160; byte[] lBytes=aStr.getBytes("ISO-8859-1");</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">&#160;&#160;&#160;&#160;&#160;&#160; return new String(lBytes,StringUtil.isValidUtf8(lBytes)?"utf8":aDefaultCharset);</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">}</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">不过，该方法也存在缺陷，如下两方面：</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; "><span lang="EN-US" style="font-family: Wingdings; ">l</span>&#160;没有包括对用户默认编码的识别，这可以根据请求信息的语言来判断，但不一定正确，因为我们有时候也会输入一些韩文，或者其他文字。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; "><span lang="EN-US" style="font-family: Wingdings; ">l</span>&#160;可能会错误判断UTF-8字符，一个例子是"学习"两个字，其GBK编码是"&#160;<u>\xd1\xa7\xcf\xb0</u>"，如果使用上述isValidUtf8方法判断，将返回true。可以考虑使用更严格的判断方法，不过估计效果不大。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">有一个例子可以证明google也遇到了上述问题，而且也采用了和上述相似的处理方法，比如，如果在地址栏中输入"<a href="http://www.google.com/search?hl=zh-CN&amp;newwindow=1&amp;q=%E5%AD%A6%E4%B9%A0">http://www.google.com/search?hl=zh-CN&amp;newwindow=1&amp;q=学习</a>"，google将无法正确识别，而其他汉字一般能够正常识别。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">最后，应该补充说明一下，如果不使用rewrite规则，或者通过表单提交数据，其实并不一定会遇到上述问题，因为这时可以在提交数据时指定希望的编码。另外，中文文件名确实会带来问题，应该谨慎使用。</p>
<p class="1">6. 其它</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">下面描述一些和编码有关的其他问题。</p>
<p class="2">6.1. SecureCRT</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">除了浏览器和控制台与编码有关外，一些客户端也很有关系。比如在使用SecureCRT连接linux时，应该让SecureCRT的显示编码（不同的session，可以有不同的编码设置）和linux的编码环境变量保持一致。否则看到的一些帮助信息，就可能是乱码。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">另外，mysql有自己的编码设置，也应该保持和SecureCRT的显示编码一致。否则通过SecureCRT执行sql语句的时候，可能无法处理中文字符，查询结果也会出现乱码。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">对于Utf-8文件，很多编辑器（比如记事本）会在文件开头增加三个不可见的标志字节，如果作为mysql的输入文件，则必须要去掉这三个字符。（用linux的vi保存可以去掉这三个字符）。一个有趣的现象是，在中文windows下，创建一个新txt文件，用记事本打开，输入"连通"两个字，保存，再打开，你会发现两个字没了，只留下一个小黑点。</p>
<p class="2">6.2. 过滤器</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">如果需要统一设置编码，则通过filter进行设置是个不错的选择。在filter class中，可以统一为需要的请求或者回应设置编码。参加上述setCharacterEncoding()。这个类apache已经给出了可以直接使用的例子SetCharacterEncodingFilter。</p>
<p class="2">6.3. POST和GET</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">很明显，以POST提交信息时，URL有更好的可读性，而且可以方便的使用setCharacterEncoding()来处理字符集问题。但GET方法形成的URL能够更容易表达网页的实际内容，也能够用于收藏。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">从统一的角度考虑问题，建议采用GET方法，这要求在程序中获得参数是进行特殊处理，而无法使用setCharacterEncoding()的便利，如果不考虑rewrite，就不存在IE的UTF-8问题，可以考虑通过设置URIEncoding来方便获取URL中的参数。</p>
<p class="2">6.4. 简繁体编码转换</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">GBK同时包含简体和繁体编码，也就是说同一个字，由于编码不同，在GBK编码下属于两个字。有时候，为了正确取得完整的结果，应该将繁体和简体进行统一。可以考虑将UTF、GBK中的所有繁体字，转换为相应的简体字，BIG5编码的数据，也应该转化成相应的简体字。当然，仍旧以UTF编码存储。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">例如，对于"语言 語言"，用UTF表示为"<u>\x</u><u>E8\xAF\xAD\xE8\xA8\x80 \xE8\xAA\x9E\xE8\xA8\x80</u>"，进行简繁体编码转换后应该是两个相同的 "<u>\x</u><u>E8\xAF\xAD\xE8\xA8\x80></u>"。</p>
<p class="MsoBodyTextIndent" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; ">&#160;</p>
<p class="MsoBodyTextIndent" align="right" style="word-break: break-all; margin-top: 0cm; margin-right: 0cm; margin-bottom: 6pt; margin-left: 0cm; text-align: justify; text-indent: 10pt; font-size: 10.5pt; font-family: 'Times New Roman'; "><a href="http://china.eceel.com/">Manufacturer.com</a>&#160;刘科垠</p>
</span></span></font></div>
</div>
<img src ="http://www.blogjava.net/jjwwhmm/aggbug/188758.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-03-26 15:11 <a href="http://www.blogjava.net/jjwwhmm/articles/188758.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]使用复制来提升MySQL的高可用性和处理能力</title><link>http://www.blogjava.net/jjwwhmm/articles/187771.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Fri, 21 Mar 2008 11:03:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/articles/187771.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/187771.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/articles/187771.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/187771.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/187771.html</trackback:ping><description><![CDATA[<table style="table-layout: fixed; word-break: break-all" cellspacing="1" cellpadding="3" width="98%" bgcolor="#cccccc" border="0">
    <tbody>
        <tr bgcolor="#f8f8f8">
            <td>
            <p><a href="http://blogger.org.cn/blog/blog.asp?name=lhwork" target="_blank">lhwork</a> 发表于 2007-1-19 9:30:08 </p>
            </td>
        </tr>
        <tr bgcolor="#ffffff">
            <td height="0">
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td>
                        <p>昨晚看了一晚上的MySQL文档，主要是关于MySQL的复制方面的文档，用的工具是MySQL的帮助文档+金山词霸。</p>
                        <p>终于比较大概的了解了如何通过复制来提升MySQL数据库的高可用性和处理能力，不过还没有经过实际的试验，但整体的思想是清楚了，下面把思路大概的描述一下，有机会再进行实验。</p>
                        <p>首先在服务器端采用1+N的模型来安装和配置MySQL数据库。1就是一个master数据库，N就是一至多个slave数据库。master数据库必须启用binlog模式，关于这两种数据库的配置参见MySQL的文档。配置完成后就形成了一个1+N的复制集群，当对master进行修改时会自动把修改的数据更新到N个slave数据库上。但是有一个注意的是，所有的修改操作包括添加、删除、修改等语句必须作用在master数据库上，这样才能使数据可靠的复制到其他slave服务器上。另外，由于slave服务器只用作查询，因此选用MyISAM的存储引擎可以提高查询的速度。</p>
                        <p>而在客户端呢？如何使客户端程序能均衡的使用这些可用的服务器呢？而且更新操作只能对master进行处理。这个岂不是应用程序对数据库的操作逻辑非常的复杂？</p>
                        <p>其实没有那么复杂，MySQL为我们提供了接口可以将这些复杂的操作透明化。下面主要介绍采用JDBC的客户端如何工作在基于复制的集群环境中，其他编程语言请参照mysql的文档。</p>
                        <p>MySQL最新的JDBC驱动程序包中提供了一个驱动类就是 com.mysql.jdbc.ReplicationDriver 。这个驱动类允许在url中设置多个mysql主机地址，例如：</p>
                        <p><font face="Courier New" color="#3366ff">jdbc:mysql://master1,slave1,slave2/dlog?autoReconnect=true&amp;roundRobinLoadBalance=true</font></p>
                        <p><font face="Courier New">在上面的url中，有三个主机地址分别是master1,slave1,slave2，其中</font><font face="Arial">ReplicationDriver 规定第一个主机是master主机地址，剩下的全部是slave主机。另外有两个参数必须指定为true，就是autoReconnect和roundRobinLoadBalance。</font></p>
                        <p>使用这个驱动和配置后还不能马上解决所有的问题，我们还需要对程序做一些小改动。</p>
                        <p>我们必须告诉驱动程序，哪些语句的执行是作用在master数据库，而哪些语句的执行作用在slave数据库上。</p>
                        <p>ReplicationDriver 是通过Connection对象的readOnly属性来判断该操作是否为更新操作。因此我们在执行一个sql语句的时候必须调用一下setReadOnly告诉驱动程序当前执行的操作是否是只读。如果你是使用hibernate操作数据库的，那可以调用Query.setReadOnly方法。</p>
                        <p>以上就是整个思路的大概描述，猜想肯定还有存在一些问题，例如因为数据的复制过程是异步的，也是说有可能执行了某个更新操作，但是查询的时候查不到的情况出现。当然这些问题只能在实际的过程中进行解决。</p>
                        <p>另外关于最新版本的MySQL 5.1有一个集群的功能，不过经过研究发现这个东西简直就是儿戏，实在搞不懂MySQL怎么会做这么不负责任的设计，因为这个特性要求数据库是整个load到内存中的，也就是说你的数据有多大，内存就得有多大，怎么说呢？ 如果你真的内存足够大，你去试试吧，反正这种方案已经被我否决了，希望MySQL能改进一下。</p>
                        </td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/jjwwhmm/aggbug/187771.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-03-21 19:03 <a href="http://www.blogjava.net/jjwwhmm/articles/187771.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>