• <label id="pxtpz"><meter id="pxtpz"></meter></label>
      1. <span id="pxtpz"><optgroup id="pxtpz"></optgroup></span>

        當前位置:雨林木風下載站 > 技術開發教程 > 詳細頁面

        ASP 3.0高級編程(413)

        ASP 3.0高級編程(413)

        更新時間:2022-05-16 文章作者:未知 信息來源:網絡 閱讀次數:

        9.3.5 數據高速緩存
               首先需要注意的是,數據高速緩存與記錄集高速緩存雖然都用于改善性能,但兩者是無關的。數據高速緩存是臨時的數據存儲區,允許使用高速緩存中的數據,而不是重新生成新的數據。這只適用于那些不經常改動但多次被訪問的數據。
               在ASP中一個最簡單的緩存數據的方法是使用Application和Session范圍的變量。例如,假設有一些需要選擇書類型的網頁。正常情況下,可能會創建一個含有以下函數的包含文件。
        <%
        Function BookTypes()

          Dim rsBookTypes
          Dim strQuote

          strQuote = Chr(34)

          Set rsBookTypes = Server.CreateObject ("ADODB.Recordset")

          ' Get the book types
          rsBookTypes.Open "usp_BookTypes", strConn

          Response.Write "<SELECT NAME=" & strQuote & lstBookType & strQuote & ">"
          While Not rsBookTypes.EOF
            Response.Write & "<OPTION>" & rsBookTypes("Type") & "</OPTION>"
            rsBookTypes.MoveNext
          Wend
          Response.Write & "</SELECT>"

          rsBookTypes.Close
          Set rsBookTypes = Nothing

        End Function
        %>
        這僅僅是調用一個存儲過程,從而得到書的類型,同時創建一個SELECT列表。上述代碼的缺點在于每次調用該函數都必須訪問數據庫。因此,重新修改這個函數。
        <%
        Function BookTypes()

          Dim rsBookTypes
          Dim strQuote
          Dim strList

          ' See if the list is in the cache
          strList = Application("BookTypes")
          If strList = "" Then
            ' Not cached, so build up list and cache it
            strQuote = Chr(34)

            Set rsBookTypes = Server.CreateObject ("ADODB.Recordset")

            ' Get the book types
            rsBookTypes.Open "usp_BookTypes", strConn

            strList = "<SELECT NAME=" & strQuote & lstBookType & strQuote & ">"
            While Not rsBookTypes.EOF
              strList = strList & "<OPTION>" & rsBookTypes("type") & "</OPTION>"
              rsBookTypes.MoveNext
            Wend
            strList = strList & "</SELECT>"

            rsBookTypes.Close
            Set rsBookTypes = Nothing

            ' Check the list
            Application("BookTypes") = strList
          End If

          BookTypes = strList

        End Function
        %>
        這段代碼不只是打開記錄集,它檢查Application變量BookType的值是否為空。如果不為空,則使用該變量的內容。如果為空,則像以前一樣打開記錄集。顯然,一旦第一個人運行了這一例程,便緩存了數據,因此這只對那些不常變化的數據是有用的。
        如果想在用戶基礎上緩存數據,可以使用Session范圍的變量,但這里必須注意Session存在有效期。過期后會話層變量將和會話一起取消,代碼便有可能終止運行。
        利用Web Application Stress(WAS)工具,得到了表9-4的分析結果:
        表9-4  利用WAS工具得到的分析結果
        方 法
        頁面點擊次數

        沒有高速緩存
        190

        有高速緩存
        11000

        很明顯性能有所改善。但不要采用上述方法緩存一切內容。畢竟,這種方法只適用于那些已經格式化后用于顯示的數據。除此之外,還要考慮到如果Web服務器只為特定的一個人服務,那幾乎不是一個典型的Web服務器的用法。使用WAS可以在一個服務器上模擬多個用戶,這樣可以更實際地測試應用程序。
        通過模擬一定數量的用戶,Web Application Stress工具可以對Web頁面進行承受力測試。該工具有一個簡單的圖形界面,使用起來非常容易。可以從http://homer.rte.microsoft.com/獲得更多的信息,也可以下載該工具。
        高速緩存對象
        若要緩存未格式化過的數據該怎么辦?可以在不同地方以不同的方式使用嗎?當然,也可以用Application或Session變量這樣做。考慮一下書標題的情況。你或許希望在多個頁面中使用這個標題,也許在一個表格中顯示所有的標題,或在一個列表框中顯示供用戶選擇等等。你可能會想到可以緩存記錄集本身而無需緩存含有標簽的HTML文本。
        可以在Application或Session變量中緩存對象,但有兩個主要的問題需要注意:
        · 存放在Application變量中的對象必須支持自由線程,因此必須是自由線程對象或雙線程對象。這意味著無法在Application變量中緩存由VB創建的組件。
        · 在Session狀態中存放單元線程對象意味著創建該對象的線程是唯一允許訪問它的線程。因此IIS無法較好地完成線程管理,因為任何試圖訪問這個對象的頁面都必須等待原有線程服務于該頁面。這將扼殺擴展應用程序的任何機會。
        對于線程問題的討論參見第15章。
        默認情況下,ADO作為單元線程對象裝載,這主要是因為部分OLE DB提供者并非是線程安全的。在ADO安裝目錄中有一個注冊表文件,可將ADO轉換成雙線程模型,由此使ADO對象可以安全地存放在Application和Session對象中。
        你也許會認為所有的問題都解決了,可以通過使用各種類型的對象獲得顯著的速度提升,但這并不一定。許多人已經認識到既然連接到數據庫是一個相對昂貴的操作,那么緩存Connection對象可在再次連接時節省大量的時間。的確如此,但緩存Connection對象意味著該連接永遠不會關閉,因此連接緩存池的工作效率比較低。連接緩存池隱含的一個思想實際上是減少服務器上使用的資源,而緩存ASP狀態中的對象顯然不能減少資源的使用。事實上還增加了對它們的占用,因為每緩存一個對象便要占用服務器的資源,對于一個繁忙的站點而言,這將極大地降低Web服務器的效率。
        所以不應存儲Connection對象,但對于Recordset對象,特別是斷開連接的記錄集呢?假定ADO已從單元線程變成了雙線程,就沒有什么理由不這么做了,只要確切知道自己在做什么。不要認為這會自動地改善ASP頁的性能。每一個緩存的記錄集都在內存和ASP管理方面占用服務器的資源,因此不要緩存大的記錄集。
        另一個技巧是使用記錄集的GetRows方法,將記錄集轉換成一個數組。因為數組并不像Recordset對象那樣受線程問題的影響,因此非常適合用于會話層的變量。然而它同樣也占用服務器資源,還必須考慮處理數組的時間。
        構建自己的應用程序,緩存技巧并非是必要的。

        9.4 數據整形
        數據整形或分層的記錄集能顯示一個樹狀結構或相關記錄集。這通過在記錄集的字段中包含一個記錄集來實現,可以展現數據庫的關系,而且多個記錄集能在一次調用中返回。有兩個理由可以解釋它為什么是有用的:
        · 性能:當正確使用時,數據整形可以改善性能。
        · 便利:在數據整形中非常容易映射父子關系。
        要知道數據整形涉及到哪些內容,最簡單的方法是看圖9-8所示的內容:

        圖9-8  數據整形涉及的內容
        圖9-8顯示了Pubs數據庫中表Publishers、Titles及Sales的層次關系。
        值得注意的一點是每個子記錄集都不是獨立的記錄集。因此,圖9-8中只有三個記錄集,而不是六個。這是怎么來的呢?在層次關系中每一層都有一個記錄集,分別是Publishers、Title和Sales。在Publishers表中引用標題時,實際上是引用了Titles記錄集,但ADO過濾了Titles,所以只顯示那些與被選擇的出版社對應的記錄。這就容易使人誤以為每個子元素有一個獨立的記錄集。

        9.4.1 使用數據整形
        應用數據整形必須:
        · 使用MSDataShape OLEDB提供者。
        · 使用一種特殊的整形語言,它是SQL的一種擴充,允許構造層次。
        盡管使用新的提供者,連接字符串的實際改變不會太大。這是因為仍然需要從某處獲取數據。因此,可以這么做:
        Provider=MSDataShape; Data Provider=SQLOLEDB; Data Source=...
        這里用MSDataShape作為提供者,而正常的Provider變為Data Provider,而連接字符串的剩余部分保持不變。
        為數據整形創建連接字符串的簡便方法是從創建正規的連接字符串開始,然后附加到數據整形塊的最后。例如,考慮以下正規的連接字符串。
        strConn = "Provider=SQLOLEDB; Data Source=Kanga; " & _
                      " Initial Catalog=pubs; User Id=sa; Password="
        可以像下面這樣為數據整形提供者創建連接字符串。
        strConn = "Provider=MSDataShape; Data " & strConn
        這將提供者設置為MSDataShape,而Data Provider成為實際的數據源。初始的連接字符串已經包含了"Provider= ",所以為了獲得正確的連接細節,只須前面加上Data。
        1.  整形語言
        整形語言有其自己的語法,但這里我們不打算涉及其構造,它已包含在ADO文獻中。大多數情況下會采用以下命令。
        SHAPE {parent command} [AS parent alias]
        APPEND ({child command} [AS child alias]
        RELATE parent_column TO child_column) [AS parent_column_name]
        要理解這一點,最簡單的方法是看一個實例,以Publishers和Titles為例。
        SHAPE {SELECT * FROM publishers}
        APPEND ({SELECT * FROM Titles}
        RELATE Pub_ID TO PubID) AS rsTitles
        第一行是父記錄集,第二行則是子記錄集。第三行指明了關聯父、子記錄集的兩個字段。這個例子中兩個表都有一個名為Pub_ID的字段(出版社ID字段)。這個命令返回一個包含出版社的記錄集,在記錄集的最后又附加了一個含有子記錄集的新列(類型為adChapter)。該列名為AS子句給出,在本例中是rsTitles。
        adChapter類型只是說明了該字段含有一個子記錄集。我個人認為,adChild或adRecordset更合適。
        通過遍歷Fields集合,可以很容易看到父記錄集的字段的情況。對于上面的SHAPE命令,得到圖9-9所示的結果:

        圖9-9  執行SHAPE命令后的結果
        訪問子記錄集
        現在,我們有了一個子記錄集,它是另一個記錄集的一個字段,那么如何訪問這個子記錄集呢?很簡單,可以使用字段的Value屬性來建立另一個記錄集。
        Set rsTitles = rsPublishers("rsTitles").Value
        可以遍歷父記錄集,對應于每個父記錄可以得到一個子記錄集。下面的代碼能實現這一點。通常以包含文件、變量聲明開始。
        <!-- #INCLUDE FILE="../Include/Connection.asp" -->
        <%
        Dim rsPublishers
        Dim fldF
        Dim strShapeConn
        Dim strShape

        Set rsPublishers = Server.CreateObject ("ADODB.Recordset")
        現在創建連接字符串。
        ' Create the provider command
        strShapeConn = "Provider=MSDataShape; Data " & strConn
        接下來,輸入實際的整形命令。這將創建一個包含出版社的父記錄集和一個含有書名的子記錄集。
        ' now the shape command
        strShape = "SHAPE {SELECT * FROM Publishers}" & _
                   " APPEND ({SELECT * FROM Titles}" & _
                   " RELATE Pub_ID TO Pub_ID) AS rsTitles"
        然后正常打開記錄集。
        ' Open the shaped recordset
        rsPublishers.Open strShape, strShapeConn
        像正常的記錄集一樣,能夠遍歷記錄。
        ' loop through the publishers
        Response.Write "<UL>"
        While Not rsPublishers.EOF
            Response.Write "<LI>" & rsPublishers("pub_name")
        為了訪問子記錄集,設置一個變量來指向那個包含子記錄集的字段的Value值。本例中該變量為rsTitles。
        ' now the titles
        Response.Write "<UL>"
        Set rsTitles = rsPublishers("rsTitles").Value
        變量rsTitles在這里是個記錄集,其作用同普通的記錄集相同。因此,可以遍歷該記錄集的值,該值只包含與父出版者匹配的書名。
        ' loop through the titles
            While Not rsTitles.EOF
              Response.Write "<LI>" & rsTitles("title")
              rsTitles.MoveNext
            Wend
            Response.Write "</UL>"

            ' move to the next publisher
            rsPublishers.MoveNext
          Wend
          Response.Write "</UL>"

          rsPublishers.Close
          Set rsPublishers = Nothing
          Set rsTitles = Nothing
        %>
        于是得到一份令人滿意的出版社與書名的列表,如圖9-10所示:

        圖9-10  整形后的書名列表
        用一些DHTML代碼和一些額外的標記,就能輕松地隱藏起書名,并且只有選擇出版社時才顯示相應的書名。
        2.  多個子記錄集
        如果對于每個記錄集僅能有一個子記錄集,那么數據整形就不夠完善。但數據整形是極其靈活的。例如可以使用下面的程序來為出版社引用標題和雇員。
        SHAPE {select * from publishers}
        APPEND ({select * from titles}
        RELATE pub_id TO pub_id) AS rsTitles,
              ({select * from employee}
        RELATE pub_id To pub_id) AS rsEmployees
        只需在APPEND子句后加上其他子記錄集,就能得到圖9-11的結果:

        圖9-11  多個子記錄集的結果
        訪問子記錄集的方法并沒有改變,仍舊可以用列的Value屬性訪問子記錄集。只是此時有兩個子記錄集,因此需要使用兩個變量。
        Set rsTitles = rsPublishers("rsTitles").Value

        Set rsEmployees = rsPublishers("rsEmployees").Value
        3.  孫代記錄集
        在子記錄集自身還包含子記錄集的情況下,可能會出現孫代記錄集。例如:
        SHAPE {SELECT * FROM Publishers}
        APPEND ((    SHAPE {SELECT * FROM Titles}
                             APPEND ({SELECT * FROM Sales}
                             RELATE Title_ID TO Title_ID) AS rsSales)
        RELATE Pub_ID TO Pub_ID) AS rsTitles
        在第一個APPEND子句內是另一個SHAPE命令,而不是一個SELECT語句。與多個子記錄集的例子相似,訪問孫代記錄集的方法是相同的。
        Set rsTitles = rsPublishers("rsTitles").Value

        Set rsSales = rsTitles("rsSales").Value
        對子和孫記錄集的深度沒有理論上的限制,但也不可能建立多于三級或四級的子記錄集。

        9.4.2 性能
        數據整形不會自動改善性能,但正確使用時可以改善性能。重要的是記住其工作方式:
        · 對于SHAPE命令中的SELECT語句,將完全取出表中的數據。SQL語句并沒有得到任何優化。這樣,如果在父表中加入WHERE子句來限制父記錄集的記錄數,仍能得到所有的子記錄集。例如:
        SHAPE {SELECT * FROM Publishers WHERE State='CA'}
        APPEND ({SELECT * FROM Titles}
        RELATE Pub_ID TO Pub_ID) AS rsTitles
        APPEND語句返回所有的標題,并不僅限于加州(CA)的出版社。記住,這不是SQL JOIN語句。在加州的出版社以及所有的標題都被提取了,這樣就完成了數據整形。
        · 可以使用存儲過程,這會提高一點性能。然而,如果使用一個參數化的存儲過程產生子記錄集,那么每次訪問子記錄集時,這個存儲過程都會執行。這意味著,子記錄集不在前端代碼中編程產生,而是只包含存在存儲過程產生的那么記錄。不足之處是增加了服務器的工作,但這樣卻能保證數據是最新的,因為每次需要時就從數據庫中提取數據。
        在下一章當我們著眼于客戶端數據時,會看到更多有關經過整形的記錄集的介紹。

        9.5 小結在下面兩章以及本書的其余部分將看到相關的其他知識。在后續章節將詳細探討Web服務器與瀏覽器之間的交互。畢竟,僅有數據是不行的,還要讓人們看見這些數據。

        溫馨提示:喜歡本站的話,請收藏一下本站!

        本類教程下載

        系統下載排行

        主站蜘蛛池模板: 在线a亚洲老鸭窝天堂av高清| 亚洲日韩乱码中文无码蜜桃| MM1313亚洲精品无码久久| 91频在线观看免费大全| 亚洲免费在线观看视频| 100000免费啪啪18免进| 在线观看日本亚洲一区| 精品国产免费观看一区| 成人精品国产亚洲欧洲| www.亚洲色图.com| 91在线品视觉盛宴免费| 亚洲人成在线免费观看| 成人无码区免费视频观看| 中国china体内裑精亚洲日本| 精品免费国产一区二区三区| 亚洲精品无码专区久久| 亚洲精品国精品久久99热| 一级毛片免费全部播放| 亚洲高清专区日韩精品| 131美女爱做免费毛片| 国外亚洲成AV人片在线观看| 国产做国产爱免费视频| 337p日本欧洲亚洲大胆精品555588| 97在线视频免费公开观看| 亚洲卡一卡二卡乱码新区| 国产免费变态视频网址网站| 国产精品hd免费观看| 亚洲成电影在线观看青青| 在线视频免费国产成人| 久久一区二区三区免费| 亚洲天堂福利视频| 亚洲成AV人网址| 久久精品人成免费| 久久人午夜亚洲精品无码区| 国产亚洲日韩一区二区三区| 1000部拍拍拍18勿入免费视频软件 | 无码日韩人妻av一区免费| 婷婷亚洲综合一区二区| 婷婷亚洲综合五月天小说| 成人毛片免费视频| 91视频免费观看|