乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      sql在不同數(shù)據(jù)庫(kù)查詢(xún)前幾條數(shù)據(jù)的方法

       麗和書(shū)屋 2015-04-22

      轉(zhuǎn)自:http://blog.sina.com.cn/s/blog_7ffe577301012pnj.html

      sql在不同數(shù)據(jù)庫(kù)查詢(xún)前幾條數(shù)據(jù)


      1. ORACLE 

      SELECT * FROM TABLE1 WHEREROWNUM<=N 
        HQL: from table1 t order by t.createTime descwhere rownum<=n 
      2. INFORMIX 
         SELECT FIRST N * FROMTABLE1 
      3. DB2 
      SELECT * ROW_NUMBER() OVER(ORDER BY COL1 DESC) AS ROWNUM WHEREROWNUM<=N 
      或者 
      SELECT COLUMN FROM TABLE FETCH FIRST N ROWS ONLY 
      4. SQL SERVER 
      SELECT TOP N * FROM TABLE1 
      5. SYBASE 
      SET ROWCOUNT N 
      GO 
      SELECT * FROM TABLE1 
      6. MYSQL 
      SELECT * FROM TABLE1 LIMIT N 
      hibernate查詢(xún)記錄的前10條記錄 
      就像mysql的SQL語(yǔ)句的"select * from table limit 10" hql不支持limit 
      query.setFirstResult(0);//從第0條開(kāi)始取 
      query.setMaxResults(10);//取十條記錄 
      7. FOXPRO 
      SELECT * TOP N FROM TABLE ORDER BY COLUMN 
      8.postgres
      SELECT * FROM TABLE LIMIT 
      跟我學(xué)SQL分為三部分,其中涵蓋了有關(guān)SQL標(biāo)準(zhǔn)的基本知識(shí)。在上一篇文章里我們討論了一些數(shù)據(jù)庫(kù)術(shù)語(yǔ)和4種最基本的數(shù)據(jù)查詢(xún)類(lèi)型。此外,我們還解釋了WHERE子句和條件語(yǔ)句的用法,同時(shí)我們提供了各類(lèi)查詢(xún)的具體示例。
      在這篇文章里,我們將就其他一些SQL函數(shù)和子句進(jìn)行闡述,供你用于基本的SELECT數(shù)據(jù)查詢(xún)中。
      SELECT選項(xiàng)精制結(jié)果
      正如我們從上一篇文章中所讀到的那樣,SELECT語(yǔ)句具有種類(lèi)繁多的各類(lèi)選項(xiàng),這些選項(xiàng)可以用來(lái)控制數(shù)據(jù)返回的方式。這些選項(xiàng)以子句、關(guān)鍵詞和函數(shù)的形式存在。
      子句是一種修改結(jié)果的語(yǔ)句。子句不是必要的語(yǔ)句但它對(duì)數(shù)據(jù)的內(nèi)容及其顯示進(jìn)行了提煉。WHERE子句就是這樣的子句。
      關(guān)鍵詞觸發(fā)數(shù)據(jù)庫(kù)的內(nèi)在功能。這些關(guān)鍵詞在有時(shí)甚至是查詢(xún)所必需的。例如“INSERT INTO table_name (column1)VALUES(‘data1’);”語(yǔ)句中的INTO和VALUE就是如此。我們將了解DISTINCT關(guān)鍵詞,它能觸發(fā)一些非常有用的可選功能。
      下面總結(jié)了一些最常用的子句、關(guān)鍵詞和函數(shù)。然后我會(huì)對(duì)每一部分舉例說(shuō)明。
      ·ORDER BY – 按照指定列排序返回結(jié)果的子句
      ·DISTINCT – 只返回結(jié)果集合內(nèi)唯一行的關(guān)鍵詞 
      ·COUNT -- 返回匹配查詢(xún)的數(shù)據(jù)行總數(shù)數(shù)值的函數(shù) 
      ·AVG – 該函數(shù)返回指定列的平均值
      ·SUM –該函數(shù)把指定的列中的數(shù)字加起來(lái)
      ·MIN – 該函數(shù)返回列中最小的非NULL值
      ·MAX –該函數(shù)返回列中的最大值
      ·GROUP BY – 按列匯集查詢(xún)函數(shù)結(jié)果的子句
      用ORDER BY對(duì)查詢(xún)結(jié)果排序
      ORDER BY子句讓數(shù)據(jù)庫(kù)對(duì)查詢(xún)結(jié)果排序,這樣你就無(wú)須自己編寫(xiě)應(yīng)用程序進(jìn)行“手工”排序了。ORDERBY子句必須放在查詢(xún)語(yǔ)句的結(jié)尾。其基本用法如下:
      SELECT * FROM Contacts ORDER BY first_name;
      你可以隨意在任何選擇語(yǔ)句中使用ORDER BY 子句返回多列結(jié)果。你還可以用它連接其他子句:
      SELECT first_name, last_name FROM Contacts WHERE first_name BETWEEN‘a(chǎn)’ AND ‘k’ ORDER BY last_name;
      你可以對(duì)多列數(shù)據(jù)排序。優(yōu)先順序按從左到右依次降低,所以查詢(xún)語(yǔ)句中各列的排列順序很重要。
      SELECT * FROM Contacts ORDER BY company, last_name,first_name;
      查詢(xún)結(jié)果默認(rèn)按數(shù)字或者字母的升序排序。你可以在ORDER BY子句后面加上DESC關(guān)鍵詞改成降序排列。在下面的例子中,最高的net_amount排在最先(降序)。假如兩行或者兩行以上數(shù)據(jù)都包含了同樣的net_amount值,那么同行中l(wèi)ast_name值在字母表中最先出現(xiàn)的排先,因?yàn)閘ast_name一列還是按照升序排序的。
      SELECT * FROM Sales ORDER BY net_amount DESC, last_name,first_name;
      在按照定義的列名排序以后,大多數(shù)數(shù)據(jù)庫(kù)隨后將按照數(shù)據(jù)表內(nèi)的第一列排序然后順序向右再排序。具體的實(shí)現(xiàn)各有變化,因此,如果排序在應(yīng)用中比較重要那么你應(yīng)該明確地定義所要排序的列。
      另外一值得注意的問(wèn)題是,采用ORDERBY子句(以及WHERE子句),你正在用來(lái)排序結(jié)果的數(shù)據(jù)列并不一定得是返回結(jié)果集合的一部分。只要所有引用的列都在數(shù)據(jù)表內(nèi)存在則下例完全有效:
      SELECT company, first_name, net_amount FROM Sales ORDER BYstart_date, last_name;
      DISTINCT返回不重復(fù)結(jié)果
      DISTINCT關(guān)鍵詞只返回結(jié)果集合內(nèi)不重復(fù)的數(shù)據(jù)行。例如,有時(shí)你可能需要找出Sales表內(nèi)的公司,但是你又不想看見(jiàn)每個(gè)條目。于是你可以用DISTINCT對(duì)應(yīng)每一公司名返回一行數(shù)據(jù):
      SELECT DISTINCT company FROM Sales;
      在使用DISTINCT時(shí),它適用于所有的請(qǐng)求列。如果你打算列出表內(nèi)的所有銷(xiāo)售人員和他們所代表的公司而非每一銷(xiāo)售記錄,那么你可以使用下列語(yǔ)句。注意,這樣操作還可能返回同一公司的若干條目等等。
      SELECT DISTINCT company, last_name, first_name FROMSales;
      你還可以在對(duì)結(jié)果縮小范圍和進(jìn)行排序時(shí)結(jié)合SELECT語(yǔ)句使用DISTINCT。為了確定顯示的內(nèi)容,數(shù)據(jù)庫(kù)首先會(huì)證實(shí)精練的請(qǐng)求是否匹配數(shù)據(jù)行,然后應(yīng)用DISTINCT功能。在全部結(jié)果集合都得以確定之后即處理ORDERBY子句。如下例所示,只有net_amount大于100的數(shù)據(jù)行才被返回。由于DISTINCT保留遇見(jiàn)的第1個(gè)匹配查詢(xún)條件的數(shù)據(jù)行而丟棄其他匹配行,所以O(shè)RDER BY語(yǔ)句所引用的net_amount看起來(lái)就好象產(chǎn)生了隨機(jī)的結(jié)果。
      SELECT DISTINCT company, last_name, first_name FROM Sales WHEREnet_amount > 100 ORDER BY company,net_amount;
      函數(shù)應(yīng)用邏輯
      返回單一值的函數(shù)稱(chēng)做聚集函數(shù)(aggregatefunction)。通過(guò)應(yīng)用程序訪問(wèn)下列聚集函數(shù)的結(jié)果時(shí),包含結(jié)果的“字段名”就是你所使用的實(shí)際函數(shù)。例如,在分析你的數(shù)據(jù)庫(kù)結(jié)果時(shí),結(jié)果數(shù)組的鍵值可能如下所示:
      $keyname = “COUNT(*)”;
      $resultkey = “AVG(net_amount)”;
      COUNT
      COUNT函數(shù)計(jì)算出結(jié)果集合中的數(shù)據(jù)行數(shù)。和其他函數(shù)一樣它接受一個(gè)參數(shù)。以下的基本示例能告訴你數(shù)據(jù)表內(nèi)的行數(shù):SELECTCOUNT(*) FROM Sales;
      你也可以用它來(lái)計(jì)算任何結(jié)果集合中的行數(shù)。
      SELECT COUNT(*) FROM Sales WHERE net_amount >100;
      如果你想看看某特定列有多少行包含非空值,那你不妨對(duì)該列使用COUNT函數(shù)。注意,除非數(shù)據(jù)庫(kù)設(shè)置為字段為空時(shí)缺省填充N(xiāo)ULL否則將返回表內(nèi)數(shù)據(jù)行的總數(shù)。另外,列出的列在超出一個(gè)的情況下會(huì)引起錯(cuò)誤。
      SELECT COUNT(company) FROM Sales;
       COUNT還可以用來(lái)計(jì)算DISTINCT結(jié)果集合中的行數(shù)。
      SELECT COUNT(DISTINCT company, last_name) FROM Sales;
      COUNT語(yǔ)句通常用在程序中確定FOR循環(huán)的循環(huán)次數(shù)。
      AVG
      AVG返回某列所有字段的平均值,該列必須是數(shù)字?jǐn)?shù)據(jù)類(lèi)型。該函數(shù)用列的名字作為其參數(shù),如果列字段數(shù)據(jù)類(lèi)型是非數(shù)字類(lèi)型的則函數(shù)返回“0”。SELECTAVG(net_amount) FROM Sales;
      你可以結(jié)合子句限制該函數(shù)的應(yīng)用范圍。
      SELECT AVG(net_amount) FROM Sales WHERE company LIKE ‘?CDCo%’;
      就象所有聚集函數(shù)一樣,ORDER BY語(yǔ)句將被忽略。
      SUM
      SUM的工作方式和AVG差不多,只不過(guò)該函數(shù)返回結(jié)果集合中所有字段值的和。
      SELECT SUM(net_amount) FROM Sales WHERE net_amount >100;
      AVG、SUM、MIN和MAX函數(shù)在沒(méi)有指定列的情況下都會(huì)返回錯(cuò)誤,所以你不能使用“*”通配符。
      MIN
      MIN返回指定列中最小的非空值。如果指定列是數(shù)字?jǐn)?shù)據(jù)類(lèi)型則結(jié)果將是最小的數(shù)字。如果它是一種字符串?dāng)?shù)據(jù)類(lèi)型則函數(shù)將返回按字母表順序出現(xiàn)的第1個(gè)值。SELECTMIN(net_amount) FROM Sales WHERE last_name = “Smith”;
      SELECT MIN(last_name) FROM Sales;
       MAX
      MAX的工作方式和MIN函數(shù)一樣,只不過(guò)該函數(shù)返回最大的非空值。該函數(shù)也可以用于字符串或者數(shù)字列
      SELECT MAX(net_amount) FROM Sales;
      SELECT MAX(company) FROM Sales WHERE net_amount >100;
      MAX函數(shù)有時(shí)還用在包含自動(dòng)遞增鍵字段的列上確定下一條目的鍵ID。除非你正在運(yùn)行一個(gè)非公開(kāi)的數(shù)據(jù)庫(kù),否則在使用這一信息插入下一條目時(shí)務(wù)必謹(jǐn)慎,以防其他用戶(hù)先你執(zhí)行數(shù)據(jù)操作。
      GROUP BY 令函數(shù)更有用
      雖然以上提到的所有這些函數(shù)都能提供相當(dāng)有用的信息,但是,如果有GROUPBY子句幫忙的話更能讓你在列的字段子集中應(yīng)用這些函數(shù)。不要對(duì)你的Sales表中每一家公司一次又一次地執(zhí)行MAX函數(shù)查詢(xún)——你完全可以帶GROUPBY子句獲得同樣的結(jié)果:
      SELECT company, MAX(net_amount) FROM Sales GROUP BYcompany;
      這樣做可以獲得每家公司net_amount的的最大值。在選擇多列名的時(shí)候也可以采用該語(yǔ)句,你還可以用多列來(lái)對(duì)函數(shù)結(jié)果分組。
      下面的例子演示了以上各種方式。首先,包括GROUPBY子句可以令你指定要顯示的其他列。然而,你得知道這個(gè)例子將返回在組中遇到的第1個(gè)last_name值;Sum( net_amount)將顯示全部公司的結(jié)果而不僅僅針對(duì)匹配姓氏的數(shù)據(jù)行。這是因?yàn)椋覀冎皇褂昧薈ompany字段來(lái)定義我們的組。
      SELECT company, last_name, SUM(net_amount) FROM Sales GROUP BYcompany;
      在上面的例子中,last_name列實(shí)際上并沒(méi)有提供什么有用的信息,但這樣做是為了在下一個(gè)例子中要用到的功能做準(zhǔn)備。你可以創(chuàng)建多列定義的組。這樣就可以在結(jié)果集合中產(chǎn)生針對(duì)特定行的函數(shù)結(jié)果,而結(jié)果集合則是由所有指定的GROUPBY列聯(lián)合起來(lái)創(chuàng)建的:
      SELECT company, AVG(net_amount), last_name FROM Sales GROUP BYcompany, last_name;
       上面的例子給每家公司中每一姓氏給出了平均的net_amount。你列出GROUPBY列的順序控制著結(jié)果的排序,但是實(shí)際的函數(shù)值結(jié)果是一樣的。
      下面的例子表明如何組織結(jié)果而不顯示分組的列。在有些場(chǎng)合這樣做是很有用的,例如,如果要顯示個(gè)人的銷(xiāo)售量但卻不顯示姓名就能用上下面的例子了:
      SELECT company, COUNT(sale_id) FROM Sales GROUP BY company,last_name;
      限制使用GROUP BY的查詢(xún)
      如你在以上示例中所看到的那樣,你可以結(jié)合WHERE字句利用以上的概念限制查詢(xún)的范圍。WHERE子句會(huì)首先被計(jì)算,然后執(zhí)行函數(shù)。在使用組的時(shí)候就是這樣的。
      SELECT company, AVG(net_amount), FROM Sales WHERE net_amount> 100 GROUP BY company;
      上面的例子只對(duì)那些滿(mǎn)足WHERE限制條件的數(shù)據(jù)行適用AVG函數(shù)。注意,WHERE子句必須放在GROUPBY子句之前。你還可以用HAVING語(yǔ)句對(duì)分組計(jì)算之后限制返回的結(jié)果集合。
      SELECT company, AVG(net_amount), FROM Sales WHERE last_name BETWEEN‘a(chǎn)’ AND ‘m’ GROUP BY company HAVING AVG(net_amount)> 500;
       
      上面的語(yǔ)句計(jì)算每家公司net_amount的平均值,而且只計(jì)算那些姓氏滿(mǎn)足限制條件的銷(xiāo)售人員的銷(xiāo)售量,同時(shí)只顯示大于500的結(jié)果。
      MySQL可以很好的支持大數(shù)據(jù)量的存取,但是一般說(shuō)來(lái),數(shù)據(jù)庫(kù)中的表越小,在它上面執(zhí)行的查詢(xún)也就會(huì)越快。因此,在創(chuàng)建表的時(shí)候,為了獲得更好的性能,我們可以將表中字段的寬度設(shè)得盡可能小。例如,在定義郵政編碼這個(gè)字段時(shí),如果將其設(shè)置為CHAR(255),顯然給數(shù)據(jù)庫(kù)增加了不必要的空間,甚至使用VARCHAR這種類(lèi)型也是多余的,因?yàn)镃HAR(6)就可以很好的完成任務(wù)了。同樣的,如果可以的話,我們應(yīng)該使用MEDIUMINT而不是BIGIN來(lái)定義整型字段。 
      另外一個(gè)提高效率的方法是在可能的情況下,應(yīng)該盡量把字段設(shè)置為NOTNULL,這樣在將來(lái)執(zhí)行查詢(xún)的時(shí)候,數(shù)據(jù)庫(kù)不用去比較NULL值。 
      對(duì)于某些文本字段,例如“省份”或者“性別”,我們可以將它們定義為ENUM類(lèi)型。因?yàn)樵贛ySQL中,ENUM類(lèi)型被當(dāng)作數(shù)值型數(shù)據(jù)來(lái)處理,而數(shù)值型數(shù)據(jù)被處理起來(lái)的速度要比文本類(lèi)型快得多。這樣,我們又可以提高數(shù)據(jù)庫(kù)的性能。
      2、使用連接(JOIN)來(lái)代替子查詢(xún)(Sub-Queries) 
      MySQL從4.1開(kāi)始支持SQL的子查詢(xún)。這個(gè)技術(shù)可以使用SELECT語(yǔ)句來(lái)創(chuàng)建一個(gè)單列的查詢(xún)結(jié)果,然后把這個(gè)結(jié)果作為過(guò)濾條件用在另一個(gè)查詢(xún)中。例如,我們要將客戶(hù)基本信息表中沒(méi)有任何訂單的客戶(hù)刪除掉,就可以利用子查詢(xún)先從銷(xiāo)售信息表中將所有發(fā)出訂單的客戶(hù)ID取出來(lái),然后將結(jié)果傳遞給主查詢(xún),如下所示: 
      DELETE FROM customerinfo WHERE CustomerID NOT in (SELECT CustomerIDFROM salesinfo ) 
      使用子查詢(xún)可以一次性的完成很多邏輯上需要多個(gè)步驟才能完成的SQL操作,同時(shí)也可以避免事務(wù)或者表鎖死,并且寫(xiě)起來(lái)也很容易。但是,有些情況下,子查詢(xún)可以被更有效率的連接(JOIN)..替代。例如,假設(shè)我們要將所有沒(méi)有訂單記錄的用戶(hù)取出來(lái),可以用下面這個(gè)查詢(xún)完成: 
      SELECT * FROM customerinfo WHERE CustomerID NOT in (SELECTCustomerID FROM salesinfo ) 
      如果使用連接(JOIN)..來(lái)完成這個(gè)查詢(xún)工作,速度將會(huì)快很多。尤其是當(dāng)salesinfo表中對(duì)CustomerID建有索引的話,性能將會(huì)更好,查詢(xún)?nèi)缦拢?SPAN style="FONT-FAMILY: fontello, icomoon, tmt-icons, topbar, sv, MD_Font, octicons, 'Glyphicons Halflings', FontAwesome, dashicons, iconfont, 'Segoe UI', 'WenQuanYi Micro Hei', 'WenQuanYi Micro Hei Mono', 'Microsoft Yahei', 'Microsoft Yahei Mono', ,, 微軟雅黑, sans-serif !important"> 
      SELECT * FROM customerinfo LEFT JOIN salesinfoONcustomerinfo.CustomerID=salesinfo. CustomerID WHEREsalesinfo.CustomerID IS NULL 
      連接(JOIN).. 之所以更有效率一些,是因?yàn)镸ySQL不需要在內(nèi)存中創(chuàng)建臨時(shí)表來(lái)完成這個(gè)邏輯上的需要兩個(gè)步驟的查詢(xún)工作。 
      3、使用聯(lián)合(UNION)來(lái)代替手動(dòng)創(chuàng)建的臨時(shí)表 
      MySQL 從 4.0 的版本開(kāi)始支持 UNION 查詢(xún),它可以把需要使用臨時(shí)表的兩條或更多的 SELECT查詢(xún)合并的一個(gè)查詢(xún)中。在客戶(hù)端的查詢(xún)會(huì)話結(jié)束的時(shí)候,臨時(shí)表會(huì)被自動(dòng)刪除,從而保證數(shù)據(jù)庫(kù)整齊、高效。使用 UNION來(lái)創(chuàng)建查詢(xún)的時(shí)候,我們只需要用 UNION作為關(guān)鍵字把多個(gè) SELECT 語(yǔ)句連接起來(lái)就可以了,要注意的是所有 SELECT語(yǔ)句中的字段數(shù)目要想同。下面的例子就演示了一個(gè)使用 UNION的查詢(xún)。 
      SELECT Name, Phone FROM client UNION SELECT Name, BirthDate FROMauthor 
      UNION 
      SELECT Name, Supplier FROM product 
      4、事務(wù) 
      盡管我們可以使用子查詢(xún)(Sub-Queries)、連接(JOIN)和聯(lián)合(UNION)來(lái)創(chuàng)建各種各樣的查詢(xún),但不是所有的數(shù)據(jù)庫(kù)操作都可以只用一條或少數(shù)幾條SQL語(yǔ)句就可以完成的。更多的時(shí)候是需要用到一系列的語(yǔ)句來(lái)完成某種工作。但是在這種情況下,當(dāng)這個(gè)語(yǔ)句塊中的某一條語(yǔ)句運(yùn)行出錯(cuò)的時(shí)候,整個(gè)語(yǔ)句塊的操作就會(huì)變得不確定起來(lái)。設(shè)想一下,要把某個(gè)數(shù)據(jù)同時(shí)插入兩個(gè)相關(guān)聯(lián)的表中,可能會(huì)出現(xiàn)這樣的情況:第一個(gè)表中成功更新后,數(shù)據(jù)庫(kù)突然出現(xiàn)意外狀況,造成第二個(gè)表中的操作沒(méi)有完成,這樣,就會(huì)造成數(shù)據(jù)的不完整,甚至?xí)茐臄?shù)據(jù)庫(kù)中的數(shù)據(jù)。要避免這種情況,就應(yīng)該使用事務(wù),它的作用是:要么語(yǔ)句塊中每條語(yǔ)句都操作成功,要么都失敗。換句話說(shuō),就是可以保持?jǐn)?shù)據(jù)庫(kù)中數(shù)據(jù)的一致性和完整性。事物以BEGIN關(guān)鍵字開(kāi)始,COMMIT關(guān)鍵字結(jié)束。在這之間的一條SQL操作失敗,那么,ROLLBACK命令就可以把數(shù)據(jù)庫(kù)恢復(fù)到BEGIN開(kāi)始之前的狀態(tài)。 
      BEGIN; 
      INSERT INTO salesinfo SET CustomerID=14; 
      UPDATE inventory SET Quantity=11 
      WHERE item='book'; 
      COMMIT; 
      事務(wù)的另一個(gè)重要作用是當(dāng)多個(gè)用戶(hù)同時(shí)使用相同的數(shù)據(jù)源時(shí),它可以利用鎖定數(shù)據(jù)庫(kù)的方法來(lái)為用戶(hù)提供一種安全的訪問(wèn)方式,這樣可以保證用戶(hù)的操作不被其它的用戶(hù)所干擾。 
      5、鎖定表 
      盡管事務(wù)是維護(hù)數(shù)據(jù)庫(kù)完整性的一個(gè)非常好的方法,但卻因?yàn)樗莫?dú)占性,有時(shí)會(huì)影響數(shù)據(jù)庫(kù)的性能,尤其是在很大的應(yīng)用系統(tǒng)中。由于在事務(wù)執(zhí)行的過(guò)程中,數(shù)據(jù)庫(kù)將會(huì)被鎖定,因此其它的用戶(hù)請(qǐng)求只能暫時(shí)等待直到該事務(wù)結(jié)束。如果一個(gè)數(shù)據(jù)庫(kù)系統(tǒng)只有少數(shù)幾個(gè)用戶(hù) 
      來(lái)使用,事務(wù)造成的影響不會(huì)成為一個(gè)太大的問(wèn)題;但假設(shè)有成千上萬(wàn)的用戶(hù)同時(shí)訪問(wèn)一個(gè)數(shù)據(jù)庫(kù)系統(tǒng),例如訪問(wèn)一個(gè)電子商務(wù)網(wǎng)站,就會(huì)產(chǎn)生比較嚴(yán)重的響應(yīng)延遲。 
      其實(shí),有些情況下我們可以通過(guò)鎖定表的方法來(lái)獲得更好的性能。下面的例子就用鎖定表的方法來(lái)完成前面一個(gè)例子中事務(wù)的功能。 
      LOCK TABLE inventory WRITE 
      SELECT Quantity FROM inventory 
      WHEREItem='book'; 
      ... 
      UPDATE inventory SET Quantity=11 
      WHEREItem='book'; 
      UNLOCK TABLES 
      這里,我們用一個(gè) SELECT 語(yǔ)句取出初始數(shù)據(jù),通過(guò)一些計(jì)算,用 UPDATE 語(yǔ)句將新值更新到表中。包含有 WRITE 關(guān)鍵字的LOCK TABLE 語(yǔ)句可以保證在 UNLOCK TABLES 命令被執(zhí)行之前,不會(huì)有其它的訪問(wèn)來(lái)對(duì) inventory進(jìn)行插入、更新或者刪除的操作。 
      6、使用外鍵 
      鎖定表的方法可以維護(hù)數(shù)據(jù)的完整性,但是它卻不能保證數(shù)據(jù)的關(guān)聯(lián)性。這個(gè)時(shí)候我們就可以使用外鍵。例如,外鍵可以保證每一條銷(xiāo)售記錄都指向某一個(gè)存在的客戶(hù)。在這里,外鍵可以把customerinfo表中的CustomerID映射到salesinfo表中CustomerID,任何一條沒(méi)有合法CustomerID的記錄都不會(huì)被更新或插入到salesinfo中。 
      CREATE TABLE customerinfo 
      ( 
      CustomerID INT NOT NULL , 
      PRIMARY KEY ( CustomerID ) 
      ) TYPE = INNODB; 
      CREATE TABLE salesinfo 
      ( 
      SalesID INT NOT NULL, 
      CustomerID INT NOT NULL, 
      PRIMARY KEY(CustomerID, SalesID), 
      FOREIGN KEY (CustomerID) REFERENCES customerinfo 
      (CustomerID) ON DELETECASCADE 
      ) TYPE = INNODB; 
      注意例子中的參數(shù)“ON DELETE CASCADE”。該參數(shù)保證當(dāng) customerinfo表中的一條客戶(hù)記錄被刪除的時(shí)候,salesinfo 表中所有與該客戶(hù)相關(guān)的記錄也會(huì)被自動(dòng)刪除。如果要在 MySQL中使用外鍵,一定要記住在創(chuàng)建表的時(shí)候?qū)⒈淼念?lèi)型定義為事務(wù)安全表 InnoDB類(lèi)型。該類(lèi)型不是 MySQL 表的默認(rèn)類(lèi)型。定義的方法是在CREATE TABLE 語(yǔ)句中加上 TYPE=INNODB。如例中所示。
      Mysql Limit操作 
      select * from table LIMIT 5,10; #返回第6-15行數(shù)據(jù)
      select * from table LIMIT 5; #返回前5行
      select * from table LIMIT 0,5; #返回前5行 
      性能優(yōu)化: 
      基于MySQL5.0中l(wèi)imit的高性能,我對(duì)數(shù)據(jù)分頁(yè)也重新有了新的認(rèn)識(shí).
      1.
      Select * From cyclopedia Where ID>=(
      Select Max(ID) From (
       Select ID From cyclopedia Order By ID limit90001
      ) As tmp
      ) limit 100;
      2.
      Select * From cyclopedia Where ID>=(
      Select Max(ID) From (
       Select ID From cyclopedia Order By ID limit90000,1
      ) As tmp
      ) limit 100;
      同樣是取90000條后100條記錄,第1句快還是第2句快?
      第1句是先取了前90001條記錄,取其中最大一個(gè)ID值作為起始標(biāo)識(shí),然后利用它可以快速定位下100條記錄
      第2句擇是僅僅取90000條記錄后1條,然后取ID值作起始標(biāo)識(shí)定位下100條記錄
      第1句執(zhí)行結(jié)果.100 rows in set (0.23) sec
      第2句執(zhí)行結(jié)果.100 rows in set (0.19) sec
      很明顯第2句勝出.看來(lái)limit好像并不完全像我之前想象的那樣做全表掃描返回limitoffset+length條記錄,這樣看來(lái)limit比起MS-SQL的Top性能還是要提高不少的.
      其實(shí)第2句完全可以簡(jiǎn)化成
      Select * From cyclopedia Where ID>=(
      Select ID From cyclopedia limit 90000,1
      )limit 100;
      直接利用第90000條記錄的ID,不用經(jīng)過(guò)Max運(yùn)算,這樣做理論上效率因該高一些,但在實(shí)際使用中幾乎看不到效果,因?yàn)楸旧矶ㄎ籌D返回的就是1條記錄,Max幾乎不用運(yùn)作就能得到結(jié)果,但這樣寫(xiě)更清淅明朗,省去了畫(huà)蛇那一足.
      可是,既然MySQL有l(wèi)imit可以直接控制取出記錄的位置,為什么不干脆用Select * From cyclopedia limit90000,1呢?豈不更簡(jiǎn)潔?
      這樣想就錯(cuò)了,試了就知道,結(jié)果是:1 row in set (8.88)sec,怎么樣,夠嚇人的吧,讓我想起了昨天在4.1中比這還有過(guò)之的"高分".Select *最好不要隨便用,要本著用什么,選什么的原則, Select的字段越多,字段數(shù)據(jù)量越大,速度就越慢.上面2種分頁(yè)方式哪種都比單寫(xiě)這1句強(qiáng)多了,雖然看起來(lái)好像查詢(xún)的次數(shù)更多一些,但實(shí)際上是以較小的代價(jià)換取了高效的性能,是非常值得的.
      第1種方案同樣可用于MS-SQL,而且可能是最好的.因?yàn)榭恐麈IID來(lái)定位起始段總是最快的.
      Select Top 100* From cyclopedia WhereID>=(
      Select Top 90001 Max(ID) From (
       Select ID From cyclopedia Order By ID
      ) As tmp
      )
      但不管是實(shí)現(xiàn)方式是存貯過(guò)程還是

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶(hù) 評(píng)論公約

        類(lèi)似文章 更多