明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線(xiàn)學(xué)習(xí)分享的學(xué)習(xí)平臺(tái)!

Visual FoxPro 9中新的數(shù)據(jù)處理方式

[摘要]Visual FoxPro 9.0與以前的版本相比,在數(shù)據(jù)引擎上做了很大的改進(jìn)。從增強(qiáng)的SQL語(yǔ)言到支持新的數(shù)據(jù)類(lèi)型和索引都作了增強(qiáng),本文闡述了這個(gè)最新版本作為一個(gè)成熟開(kāi)發(fā)平臺(tái)的魅力。數(shù)據(jù)引擎的改變主要體現(xiàn)在以下5個(gè)方面:· 增強(qiáng)的SQL語(yǔ)言:取消了很多硬編碼的限制,增強(qiáng)了子查詢(xún)和關(guān)聯(lián)查...

Visual FoxPro 9.0與以前的版本相比,在數(shù)據(jù)引擎上做了很大的改進(jìn)。從增強(qiáng)的SQL語(yǔ)言到支持新的數(shù)據(jù)類(lèi)型和索引都作了增強(qiáng),本文闡述了這個(gè)最新版本作為一個(gè)成熟開(kāi)發(fā)平臺(tái)的魅力。

數(shù)據(jù)引擎的改變主要體現(xiàn)在以下5個(gè)方面:

· 增強(qiáng)的SQL語(yǔ)言:取消了很多硬編碼的限制,增強(qiáng)了子查詢(xún)和關(guān)聯(lián)查詢(xún)的支持,支持更復(fù)雜的表達(dá)式,以及增強(qiáng)了對(duì)UNION的支持。

· 性能方面:加入了一個(gè)全新的索引方式,增加了過(guò)濾型索引的性能,提高了了TOP n ,MIN()/MAX()以及LIKE這些查詢(xún)子句的性能。

· 命令和函數(shù):對(duì)數(shù)據(jù)操作的更具靈活性,增強(qiáng)對(duì)SQL中showplan的支持,增加ICASE()來(lái)代替IIF()函數(shù)。

· 新的數(shù)據(jù)類(lèi)型:支持VarChar、VarBinary和BLOB等新的數(shù)據(jù)類(lèi)型,并提供相應(yīng)的類(lèi)型轉(zhuǎn)換函數(shù):CAST()。增強(qiáng)了現(xiàn)有函數(shù)對(duì)數(shù)據(jù)類(lèi)型的控制和轉(zhuǎn)換能力

· 遠(yuǎn)程數(shù)據(jù):增強(qiáng)了事務(wù)控制的能力,游標(biāo)機(jī)制使得代碼邏輯更加清晰,并且對(duì)CursorAdapter作了加強(qiáng),使開(kāi)發(fā)者只需數(shù)行代碼就可以方便地訪問(wèn)遠(yuǎn)程視圖。

由于提供了與SQLServer強(qiáng)有力的互操作性,Visual FoxPro 9對(duì)客戶(hù)端/服務(wù)器模式做了很大的改進(jìn)。通過(guò)支持新的數(shù)據(jù)類(lèi)型,并取消了SQL語(yǔ)言的諸多限制,同一套代碼可同時(shí)運(yùn)行在本地?cái)?shù)據(jù)引擎和SQL Server這兩種不同的數(shù)據(jù)源上。

以上是大致的描述,下面讓我們深入剖析這些新增功能。

SQL子查詢(xún)的增強(qiáng)

如果要用一句話(huà)來(lái)表示SQL子查詢(xún)的增強(qiáng)程度,那就是:“太多了”!SQL語(yǔ)句中再?zèng)]有了元素?cái)?shù)量的硬編碼限制。一個(gè)簡(jiǎn)單的SELECT語(yǔ)句能包括更多的表、連接、子查詢(xún)、嵌套子查詢(xún)和聯(lián)結(jié)。

SQL語(yǔ)句中的IN子句中再也沒(méi)有數(shù)量限制。在以前的版本中IN實(shí)際被映射到了一個(gè)名字INLIST()函數(shù)中,但現(xiàn)在這種依賴(lài)取消了。這個(gè)改變使得IN子句能使用更多的參數(shù)來(lái)生成非常復(fù)雜的SQL語(yǔ)句。與原來(lái)版本不同,只要找到相應(yīng)記錄,Visual FoxPro 9會(huì)自動(dòng)停止計(jì)算IN子句中的表達(dá)式,這將帶來(lái)性能的提高。

