隨筆-11  評(píng)論-0  文章-2  trackbacks-0
            2012年3月19日
          1. <%  
          2. WebApplicationContext context = (WebApplicationContext)this.getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);  
          3. TestService service = (TestService)context.getBean("testService");  
          4. %> 
          posted @ 2013-08-08 14:48 邦 閱讀(205) | 評(píng)論 (0)編輯 收藏

          一、模版修改

          在導(dǎo)出表時(shí),powerdesigner默認(rèn)為我們提供了很多的模版,在工具欄中選擇【Report--->Report Template】即可看到所有的默認(rèn)模版。如圖一:

          圖一 模版列表

          這里我們?yōu)榱藢?dǎo)出powerdesigner中創(chuàng)建的表,在工具欄中選擇【Report--->Reports】(快捷鍵Ctrl+E),然后創(chuàng)建一個(gè)New Report,如下圖二所以,選擇Standard Physical Report,這里選擇的標(biāo)準(zhǔn)的模版,點(diǎn)擊OK確定。

          圖二 創(chuàng)建新的Report

          從工具欄【Report--->Print Preview】或者點(diǎn)擊圖標(biāo)同樣可以預(yù)覽導(dǎo)出到word的效果了。效果如圖三所示:

          圖三 導(dǎo)出到word中預(yù)覽效果

          從【圖三】中的工具欄里面HTM和RTF兩種導(dǎo)出格式。如果導(dǎo)出到word選擇RTF格式即可,但是我們從【圖三】中看出紅色標(biāo)出的部分,1 是word的頁(yè)眉,同樣還有頁(yè)腳信息 ,2 是一些列的屬性清單。

                                            

          圖四 設(shè)置頁(yè)眉、頁(yè)腳

          在【圖四】中,選擇Header/Footer后,刪掉Header里面的%MODULE% %MODELNAME%,刪掉Footer里面的%APPNAME% %DATE% 頁(yè)數(shù) %PAGE%,User_defined footer就會(huì)自動(dòng)勾上,這樣就去掉了頁(yè)眉、頁(yè)腳了

           

          還有其他的比如表前面的自增序號(hào),第一頁(yè)中的創(chuàng)建者、版本、日期信息也不需要,我們可以進(jìn)行配置去掉,如下【圖五】【圖六】

                                          

                                                        圖四 

           

                                                        圖五 Properties配置

          在圖五中,在默認(rèn)配置中(General)勾上No paragraph numbering即可取消表前面的自增序號(hào),在Title Page中選擇 No Title Page就不會(huì)生成第一頁(yè)中關(guān)于創(chuàng)建者、版本、日期等信息。

          在【圖三】中,預(yù)覽看到的內(nèi)容太多,就必須刪除一些我們不需要的內(nèi)容,經(jīng)過(guò)刪減之后,如下【圖六】所示

          圖六 

          在【圖六】中右鍵單擊【List of Table Columns - 表<%PARENT%>列說(shuō)明】,從菜單中選擇 Edit Title...,就可以編輯成現(xiàn)在我們已看到的。然后,在右鍵菜單中選擇Layout...,選擇我們所需要顯示的內(nèi)容,Code表示列名稱,一般用英文單詞或拼音字母表示,Name一般用中文描述,Data Type 表示數(shù)據(jù)類型,Comment表示字段備注或字段說(shuō)明等。

          到此基本上已經(jīng)完成了powerdesigner模版的修改

          二、導(dǎo)出表

          然后點(diǎn)擊[Report---->Generate RTF]導(dǎo)出到word中,最后我們看看導(dǎo)出到word的效果,如下圖:

          圖七 導(dǎo)出到word效果

          三、保存模版

                通過(guò)上文,我們完成了自己所需的模版,然后就保存,以后可以直接使用即可,在工具欄中[Report--->Create Template From Section],然后Ctrl+S就會(huì)要求保存,取名保存即可。

          posted @ 2012-09-24 18:12 邦 閱讀(586) | 評(píng)論 (0)編輯 收藏
           /Files/bang/Maven3應(yīng)用入門講座.pptx
          posted @ 2012-08-22 10:31 邦 閱讀(264) | 評(píng)論 (0)編輯 收藏
          用jTDS通過(guò)JDBC連:
          <dependency>
          <groupId>net.sourceforge.jtds</groupId>
          <artifactId>jtds</artifactId>
          <version>1.2.4</version>
          </dependency>

          public static List<String> executeQuery(String sql,String columns) {

                  try {
                      Connection conn = getConnection();
                      Statement st = conn.createStatement();
                      ResultSet set = st.executeQuery(sql);
                      List<String> result = new ArrayList<String>();
                      while (set.next()) {
                          String[] columnList = columns.split(",");
                          for(String str:columnList){
                              result.add(set.getString(str));
                          }
                         
                      }
                      set.close();
                      st.close();
                      conn.close();
                      return result;
                  } catch (SQLException e) {
                      throw new IllegalArgumentException(e);
                  }
              }

              public static Connection getConnection() {
                  try {
                      Class.forName("net.sourceforge.jtds.jdbc.Driver");
                      String url = "jdbc:jtds:sqlserver://localhost:1433;DatabaseName=jdl";
                      String username = "sa";
                      String password = "";
                      Connection conn = DriverManager.getConnection(url, username,
                      password);
                      return conn;
                  } catch (Exception e) {
                      throw new IllegalArgumentException(e);
                  }
              }

          posted @ 2012-08-02 15:55 邦 閱讀(5154) | 評(píng)論 (0)編輯 收藏
          在js中的url進(jìn)行encodeURIComponent編碼:dd_ddtj_sub.jsp?shrxm="+encodeURIComponent(shrxm1)+"&lxdh="+encodeURIComponent(lxdh1)
          后臺(tái)service進(jìn)行encode編碼和decode解碼:shrxm= java.net.URLEncoder.encode(shrxm, "UTF-8");
            shrxm= java.net.URLDecoder.decode(shrxm,"UTF-8");
          posted @ 2012-07-11 17:01 邦 閱讀(278) | 評(píng)論 (0)編輯 收藏

          1)、下載MongoDB
          http://downloads.mongodb.org/win32/mongodb-win32-i386-2.0.4.zip

          2)、設(shè)置MongoDB目錄

          將其解壓到 d:\,再重命名為mongodb,路徑為d:\mongodb

          3)、設(shè)置數(shù)據(jù)文件路徑

          d:盤建一個(gè)data文件夾,在data文件夾中新建db文件夾,路徑d:\data\db

          4)、啟動(dòng)MongoDB服務(wù)

          進(jìn)入 cmd 提示符控制臺(tái),
          D:\mongodb\bin\mongod.exe --dbpath=d:\data\db

          <!--[if !supportLists]-->1.  <!--[endif]-->Mon Apr 16 08:50:54
          <!--[if !supportLists]-->2.  <!--[endif]-->Mon Apr 16 08:50:54 warning: 32-bit servers don't have journaling enabled by def
          <!--[if !supportLists]-->3.  <!--[endif]-->ault. Please use --journal if you want durability.
          <!--[if !supportLists]-->4.  <!--[endif]-->Mon Apr 16 08:50:54
          <!--[if !supportLists]-->5.  <!--[endif]-->Mon Apr 16 08:50:54 [initandlisten] MongoDB starting : pid=5084 port=27017 dbpat
          <!--[if !supportLists]-->6.  <!--[endif]-->h=d:\data\db 32-bit host=PC-201012302214
          <!--[if !supportLists]-->7.  <!--[endif]-->Mon Apr 16 08:50:54 [initandlisten]
          <!--[if !supportLists]-->8.  <!--[endif]-->Mon Apr 16 08:50:54 [initandlisten] ** NOTE: when using MongoDB 32 bit, you are
          <!--[if !supportLists]-->9.  <!--[endif]-->limited to about 2 gigabytes of data
          <!--[if !supportLists]-->10. <!--[endif]-->Mon Apr 16 08:50:54 [initandlisten] **       see http://blog.mongodb.org/post/13
          <!--[if !supportLists]-->11. <!--[endif]-->7788967/32-bit-limitations
          <!--[if !supportLists]-->12. <!--[endif]-->Mon Apr 16 08:50:54 [initandlisten] **       with --journal, the limit is lower
          <!--[if !supportLists]-->13. <!--[endif]-->Mon Apr 16 08:50:54 [initandlisten]
          <!--[if !supportLists]-->14. <!--[endif]-->Mon Apr 16 08:50:54 [initandlisten] db version v2.0.4, pdfile version 4.5
          <!--[if !supportLists]-->15. <!--[endif]-->Mon Apr 16 08:50:54 [initandlisten] git version: 329f3c47fe8136c03392c8f0e548506
          <!--[if !supportLists]-->16. <!--[endif]-->cb21f8ebf
          <!--[if !supportLists]-->17. <!--[endif]-->Mon Apr 16 08:50:54 [initandlisten] build info: windows sys.getwindowsversion(ma
          <!--[if !supportLists]-->18. <!--[endif]-->jor=6, minor=0, build=6002, platform=2, service_pack='Service Pack 2') BOOST_LIB
          <!--[if !supportLists]-->19. <!--[endif]-->_VERSION=1_42
          <!--[if !supportLists]-->20. <!--[endif]-->Mon Apr 16 08:50:54 [initandlisten] options: { dbpath: "d:\data\db" }
          <!--[if !supportLists]-->21. <!--[endif]-->Mon Apr 16 08:50:54 [websvr] admin web console waiting for connections on port 2
          <!--[if !supportLists]-->22. <!--[endif]-->8017
          <!--[if !supportLists]-->23. <!--[endif]-->Mon Apr 16 08:50:54 [initandlisten] waiting for connections on port 27017

          MongoDB服務(wù)端的默認(rèn)連接端口:27017

          5)、將MongoDB作為 Windows 服務(wù)隨機(jī)啟動(dòng)

          先創(chuàng)建D:\mongodb\logs\mongodb.log文件,用于存儲(chǔ)MongoDB的日志文件, 再安裝系統(tǒng)服務(wù):
                
          D:\mongodb\bin\mongod --dbpath=d:\data\db --logpath=d:\mongodb\log

          s\mongodb.log --install   
          all output going to: d:\mongodb\logs\mongodb.log  
          Creating service MongoDB.  
          Service creation successful.  
          Service can be started from the command line via 'net start "MongoDB"'.
          D:\>net start mongodb  
          Mongo DB 
          服務(wù)已經(jīng)啟動(dòng)成功。  
          D:> 
          注意:如果需要卸載服務(wù),執(zhí)行命令:sc delete MongoDB

          6)、客戶端連接驗(yàn)證

          新打開(kāi)一個(gè)CMD輸入:d:\mongodb\bin\mongo,如果出現(xiàn)下面提示,那么您就可以開(kāi)始MongoDB之旅了:

          <!--[if !supportLists]-->1.  <!--[endif]-->d:\mongodb\bin\mongo  
          <!--[if !supportLists]-->2.  <!--[endif]-->MongoDB shell version: 2.0.4  
          <!--[if !supportLists]-->3.  <!--[endif]-->connecting to: test  
          <!--[if !supportLists]-->4.  <!--[endif]-->> 

          7)、查看MongoDB日志

          查看D:\mongodb\logs\mongodb.log文件,即可對(duì)MongoDB的運(yùn)行情況進(jìn)行查看或排錯(cuò)。

          posted @ 2012-07-10 13:24 邦 閱讀(639) | 評(píng)論 (0)編輯 收藏

          方案一:

          希望實(shí)現(xiàn) 當(dāng)鼠標(biāo)離開(kāi)一個(gè)DIV的時(shí)候觸發(fā)一個(gè)事件處理函數(shù) 于是用onmouseout 結(jié)果卻發(fā)現(xiàn)它的觸發(fā)是不是也太敏感了 原因現(xiàn)在也沒(méi)有弄清楚 IE下好像是因?yàn)閰^(qū)分mouseout時(shí)的fromElement還是toElement ,IE 5.5以上的onmouseleave事件就比較好用 偏FF又不支持這個(gè)事件 只有自己想辦法手工判斷了。
          <SCRIPT>
          /***
          * 參數(shù)e 是對(duì)象傳遞的觸發(fā)事件 FF下想訪問(wèn)event對(duì)象必須傳遞event參數(shù)
          * 參數(shù)o 是目標(biāo)DIV對(duì)象
          */  
          function fun(e,o) {
                  /* FF 下判斷鼠標(biāo)是否離開(kāi)DIV */
                  if(window.navigator.userAgent.indexOf("Firefox")>=1) {
                      var x = e.clientX + document.body.scrollLeft;
                      var y = e.clientY + document.body.scrollTop ;
                      var left = o.offsetLeft;
                      var top = o.offsetTop;
                      var w = o.offsetWidth;
                      var h = o.offsetHeight;
                     
                      if(y < top || y > (h + top) || x > left + w || x<left ) {
                          alert("mouseout");
                      }
                  }

                  /* IE */
                  if(o.contains(event.toElement ) == false    )
          alert("mouseout");
                 
              }
          </SCRIPT>

          <DIV onmouseout=fun(event,this)>content</DIV>


          需要注意 在取鼠標(biāo)的值的時(shí)候 一定要加上滾動(dòng)條已經(jīng)拖動(dòng)過(guò)的內(nèi)容e.clientY + document.body.scrollTop 如果只是e.clientY得到是個(gè)錯(cuò)誤的值 當(dāng)然如果高寬都很小 是看不出來(lái)問(wèn)題。 取一個(gè)對(duì)象的高和寬 也可以使用 clientHeight clientWidth 屬性 以后遇到FF IE不兼容的時(shí)候要多看看FF的開(kāi)發(fā)手冊(cè) http://developer.mozilla.org/en/docs/DOM:element.offsetLeft

           

           

          方案二:(與一相似)

          js的onmouseout有很奇怪的一個(gè)問(wèn)題。例如

          <div onmouseout="alert(123)">

          <a href="#">test</a>

          </div>

          我們預(yù)期只有當(dāng)鼠標(biāo)從div中移開(kāi)的時(shí)候才會(huì)觸發(fā)onmouseout事件,可是,事實(shí)上,當(dāng)我們移到div中的元素時(shí),例如本例中的a標(biāo)簽時(shí),就會(huì)觸發(fā)onmousout事件。也就是說(shuō),移到對(duì)象的子對(duì)象上,也算onmouseout了。這往往會(huì)讓我們預(yù)期的效果達(dá)不到。今天的工作就遇到了這個(gè)問(wèn)題。在blueidea上搜了一下,找了解決辦法。兼容IE和FF。

           

          復(fù)制代碼
          <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
          <html xmlns="http://www.w3.org/1999/xhtml">
          <head>
          <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
          <title>阿當(dāng)制作</title>
          </head>

          <body>
          <script type="text/javascript">
          function test(obj, e) {
          if (e.currentTarget) {
          if (e.relatedTarget != obj) {
          if (obj != e.relatedTarget.parentNode) {
          alert(
          1);
          }
          }
          }
          else {
          if (e.toElement != obj) {
          if (obj != e.toElement.parentNode) {
          alert(
          1);
          }
          }
          }
          }
          </script>
          <div onmouseout="test(this, event)" style="width:100px;height:100px;border:1px #666 solid">
          <span style="margin:5px;width:100%;height:100%;border:1px #ff0000 solid">faddsf</span>
          </div>
          </body>
          </html>

          復(fù)制代碼

           

          
          

           

          今天發(fā)現(xiàn)JQ中關(guān)于這個(gè)問(wèn)題,已經(jīng)有了一個(gè)好的解決辦法了.呵呵,jquery中定義了一種事件叫做"mouseleave",用這個(gè)事件做事件句柄的話,就可以解決這個(gè)問(wèn)題了.越來(lái)越發(fā)現(xiàn)jquery是個(gè)好東西了.

           

          方案三:

          ,jQuery V1.2.2推薦用bind("mouseleave",function(){})來(lái)代替以前的mouseover方法
          用bind("mouseenter",function(){})來(lái)代替mouseout,同樣也針對(duì)以前的hover方法,要看詳細(xì)的說(shuō)明點(diǎn)這個(gè)地址:http://docs.jquery.com/Release:jQuery_1.2.2

          $(document).ready(function() {
             $("#a1").bind("mouseleave", function(){
             $('<div style="color:red;">out</div>')
             .insertAfter($(this));
          });
          });

          posted @ 2012-05-03 16:08 邦 閱讀(239) | 評(píng)論 (0)編輯 收藏

          1. 為查詢緩存優(yōu)化你的查詢

          大多數(shù)的MySQL服務(wù)器都開(kāi)啟了查詢緩存。這是提高性最有效的方法之一,而且這是被MySQL的數(shù)據(jù)庫(kù)引擎處理的。當(dāng)有很多相同的查詢被執(zhí)行了多次的時(shí)候,這些查詢結(jié)果會(huì)被放到一個(gè)緩存中,這樣,后續(xù)的相同的查詢就不用操作表而直接訪問(wèn)緩存結(jié)果了。

           

          這里最主要的問(wèn)題是,對(duì)于程序員來(lái)說(shuō),這個(gè)事情是很容易被忽略的。因?yàn)椋覀兡承┎樵冋Z(yǔ)句會(huì)讓MySQL不使用緩存。請(qǐng)看下面的示例:

          1 // 查詢緩存不開(kāi)啟

          2 $r = mysql_query("SELECT username FROM user WHERE signup_date >= CURDATE()");

          3   

          4 // 開(kāi)啟查詢緩存

          5 $today = date("Y-m-d");

          6 $r = mysql_query("SELECT username FROM user WHERE signup_date >= '$today'");

          上面兩條SQL語(yǔ)句的差別就是 CURDATE() ,MySQL的查詢緩存對(duì)這個(gè)函數(shù)不起作用。所以,像 NOW() RAND() 或是其它的諸如此類的SQL函數(shù)都不會(huì)開(kāi)啟查詢緩存,因?yàn)檫@些函數(shù)的返回是會(huì)不定的易變的。所以,你所需要的就是用一個(gè)變量來(lái)代替MySQL的函數(shù),從而開(kāi)啟緩存。

          2. 當(dāng)只要一行數(shù)據(jù)時(shí)使用 LIMIT 1

          當(dāng)你查詢表的有些時(shí)候,你已經(jīng)知道結(jié)果只會(huì)有一條結(jié)果,但因?yàn)槟憧赡苄枰?/span>fetch游標(biāo),或是你也許會(huì)去檢查返回的記錄數(shù)。

           

          在這種情況下,加上 LIMIT 1 可以增加性能。這樣一樣,MySQL數(shù)據(jù)庫(kù)引擎會(huì)在找到一條數(shù)據(jù)后停止搜索,而不是繼續(xù)往后查少下一條符合記錄的數(shù)據(jù)。

           

          下面的示例,只是為了找一下是否有“中國(guó)”的用戶,很明顯,后面的會(huì)比前面的更有效率。(請(qǐng)注意,第一條中是Select *,第二條是Select 1

          01 // 沒(méi)有效率的:

          02 $r = mysql_query("SELECT * FROM user WHERE country = 'China'");

          03 if (mysql_num_rows($r) > 0) {

          04     // ...

          05 }

          06   

          07 // 有效率的:

          08 $r = mysql_query("SELECT 1 FROM user WHERE country = 'China' LIMIT 1");

          09 if (mysql_num_rows($r) > 0) {

          10     // ...

          11 }

          3. 千萬(wàn)不要 ORDER BY RAND()

          想打亂返回的數(shù)據(jù)行?隨機(jī)挑一個(gè)數(shù)據(jù)?真不知道誰(shuí)發(fā)明了這種用法,但很多新手很喜歡這樣用。但你確不了解這樣做有多么可怕的性能問(wèn)題。

           

          如果你真的想把返回的數(shù)據(jù)行打亂了,你有N種方法可以達(dá)到這個(gè)目的。這樣使用只讓你的數(shù)據(jù)庫(kù)的性能呈指數(shù)級(jí)的下降。這里的問(wèn)題是:MySQL會(huì)不得不去執(zhí)行RAND()函數(shù)(很耗CPU時(shí)間),而且這是為了每一行記錄去記行,然后再對(duì)其排序。就算是你用了Limit 1也無(wú)濟(jì)于事(因?yàn)橐判颍?/span>

           

          下面的示例是隨機(jī)挑一條記錄

          1 // 千萬(wàn)不要這樣做:

          2 $r = mysql_query("SELECT username FROM user ORDER BY RAND() LIMIT 1");

          3   

          4 // 這要會(huì)更好:

          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 *

          從數(shù)據(jù)庫(kù)里讀出越多的數(shù)據(jù),那么查詢就會(huì)變得越慢。并且,如果你的數(shù)據(jù)庫(kù)服務(wù)器和WEB服務(wù)器是兩臺(tái)獨(dú)立的服務(wù)器的話,這還會(huì)增加網(wǎng)絡(luò)傳輸?shù)呢?fù)載。

           

          所以,你應(yīng)該養(yǎng)成一個(gè)需要什么就取什么的好的習(xí)慣。

          1 // 不推薦

          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. 永遠(yuǎn)為每張表設(shè)置一個(gè)ID

          我們應(yīng)該為數(shù)據(jù)庫(kù)里的每張表都設(shè)置一個(gè)ID做為其主鍵,而且最好的是一個(gè)INT型的(推薦使用UNSIGNED),并設(shè)置上自動(dòng)增加的AUTO_INCREMENT標(biāo)志。

           

          就算是你 users 表有一個(gè)主鍵叫 email”的字段,你也別讓它成為主鍵。使用 VARCHAR 類型來(lái)當(dāng)主鍵會(huì)使用得性能下降。另外,在你的程序中,你應(yīng)該使用表的ID來(lái)構(gòu)造你的數(shù)據(jù)結(jié)構(gòu)。

           

          而且,在MySQL數(shù)據(jù)引擎下,還有一些操作需要使用主鍵,在這些情況下,主鍵的性能和設(shè)置變得非常重要,比如,集群,分區(qū)……

           

          在這里,只有一個(gè)情況是例外,那就是“關(guān)聯(lián)表”的“外鍵”,也就是說(shuō),這個(gè)表的主鍵,通過(guò)若干個(gè)別的表的主鍵構(gòu)成。我們把這個(gè)情況叫做“外鍵”。比如:有一個(gè)“學(xué)生表”有學(xué)生的ID,有一個(gè)“課程表”有課程ID,那么,“成績(jī)表”就是“關(guān)聯(lián)表”了,其關(guān)聯(lián)了學(xué)生表和課程表,在成績(jī)表中,學(xué)生ID和課程ID叫“外鍵”其共同組成主鍵。

           

          6. 使用 ENUM 而不是 VARCHAR

          ENUM 類型是非??旌途o湊的。在實(shí)際上,其保存的是 TINYINT,但其外表上顯示為字符串。這樣一來(lái),用這個(gè)字段來(lái)做一些選項(xiàng)列表變得相當(dāng)?shù)耐昝馈?/span>

           

          如果你有一個(gè)字段,比如“性別”,“國(guó)家”,“民族”,“狀態(tài)”或“部門”,你知道這些字段的取值是有限而且固定的,那么,你應(yīng)該使用 ENUM 而不是 VARCHAR。

           

          MySQL也有一個(gè)“建議”(見(jiàn)第十條)告訴你怎么去重新組織你的表結(jié)構(gòu)。當(dāng)你有一個(gè) VARCHAR 字段時(shí),這個(gè)建議會(huì)告訴你把其改成 ENUM 類型。使用 PROCEDURE ANALYSE() 你可以得到相關(guān)的建議。

          7. 盡可能的使用 NOT NULL

          除非你有一個(gè)很特別的原因去使用 NULL 值,你應(yīng)該總是讓你的字段保持 NOT NULL。這看起來(lái)好像有點(diǎn)爭(zhēng)議,請(qǐng)往下看。

          首先,問(wèn)問(wèn)你自己“Empty”和“NULL”有多大的區(qū)別(如果是INT,那就是0和NULL)?如果你覺(jué)得它們之間沒(méi)有什么區(qū)別,那么你就不要使用NULL。(你知道嗎?在 Oracle 里,NULL 和 Empty 的字符串是一樣的!)

          不要以為 NULL 不需要空間,其需要額外的空間,并且,在你進(jìn)行比較的時(shí)候,你的程序會(huì)更復(fù)雜。當(dāng)然,這里并不是說(shuō)你就不能使用NULL了,現(xiàn)實(shí)情況是很復(fù)雜的,依然會(huì)有些情況下,你需要使用NULL值。

          8. 把IP地址存成 UNSIGNED INT

          很多程序員都會(huì)創(chuàng)建一個(gè) VARCHAR(15) 字段來(lái)存放字符串形式的IP而不是整形的IP。如果你用整形來(lái)存放,只需要4個(gè)字節(jié),并且你可以有定長(zhǎng)的字段。而且,這會(huì)為你帶來(lái)查詢上的優(yōu)勢(shì),尤其是當(dāng)你需要使用這樣的WHERE條件:IP between ip1 and ip2。

          我們必需要使用UNSIGNED INT,因?yàn)?IP地址會(huì)使用整個(gè)32位的無(wú)符號(hào)整形。

          而你的查詢,你可以使用 INET_ATON() 來(lái)把一個(gè)字符串IP轉(zhuǎn)成一個(gè)整形,并使用 INET_NTOA() 把一個(gè)整形轉(zhuǎn)成一個(gè)字符串IP

          9. 拆分大的 DELETE 或 INSERT 語(yǔ)句

          如果你需要在一個(gè)在線的網(wǎng)站上去執(zhí)行一個(gè)大的 DELETE INSERT 查詢,你需要非常小心,要避免你的操作讓你的整個(gè)網(wǎng)站停止相應(yīng)。因?yàn)檫@兩個(gè)操作是會(huì)鎖表的,表一鎖住了,別的操作都進(jìn)不來(lái)了。

          如果你把你的表鎖上一段時(shí)間,比如30秒鐘,那么對(duì)于一個(gè)有很高訪問(wèn)量的站點(diǎn)來(lái)說(shuō),這30秒所積累的訪問(wèn)進(jìn)程/線程,數(shù)據(jù)庫(kù)鏈接,打開(kāi)的文件數(shù),可能不僅僅會(huì)讓你泊WEB服務(wù)Crash,還可能會(huì)讓你的整臺(tái)服務(wù)器馬上宕機(jī)。

           

          所以,如果你有一個(gè)大的處理,你定你一定把其拆分,使用 LIMIT 條件是一個(gè)好的方法。下面是一個(gè)示例:

          01 while (1) {

          02     //每次只做1000

          03     mysql_query("DELETE FROM logs WHERE log_date <= '2009-11-01' LIMIT 1000");

          04     if (mysql_affected_rows() == 0) {

          05         // 沒(méi)得可刪了,退出!

          06         break;

          07     }

          08     // 每次都要休息一會(huì)兒

          09     usleep(50000);

          10 }

          10. 越小的列會(huì)越快

          對(duì)于大多數(shù)的數(shù)據(jù)庫(kù)引擎來(lái)說(shuō),硬盤操作可能是最重大的瓶頸。所以,把你的數(shù)據(jù)變得緊湊會(huì)對(duì)這種情況非常有幫助,因?yàn)檫@減少了對(duì)硬盤的訪問(wèn)。

          如果一個(gè)表只會(huì)有幾列罷了(比如說(shuō)字典表,配置表),那么,我們就沒(méi)有理由使用 INT 來(lái)做主鍵,使用 MEDIUMINT, SMALLINT 或是更小的 TINYINT 會(huì)更經(jīng)濟(jì)一些。

           

          posted @ 2012-03-19 14:50 邦 閱讀(506) | 評(píng)論 (0)編輯 收藏

          首先看一下分頁(yè)的基本原理:

          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的意思掃描滿足條件的10020行,扔掉前面的10000行,返回最后的20行,問(wèn)題就在這里,如果是limit 100000,100,需要掃描100100行,在一個(gè)高并發(fā)的應(yīng)用里,每次查詢需要掃描超過(guò)10W行,性能肯定大打折扣。

          一種”clue”的做法,給翻頁(yè)提供一些”線索”,比如還是SELECT * FROM message ORDER BY id DESC,按id降序分頁(yè),每頁(yè)20條,當(dāng)前是第10頁(yè),當(dāng)前頁(yè)條目id最大的是9527,最小的是9500,如果我們只提供”上一頁(yè)”、”下一頁(yè)”這樣的跳轉(zhuǎn)(不提供到第N頁(yè)的跳轉(zhuǎn)),那么在處理”上一頁(yè)”的時(shí)候SQL語(yǔ)句可以是:

          SELECT * FROM message WHERE id > 9527 ORDER BY id ASC LIMIT 20;

          處理”下一頁(yè)”的時(shí)候SQL語(yǔ)句可以是:

          SELECT * FROM message WHERE id < 9500 ORDER BY id DESC LIMIT 20;

          不管翻多少頁(yè),每次查詢只掃描20行。

          缺點(diǎn)是只能提供”上一頁(yè)”、”下一頁(yè)”的鏈接形式,但是有些人非常喜歡”<上一頁(yè) 1 2 3 4 5 6 7 8 9 下一頁(yè)>”這樣的鏈接方式,怎么辦呢?

          如果LIMIT m,n不可避免的話,要優(yōu)化效率,只有盡可能的讓m小一下,我們擴(kuò)展前面的”clue”做法,還是SELECT * FROM message ORDER BY id DESC,按id降序分頁(yè),每頁(yè)20條,當(dāng)前是第10頁(yè),當(dāng)前頁(yè)條目id最大的是9527,最小的是9500,比如要跳到第8頁(yè),我看的SQL語(yǔ)句可以這樣寫:

          SELECT * FROM message WHERE id > 9527 ORDER BY id ASC LIMIT 20,20;

          跳轉(zhuǎn)到第13頁(yè):

          SELECT * FROM message WHERE id < 9500 ORDER BY id DESC LIMIT 40,20;

          原理還是一樣,記錄住當(dāng)前頁(yè)id的最大值和最小值,計(jì)算跳轉(zhuǎn)頁(yè)面和當(dāng)前頁(yè)相對(duì)偏移,由于頁(yè)面相近,這個(gè)偏移量不會(huì)很大,這樣的話m值相對(duì)較小,大大減少掃描的行數(shù)。其實(shí)傳統(tǒng)的limit m,n,相對(duì)的偏移一直是第一頁(yè),這樣的話越翻到后面,效率越差,而上面給出的方法就沒(méi)有這樣的問(wèn)題。

           

          posted @ 2012-03-19 14:46 邦 閱讀(857) | 評(píng)論 (0)編輯 收藏
          主站蜘蛛池模板: 灵武市| 佛山市| 五寨县| 淮安市| 太湖县| 崇州市| 吴旗县| 从化市| 乌审旗| 鹿邑县| 新和县| 辉县市| 巩留县| 江都市| 侯马市| 大名县| 湟源县| 镇坪县| 文水县| 墨竹工卡县| 酉阳| 广灵县| 河源市| 清水河县| 孟村| 三门峡市| 青冈县| 浦北县| 清河县| 威海市| 苏州市| 本溪| 扎鲁特旗| 章丘市| 灵山县| 甘肃省| 彰化市| 永修县| 永嘉县| 哈尔滨市| 长丰县|