??xml version="1.0" encoding="utf-8" standalone="yes"?> 一、模版修?/p>
在导Ӟpowerdesigner默认为我们提供了很多的模版,在工h中选择【Report--->Report Template】即可看到所有的默认模版。如图一Q?/p>
图一 模版列表 q里我们Z导出powerdesigner中创建的表,在工h中选择【Report--->Reports?快捷键Ctrl+E),然后创徏一个New Report 图二 创徏新的Report 从工h【Report--->Print Preview】或者点d?img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" alt="" src="http://pic002.cnblogs.com/images/2011/28023/2011042411342378.png" />同样可以预览导出到word的效果了。效果如图三所C: 图三 导出到word中预览效?/p>
从【图三】中的工h里面HTM和RTF两种导出格式。如果导出到word选择RTF格式卛_Q但是我们从【图三】中看出U色标出的部分,1 是word的页眉,同样q有脚信息 Q? 是一些列的属性清单?/p>
囑֛ 讄늜、页?/p>
在【图四】中Q选择Header/Footer后,删掉Header里面?MODULE% %MODELNAME%Q删掉Footer里面?APPNAME% %DATE% | %PAGE%QUser_defined footer׃自动勾上Q这样就L了页眉、页脚了 q有其他的比如表前面的自增序PW一中的创、版本、日期信息也不需要,我们可以q行配置LQ如下【图五】【图六?/p>
囑֛ 图五 Properties配置 在图五中Q在默认配置?General)勾上No paragraph numbering卛_取消表前面的自增序号Q在Title Page中选择 No Title Page׃会生成第一中关于创徏者、版本、日期等信息?/p>
在【图三】中Q预览看到的内容太多Q就必须删除一些我们不需要的内容Q经q删减之后,如下【图六】所C?/p>
囑օ 在【图六】中右键单击【List of Table Columns - ?lt;%PARENT%>列说明】,从菜单中选择 Edit Title...Q就可以~辑成现在我们已看到的。然后,在右键菜单中选择Layout...Q选择我们所需要显C的内容,Code表示列名Uͼ一般用英文单词或拼韛_母表C,Name一般用中文描述QData Type 表示数据cdQComment表示字段备注或字D说明等?/p>
到此基本上已l完成了powerdesigner模版的修?/p>
二、导 然后点击[Report---->Generate RTF]导出到word中,最后我们看看导出到word的效果,如下图: 图七 导出到word效果 三、保存模?/p>
通过上文Q我们完成了自己所需的模版,然后׃存,以后可以直接使用卛_Q在工具栏中[Report--->Create Template From Section]Q然后Ctrl+S׃要求保存Q取名保存即可?/p>,如下图二所以,选择Standard Physical ReportQ这里选择的标准的模版Q点击OK定?/p>
大多数的MySQL服务器都开启了查询~存。这是提高性最有效的方法之一Q而且q是?/span>MySQL的数据库引擎处理的。当有很多相同的查询被执行了多次的时候,q些查询l果会被攑ֈ一个缓存中Q这P后箋的相同的查询׃用操作表而直接访问缓存结果了?/span>
q里最主要的问题是Q对于程序员来说Q这个事情是很容易被忽略的。因为,我们某些查询语句会让MySQL不用缓存。请看下面的CZQ?/span>
1 // 查询~存不开?/span>
2 $r = mysql_query("SELECT username FROM user WHERE signup_date >= CURDATE()");
3
4 // 开启查询缓?/span>
5 $today = date("Y-m-d");
6 $r = mysql_query("SELECT username FROM user WHERE signup_date >= '$today'");
上面两条SQL语句的差别就?/span> CURDATE() Q?/span>MySQL的查询缓存对q个函数不v作用。所以,?/span> NOW() ?/span> RAND() 或是其它的诸如此cȝSQL函数都不会开启查询缓存,因ؓq些函数的返回是会不定的易变的。所以,你所需要的是用一个变量来代替MySQL的函敎ͼ从而开启缓存?/span>
2. 当只要一行数据时使用 LIMIT 1
当你查询表的有些时候,你已l知道结果只会有一条结果,但因Z可能需要去fetch游标Q或是你也许会去查返回的记录数?/span>
在这U情况下Q加?/span> LIMIT 1 可以增加性能。这样一PMySQL数据库引擎会在找C条数据后停止搜烦Q而不是l往后查下一条符合记录的数据?/span>
下面的示例,只是Z找一下是否有“中国”的用P很明显,后面的会比前面的更有效率。(h意,W一条中?/span>Select *Q第二条?/span>Select 1Q?/span>
01 // 没有效率的:
02 $r = mysql_query("SELECT * FROM user WHERE country = 'China'");
03 if (mysql_num_rows($r) > 0) {
04 // ...
05 }
06
07 // 有效率的Q?/span>
08 $r = mysql_query("SELECT 1 FROM user WHERE country = 'China' LIMIT 1");
09 if (mysql_num_rows($r) > 0) {
10 // ...
11 }
3. 千万不要 ORDER BY RAND()
xp回的数据行?随机挑一个数据?真不知道谁发明了q种用法Q但很多新手很喜Ƣ这L。但你确不了解这样做有多么可怕的性能问题?/span>
如果你真的想把返回的数据行打׃Q你?/span>NU方法可以达到这个目的。这样用只让你的数据库的性能呈指数的下降。这里的问题是:MySQL会不得不L?/span>RAND()函数Q很?/span>CPU旉Q,而且q是Z每一行记录去记行Q然后再对其排序。就是你用?/span>Limit 1也无于事(因ؓ要排序)
下面的示例是随机挑一条记?/span>
1 // 千万不要q样做:
2 $r = mysql_query("SELECT username FROM user ORDER BY RAND() LIMIT 1");
3
4 // q要会更好:
5 $r = mysql_query("SELECT count(*) FROM user");
6 $d = mysql_fetch_row($r);
7 $rand = mt_rand(0,$d[0] - 1);
8
9 $r = mysql_query("SELECT username FROM user LIMIT $rand, 1");
4. 避免 SELECT *
从数据库里读多的数据Q那么查询就会变得越慢。ƈ且,如果你的数据库服务器?/span>WEB服务器是两台独立的服务器的话Q这q会增加|络传输的负载?/span>
所以,你应该养成一个需要什么就取什么的好的习惯?/span>
1 // 不推?/span>
2 $r = mysql_query("SELECT * FROM user WHERE user_id = 1");
3 $d = mysql_fetch_assoc($r);
4 echo "Welcome {$d['username']}";
5
6 // 推荐
7 $r = mysql_query("SELECT username FROM user WHERE user_id = 1");
8 $d = mysql_fetch_assoc($r);
9 echo "Welcome {$d['username']}";
5. 永远为每张表讄一个ID
我们应该为数据库里的每张表都讄一?/span>ID做ؓ其主键,而且最好的是一?/span>INT型的Q推荐?/span>UNSIGNEDQ,q设|上自动增加?/span>AUTO_INCREMENT标志?/span>
q是你 users 表有一个主键叫 “email”的字D,你也别让它成Z键。?/span> VARCHAR cd来当主键会用得性能下降。另外,在你的程序中Q你应该使用表的ID来构造你的数据结构?/span>
而且Q在MySQL数据引擎下,q有一些操作需要用主键,在这些情况下Q主键的性能和设|变得非帔R要,比如Q集,分区……
在这里,只有一个情冉|例外Q那是“兌?#8221;?#8220;外键”Q也是_q个表的主键Q通过若干个别的表的主键构成。我们把q个情况叫做“外键”。比如:有一?#8220;学生?#8221;有学生的IDQ有一?#8220;评?#8221;有课E?/span>IDQ那么,“成W?#8221;是“兌?#8221;了,其关联了学生表和评表,在成l表中,学生ID和课E?/span>ID?#8220;外键”其共同组成主键?/span>
6. 使用 ENUM 而不?VARCHAR
ENUM cd是非常快和紧凑的。在实际上,其保存的?/span> TINYINTQ但其外表上昄为字W串。这样一来,用这个字D|做一些选项列表变得相当的完?/span>
如果你有一个字D,比如“性别”Q?#8220;国家”Q?#8220;民族”Q?#8220;状?#8221;?#8220;部门”Q你知道q些字段的取值是有限而且固定的,那么Q你应该使用 ENUM 而不?/span> VARCHAR?/span>
MySQL也有一?#8220;”Q见W十条)告诉你怎么去重新组l你的表l构。当你有一?/span> VARCHAR 字段Ӟq个会告诉你把其Ҏ ENUM cd。?/span> PROCEDURE ANALYSE() 你可以得到相关的?/span>
除非你有一个很特别的原因去使用 NULL |你应该L让你的字D保?NOT NULL。这看v来好像有点争议,请往下看?/span>
首先Q问问你自己“Empty”?#8220;NULL”有多大的区别Q如果是INTQ那是0和NULLQ?如果你觉得它们之间没有什么区别,那么你就不要使用NULL。(你知道吗Q在 Oracle 里,NULL ?Empty 的字W串是一LQ?
不要以ؓ NULL 不需要空_光要额外的I间Qƈ且,在你q行比较的时候,你的E序会更复杂。当Ӟq里q不是说你就不能使用NULL了,现实情况是很复杂的,依然会有些情况下Q你需要用NULL倹{?/span>
很多E序员都会创Z?VARCHAR(15) 字段来存攑֭W串形式的IP而不是整形的IP。如果你用整形来存放Q只需?个字节,q且你可以有定长的字Dc而且Q这会ؓ你带来查询上的优势,其是当你需要用这LWHERE条gQIP between ip1 and ip2?/span>
我们必需要用UNSIGNED INTQ因?IP地址会用整?2位的无符h形?/span>
而你的查询,你可以?INET_ATON() 来把一个字W串IP转成一个整形,q?INET_NTOA() 把一个整形{成一个字W串IP
如果你需要在一个在U的|站上去执行一个大?/span> DELETE ?/span> INSERT 查询Q你需要非常小心,要避免你的操作让你的整个|站停止相应。因两个操作是会锁表的,表一锁住了,别的操作都进不来了?/span>
如果你把你的表锁上一D|_比如30U钟Q那么对于一个有很高讉K量的站点来说Q这30U所U篏的访问进E?/span>/U程Q数据库链接Q打开的文件数Q可能不仅仅会让你泊WEB服务CrashQ还可能会让你的整台服务器马上宕机?/span>
所以,如果你有一个大的处理,你定你一定把其拆分,使用 LIMIT 条g是一个好的方法。下面是一个示例:
01 while (1) {
02 //每次只做1000?/span>
03 mysql_query("DELETE FROM logs WHERE log_date <= '2009-11-01' LIMIT 1000");
04 if (mysql_affected_rows() == 0) {
05 // 没得可删了,退出!
06 break;
07 }
08 // 每次都要休息一会儿
09 usleep(50000);
10 }
对于大多数的数据库引擎来_盘操作可能是最重大的瓶颈。所以,把你的数据变得紧凑会对这U情况非常有帮助Q因减少了对盘的访问?/span>
如果一个表只会有几列Ş了(比如说字典表Q配|表Q,那么Q我们就没有理由使用 INT 来做主键Q?MEDIUMINT, SMALLINT 或是更小?TINYINT 会更l济一些?/span>
mysql> explain SELECT * FROM message ORDER BY id DESC LIMIT 10000, 20\G
***************** 1. row **************
id: 1
select_type: SIMPLE
table: message
type: index
possible_keys: NULL
key: PRIMARY
key_len: 4
ref: NULL
rows: 10020
Extra:
1 row in set (0.00 sec)
limit 10000,20的意思扫描满x件的10020行,扔掉前面?0000行,q回最后的20行,问题在q里Q如果是limit 100000,100Q需要扫?00100行,在一个高q发的应用里Q每ơ查询需要扫描超q?0W行,性能肯定大打折扣?/p>
一U?#8221;clue”的做法,l翻|供一?#8221;U烦”Q比如还是SELECT * FROM message ORDER BY id DESCQ按id降序分页Q每?0条,当前是第10,当前|目id最大的?527Q最的?500Q如果我们只提供”上一?#8221;?#8221;下一?#8221;q样的蟩转(不提供到WN늚跌{Q,那么在处?#8221;上一?#8221;的时候SQL语句可以是:
SELECT * FROM message WHERE id > 9527 ORDER BY id ASC LIMIT 20;
处理”下一?#8221;的时候SQL语句可以是:
SELECT * FROM message WHERE id < 9500 ORDER BY id DESC LIMIT 20;
不管d页Q每ơ查询只扫描20行?/p>
~点是只能提?#8221;上一?#8221;?#8221;下一?#8221;的链接Ş式,但是有些人非常喜?#8221;<上一?1 2 3 4 5 6 7 8 9 下一?gt;”q样的链接方式,怎么办呢Q?/p>
如果LIMIT m,n不可避免的话Q要优化效率Q只有尽可能的让m一下,我们扩展前面?#8221;clue”做法Q还是SELECT * FROM message ORDER BY id DESCQ按id降序分页Q每?0条,当前是第10,当前|目id最大的?527Q最的?500Q比如要跛_W?,我看的SQL语句可以q样写:
SELECT * FROM message WHERE id > 9527 ORDER BY id ASC LIMIT 20,20;
跌{到第13:
SELECT * FROM message WHERE id < 9500 ORDER BY id DESC LIMIT 40,20;
原理q是一P记录住当前页id的最大值和最|计算跌{面和当前页相对偏移Q由于页面相q,q个偏移量不会很大,q样的话m值相对较,大大减少扫描的行数。其实传l的limit m,nQ相对的偏移一直是W一,q样的话翻到后面,效率差Q而上面给出的Ҏ没有这L问题?/p>