完全無(wú)限制?

IN參數(shù)表的元素也不是完全無(wú)限的,它的最大數(shù)量等于函數(shù)SYS(3055)的返回值,而這個(gè)函數(shù)的返回值與實(shí)際可用內(nèi)存有關(guān),因此如果你的可用內(nèi)存越大,那么IN子句支持的元素就越多。無(wú)硬編碼的限制并不等于完全無(wú)限制。像可用內(nèi)存以及表達(dá)式的復(fù)雜性都能決定是否能運(yùn)行一個(gè)非常長(zhǎng)而且復(fù)雜的語(yǔ)句,你要花很大的功夫才能找出它們?cè)谀愕臋C(jī)器上的真實(shí)極限。

增強(qiáng)的子查詢(xún)功能

子查詢(xún)?cè)赟QL語(yǔ)言中是一個(gè)很有用的功能。它一般處于WHERE子句中的右邊,充當(dāng)一個(gè)選擇器的作用。在Visual FoxPro 9中,子查詢(xún)還可以處于SELECT的參數(shù)列表中(稱(chēng)為投影)以及FROM子句中(稱(chēng)為派生表)。

當(dāng)你使用投影時(shí),如果子查詢(xún)沒(méi)有返回任何記錄,那將返加一個(gè)空值(NULL)。投影還允許互相關(guān)聯(lián),以后我們會(huì)講到這點(diǎn)。
以下使用投影的SQL語(yǔ)句的一個(gè)例子:

SELECT ;
C.CustomerID, ;
C.CompanyName, ;
(SELECT YTD_Sales FROM Sales_02 WHERE ;
C.CustomerID = Sales_02.CustomerID) AS Y02,;
(SELECT YTD_Sales FROM Sales_03 WHERE ;
C.CustomerID = Sales_03.CustomerID) AS Y03,;
(SELECT YTD_Sales FROM Sales_04 WHERE ;
C.CustomerID = Sales_04.CustomerID) AS Y04 ;
FROM Customers C
這個(gè)SELECT語(yǔ)句返回最后三個(gè)會(huì)計(jì)年度的客戶(hù)ID和公司名稱(chēng)。

使用投影的限制是子查詢(xún)只能查詢(xún)一個(gè)字段,并且子查詢(xún)返回的記錄數(shù)不能大于1。

投影的另一個(gè)有價(jià)值的使用方法是它可以成為表達(dá)式的一部分,如下所示:

SELECT ;
C.customerID, ;
C.companyname, ;
SUM(D.quantity*D.unitprice) AS CustTotal ,;
(SUM(D.quantity*D.unitprice) / ;
(SELECT SUM((quantity*unitprice)-discount) ;
FROM OrderDetails D2) ;
)*100 AS PctTotal ;
FROM Customers C ;
INNER JOIN Orders O ;
ON C.customerID = O.customerID ;
INNER JOIN OrderDetails D ;
ON O.orderid = D.orderid ;
GROUP BY C.customerID, C.companyname, O.orderID ;
ORDER BY pctTotal DESC
這個(gè)SELECT語(yǔ)句返回客戶(hù)ID、公司名稱(chēng)、銷(xiāo)售額以及銷(xiāo)售額占總銷(xiāo)售額的百分比。

注意在以上語(yǔ)句中,子查詢(xún)充當(dāng)SELECT列表中的一個(gè)復(fù)雜表達(dá)式,并且它還包含一個(gè)聚集函數(shù)SUM(),這里我們可以看到使用它的靈活性。

子查詢(xún)的另一種使用場(chǎng)景即派生表,實(shí)際你可以將它看作一個(gè)邏輯表。

考慮以下的例子:

SELECT ;
C.customerid, ;
P.product_count AS p_count;
FROM Customers C, ;
(SELECT c2.customerid, ;
COUNT(DISTINCT D.productID) AS p_count ;
FROM Customers C2 ;
INNER JOIN Orders O ;
ON C2.customerid = O.customerid ;
INNER JOIN OrderDetails D ;
ON O.orderid = D.orderid ;
GROUP BY c2.customerid) AS P ;
WHERE C.customerID = p.customerID ;
AND P.p_count >= ;
(SELECT (COUNT(*)*.50) FROM Products) ;
ORDER BY p.product_count DESC
這個(gè)SELECT語(yǔ)句返回客戶(hù)ID、所有購(gòu)買(mǎi)了50%產(chǎn)品的客戶(hù),以及它們所購(gòu)買(mǎi)的產(chǎn)品數(shù)量。

觀察以上的語(yǔ)句,你可以發(fā)現(xiàn)派生表有一個(gè)名為“P”的別名,這與普通字段別名的語(yǔ)法一樣――都必須用AS子句來(lái)表達(dá)。而且這個(gè)子查詢(xún)很復(fù)雜(在本例中,它關(guān)聯(lián)了兩個(gè)表),這個(gè)派生表還可以作為WHERE子句的一個(gè)條件或者將它放在ORDER BY子句中。

與投影不同,派生表能返回多個(gè)字段以及多條記錄,但它不能相互關(guān)聯(lián)。另外,所有的子查詢(xún)都會(huì)在主句中的SELECT執(zhí)行之前運(yùn)行。

子查詢(xún)還可以充當(dāng)UPDATE語(yǔ)句中的SET列表。但SET子句只允許使用一個(gè)子查詢(xún),并且當(dāng)SET子句使用子查詢(xún)后,那WHERE子句中就不允許再使用子查詢(xún)了。

更好的關(guān)聯(lián)支持

新版本中的UPDATE語(yǔ)句和DELETE語(yǔ)句支持關(guān)聯(lián)。這樣,一條語(yǔ)句可以引用不同的表,如下所示:

DELETE products ;
FROM mfg ;
WHERE mfg.productID = products.productID;
AND mfg.discontinued = .t.
這個(gè)DELETE語(yǔ)句刪除mfg表中所有不再生產(chǎn)的產(chǎn)品。

另一個(gè)關(guān)聯(lián)UPDATE語(yǔ)句示例如下:

UPDATE products ;
SET unitprice = mfg.msrp *.90 ;
FROM mfg ;
WHERE mfg.productID = products.productID
這條UPDATE語(yǔ)句將零售產(chǎn)品的價(jià)格打了九折。可能你會(huì)問(wèn):它支持子查詢(xún)嗎?當(dāng)然支持。但使用的時(shí)候要格外小心。因?yàn)槿绻硬樵?xún)沒(méi)有返回任何記錄,那將會(huì)返回一個(gè)值為NULL的空記錄。而這恰恰不是你所希望得到的結(jié)果。如下所示:

UPDATE products ;
SET unitprice = ;
(SELECT ( msrp *.90 ) ;
FROM mfg ;
WHERE mfg.productID = products.productID)
這條UPDATE語(yǔ)句的作用與上條基本相似,但如果子查詢(xún)中的產(chǎn)品沒(méi)有找到的話(huà),那unitprice將被置為NULL。

視圖與查詢(xún)?cè)O(shè)計(jì)器

盡管新版本增強(qiáng)了子查詢(xún)功能,但不幸的是在視圖與查詢(xún)?cè)O(shè)計(jì)器中并不支持這種增強(qiáng)功能。并且由于SQL中的IN子句中的元素?cái)?shù)目取消了硬編碼的限制,但視圖與查詢(xún)?cè)O(shè)計(jì)器中并不知道,因此如果你使用設(shè)計(jì)器,那IN子句還是只支持24個(gè)元素。

增強(qiáng)的UNION操作符

由于聯(lián)結(jié)的數(shù)量沒(méi)有了硬編碼的限制,你可以在INSERTINTO子句的結(jié)果集中使用UNION。也可以在使用UNION的同時(shí)使用ORDERBY子句。

性能

不管你是訪問(wèn)遠(yuǎn)程數(shù)據(jù)還是依賴(lài)于它強(qiáng)大的本地?cái)?shù)據(jù)庫(kù)引擎,Visual FoxPro始終將性能考慮在第一位。Visual FoxPro 9進(jìn)一步地增強(qiáng)了數(shù)據(jù)引擎的功能。

二進(jìn)制索引

這種新型的索引使用方法如下:

INDEX ON DELETED() TAG DELETED BINARY

這種索引能與任何非空的邏輯表達(dá)式一起使用。除此之外,F(xiàn)OR表達(dá)式、ASCENDING、DESCENDING、UNIQUE或CANDIDATE關(guān)鍵字不能與它一起使用。

二進(jìn)制索引并不支持SET ORDER TO命令,而且INDEXON命令會(huì)將當(dāng)前的order設(shè)為0。但你可在Seek語(yǔ)句中使用二進(jìn)制索引。

二進(jìn)制索引最大的優(yōu)勢(shì)在于它的索引文件大小。以一個(gè)包含800萬(wàn)條記錄的表為例,它的二進(jìn)制索引文件的大小差不多為表大小的三十分之一。尺寸越小意味著在執(zhí)行APPEND和REPLACE操作時(shí)I/O處理速度越快,但遺憾的是所有的Rushmore優(yōu)化技術(shù)目前都還不支持二進(jìn)制索引。

如果SQL語(yǔ)句返回的記錄起過(guò)表中總記錄的三分之一的話(huà),那Rushmore將得到很好的發(fā)揮(當(dāng)所有的記錄都命中的話(huà)會(huì)提高92%的速度)。如果SQL語(yǔ)句返回的記錄低于總記錄的三分之一,那Rushmore將變得很慢(如果沒(méi)有記錄命中的話(huà)會(huì)降低兩倍的速度)。

在Visual FoxPro 9中,將DELETE語(yǔ)句設(shè)置為二進(jìn)制索引是一種增強(qiáng)性能的簡(jiǎn)單方法。但要注意版本的問(wèn)題,因?yàn)橐郧暗陌姹静⒉恢С诌@種新的索引方式。

Rushmore優(yōu)化技術(shù)

新版本中有使用了大量的Rushmore優(yōu)化技術(shù),例如對(duì)TOPN[PERCENT]作了優(yōu)化,這樣便能提供更好的性能。它一般與ORDER BY子句配合使用,返回前N個(gè)或者前百分比數(shù)目的記錄。在Visaul FoxPro 9中它減少了內(nèi)排序操作和文件I/O操作,使得執(zhí)行這種類(lèi)型的語(yǔ)句占用更少的內(nèi)存,并且正如此語(yǔ)句所言,它只返回確切的前N個(gè)記錄。

在以前的版本中,如果要統(tǒng)計(jì)一個(gè)班級(jí)總分排在前十名的學(xué)生,但中間存在并列名次的話(huà),那結(jié)果會(huì)返回多于10個(gè)的記錄。

在適當(dāng)?shù)那闆r下,Visual FoxPro 9將在FOR DELETED()子句和FOR NOT DELETED()子句中使用過(guò)濾索引來(lái)對(duì)MIN()和MAX()這兩個(gè)聚集函數(shù)進(jìn)行優(yōu)化,可以提高M(jìn)IN()和MAX()的計(jì)算速度。

如果LIKE模糊查詢(xún)語(yǔ)句中的條件以“%”為結(jié)尾,那查詢(xún)速度也將得到很大提高(請(qǐng)注意,“%”只能出現(xiàn)在查詢(xún)條件的結(jié)尾,而不能出現(xiàn)在其它地方,否則優(yōu)化無(wú)效)。這種優(yōu)化的結(jié)果等同于普通WHERE子句查詢(xún)的速度。

更多的智能索引技術(shù)

Visual FoxPro 9比以前的版本更智能化,它充分地讓索引獲得Rushmore的優(yōu)化技術(shù),如下所示:

INDEX ON DELETED() TAG DELETED
以上語(yǔ)句自動(dòng)對(duì)NOTDELETED()和DELETED()條件進(jìn)行優(yōu)化,不用你添加一條INDEX ON NOTDELETED()來(lái)實(shí)現(xiàn)。

這里有個(gè)特例,就是當(dāng)索引過(guò)過(guò)濾表達(dá)式采用了FORNOTDELETED()作為Rushmore的優(yōu)化,并且SETDELETED設(shè)為ON的話(huà),那就無(wú)須為NOTDELETED()作優(yōu)化。