第四章第二節 透視表組件如何處理資料
透視表組件最重要和最複雜的方面之一就是它是如何與各種資料來源進行互動,以及它在一個會話中是如何操作資料的。本節會解釋透視表控制項如何與資料來源通訊,以及在會話期間是如何傳輸和操作資料的。
透視表控制項的功能是有一點不確定的――因為它的大部分功能都依賴於它所串連到的資料來源的類型。它基本上只能使用兩類資料來源:表列資料和多維資料。(多維資料來源也可以稱為OLAP資料來源;本書中我會交替使用這兩個術語。)我們也會討論使用XML資料來作資料來源的情況。雖然XML資料看起來與任何其它用於透視表控制項的表列資料來源很相似,但它還是有一些需要特別討論的需求。
表列資料來源
現存任何公開資料表的OLE DB資料來源都是表列資料庫。一般來說,它們都是屬於關聯式資料庫引擎的領域的。不過,這個類別也能包含非關係型的資料提供者――只要它們具有某種形式的文本命令文法或者命名的表格???。
圖4-6顯示了將一個表列資料來源返回的資料裝載到透視表組件中後報表最初的樣子。(您也可以通過運行隨書光碟片Chap04檔案夾下的PivotTableList.htm檔案來查看這個報表。)
這個報表和在一個Excel試算表中匯入一個外部資料範圍後產生的報表相似。不過,因為透視表控制項結合了外部資料範圍和透視表報表兩者的功能,所以您現在可以在這個報表中根據任何欄位來對資料分組,以及為任何欄位建立一個新的合計。例如,使用“Move To Row Area”,“Move to Column Area”和“AutoCalc”工具箱按鈕,您可以將這個普通的資料列錶轉化成4-7所示的透視表報表。
圖4-6。一個裝載了表列資料來源的資料的透視表報表。
圖4-7。由一個普通的資料列表建立的透視表報表。
因為資料來源是表列資料來源,所以透視表控制項可以顯示任何統計值下的細目資訊――這就意味著您可以展開任何數字,立刻查看到組成這個數位各行。圖4-8顯示了訪問表列資料來源的一個整體結構。
圖4-8。訪問表列資料來源。
當提取資料時,透視表控制項首先串連到連接字串中的provider屬性中定義的OLE DB提供者。當在設計環境中建立報表時,您一般會在資料連線屬性對話方塊的一個列表中選擇所需的提供者。提供者是一個寄宿在用戶端機器上的進程內COM組件,通常使用一種專用協議與資料服務器進行通訊(如果確實有一台伺服器)。例如,SQL Server提供者使用各種協議與伺服器進行通訊,最常用的協議叫做具名管道。不過,微軟Jet資料庫的提供者需要對MDB檔案的檔案存取權限,因為Jet資料庫引擎不是一個用戶端-伺服器系統。
當透視表控制項串連到資料來源後,它將它的CommandText屬性中的內容傳遞給提供者來執行。您可以在設計階段使用屬性工具箱中的Data Source段來設定CommandText屬性,或者您也可以在運行時使用代碼來設定它。透視表控制項使用ADO的Recordset對象來執行命令文本,因此任何能夠傳遞給Recordset的Open方法的值都可以在CommandText屬性中使用。這些值一般包括SQL語句、表名、視圖名或預存程序名。提供者執行後,返回一個OLE DB的IRowset介面,以便用戶端能夠訪問執行命令返回的資料。
當動作表列資料來源時,透視表控制項使用ADO來將返回的資料立刻裝載到名為微軟遊標引擎(WCE)的組件中,WCE是由微軟資料訪問組件(MDAC)提供的一個組件,它提供了在任何資料提供者上進行進階遍曆,排序和過濾的功能。WCE將資料從資料來源提供者中裝載到它自己的記憶體緩衝中,如果緩衝中包含的資料超出了它所允許的記憶體上限,這些資料最終還是會被換頁到磁碟上。(這可以防止WCE耗盡您所有可用的系統記憶體。)當資料被裝載到WCE中後,透視表控制項通過與WCE通訊來實現過濾,排序,以及遍曆資料集。
當您開始根據一個欄位對結果集進行分組,或當您使用與前面所介紹方法相似的步驟來建立一個統計值時,魔術般的事情發生了。為了形成交叉表格,透視表控制項使用了另一種名為“透視表格服務組件”的資料管道。這個組件實際上是OLAP服務的用戶端提供者,但是它也能在不需要資料來源的情況下,在用戶端上建立臨時cube。當您根據欄位進行分組或建立一個統計值時,透視表控制項將一個指向資料集的引用和需要臨時cube中的那個維和哪個統計值的描述資訊傳遞給透視表格服務組件。這個引擎會在微軟Windows作業系統的臨時檔案夾下建立一個臨時檔案,因此如果您公司的策略是不允許web瀏覽器中的控制項建立臨時檔案,那麼你就要注意這個問題。
命名臨時cube檔案
在實現這個功能時,透視表組件的明星資料開發人員之一,David Worktendyke,必須設計一種命名臨時cube檔案的方案,以便它不會覆蓋任何現存的檔案或影響運行在其它應用程式中的另一個透視表控制項。他提出的最終方案是使用當前進程和線程ID以及慣用的CUB副檔名來組成檔案名稱。
因此當在使用表列資料來源的透視表控制項中進行分組和建立統計值時,如果您在您的臨時檔案夾下看到一些名字很奇怪的檔案,記住它是由透視表控制項建立的臨時cube檔案。不必擔心――當控制項銷毀時這些檔案會被自動刪除。
當動作表列資料時,透視表控制項會自動為細目資料中的每個日期或日期/時間欄位產生兩個時間層。一層包括年,季度,月和天的分組間隔;另一層包括年,周和天的分組間隔。(這兩層都是必需的,因為周不能恰好組成一個月。)這些自動形成的層使得可以很容易的分析那些具有時間維的資料,允許您查看每一個時間間隔對應的資料摘要。
如果您計劃在一個web頁面上使用透視表控制項,您可能還需要研究如何使用Remote Data Services(RDS)。這是MDAC中提供的另一種資料訪問管道,它使用HTTP來訪問資料來源。當使用RDS時,用戶端僅需要RDS提供者這一種提供者,它是隨Office Web組件一起被安裝的。RDS提供者然後就會通過web伺服器和實際的資料提供者(例如,SQL Server)進行通訊,這使得未經處理資料源提供者只存在與伺服器上。如果需要瞭解RDS的更多資訊,請參考微軟網站http://www.microsoft.com/data上關於資料訪問部分的內容。
多維(OLAP)資料來源
您很可能非常熟悉表列資料來源或關係資料來源,但您可能並不瞭解多維(或OLAP)資料來源。在我介紹透視表組件中的各元素是如何映射到多維資料庫的各結構上之前,請允許我先簡單介紹一下多維資料庫的概念。
OLAP簡介
在關聯式資料庫中,表和關係是最主要的資料結構和概念,您通過定義包含一列(或多列),主鍵,規則等的表來構建資料庫。然後您通過指定這個表的外鍵(與其它表的主鍵相匹配)的方法來在這些表之間建立關係。指定和其它表的主鍵相對應的外鍵來在這些表之間建立關係。一旦完成了這些工作,您就可以在資料庫引擎上執行SQL語句,可以根據需要使用關聯,排序,限制和分組來滿足客戶的需求。
在多維資料庫中,主鍵的資料結構是一個cube,或者更準確的說,是一個hypercube(超立方體)。這個結構是一個N-維的矩陣,要可視化它有點困難。在每一維中包含的項叫做members(成員),N個members的交點形成一個數字。讓我們來看一個例子,可以讓我們覺得不那麼的抽象。
假設我們在一個超立方體中對一個公司的銷售資料進行建模。在我們的例子中,我們從二維開始:產品和客戶。二維結構很容易形象化,因為它的樣子象一個矩形,您可能在比較兩維資訊時見過這種矩形,例如一個交叉表。圖4-9顯示了一個矩形可能的樣子。
圖4-9。一個二維的資料庫。
請注意客戶名稱顯示在一維中,而產品名稱顯示在另一維中,中央地區的數字是銷售額。對於任何產品和客戶的組合,都會存在一個數值,代表這個客戶在這個產品上消費的金額的總和。還要注意在每一維中都有一個名為All的額外成員。這個成員代表了當前維所有成員的統計值(一般是所有成員的總和)。因此,Customers.All和某個產品的交叉點代表了這個產品的總銷售額。同樣,Products.All和某個客戶的交叉點代表了這個客戶所產生的總的消費額。兩個All成員的交叉點就是所有客戶,所有產品的銷售總額。
現在設想將包含銷售人員姓名的第三維加入到這個矩形中。結構就會變成一個三維的立方體,在概念上類似圖4-10所示。
現在三個座標――客戶,產品,和銷售人員――確定了立方體中的每個交叉點,或者說單元。在銷售人員維中又出現了一個名為All的成員,它代表所有銷售人員的銷售總額。這個結構允許您從多個角度來查看資料,從而協助您回答各種問題。因為這些數值都儲存在結構中,所以多維資料庫能夠快速存取這些單元的任何集合。
圖4-10。一個三維資料庫。
很難將四維結構可視化,但可以設想您需要對另外的資料值進行匯總。例如,您可能不但需要瞭解銷售的物品的銷售額,還需要瞭解銷售的數量。這些多值建立了包含兩個成員(銷售物品的銷售數量和銷售金額)的第四維。這些數值在多維資料庫中被稱為measures(尺寸);不過大多數的資料來源將尺寸看作維。圖4-11顯示了一種形象化四維資料的方法。
在多維資料庫內部仍然會在一個四維的超立方體中儲存所有的資料。但是您可以採用將一個四維資料結構看作是多個三維立方體的方式來理解四維資料結構。如果您需要查看一個特定的客戶,產品和銷售人員交點的商品銷售金額,您應該查看第一個cube。如果您需要瞭解同一個交叉點的產品銷售數量,您應該查看第二個cube。當然您可以擴充這個例子以顯示立方體中的表,以及顯示cube中的的cube――但我到此為止,否則您會在企圖可視化16維的空間時發瘋。
圖4-11。一個四維資料庫。
大部分多維資料庫也允許您對一個維中包含的成員進行分組,在分組中會對該成員隱式的指定了父元素和子項目。實際上,各維在它們內部都定義了一個或多個層,每一層都包含一個或多個levels(層級),每個層級又都包含一系列的成員。這模仿了大部分分類資料的自然結構――產品通常屬於一個相關產品組,客戶通常居住在一個國家的一個州的一個城市中,銷售人員屬於某個地區的某個管區,等等。例如,客戶維可能包含層級All,國家,州,城市,和客戶名稱。國家層級中的成員集合可能是美國,加拿大和墨西哥,而州層級中的成員集合可能是華盛頓,俄勒岡,大不列顛-哥倫比亞,艾伯特,哈利斯科,韋拉克魯斯等等。
一個單一維中有可能包含多個層。例如,如果您擁有一個僱員維,您可能需要根據部門結構來計算差旅費,以便瞭解每個經理和部門主管的花費的總和,或您可能需要瞭解從事某項工作職能的所有僱員(例如,市場、銷售、產品開發、或行政人員)的花費的總和。維中的成員是相同的(都是各個僱員),但是他們被組織到不同的層,並因此建立了不同的統計值。
許多書籍,雜誌,報告,和大量論文對多維資料庫進行了深度的討論。如果您已經購買了一個多維資料庫,那麼很可能您的資料庫的附屬文檔對這些概念的描述要比我在這裡介紹的詳細的多。
透視表組件如何與OLAP資料來源互動
透視表組件與OLAP資料來源通訊和互動的方式,和它與表列資料來源通訊互動的方式相似。圖4-12顯示了對這個結構的一個整體描述的圖片。
圖4-12。透視表組件和一個OLAP資料來源之間的互動。
透視表控制項使用微軟定義的OLE DB for OLAP標準,這個標準被許多多維資料庫所支援。這個模型是OLE DB標準的一個擴充,因此透視表控制項和OLAP資料提供者之間的互動方式,自然和它與表列資料提供者之間的互動方式相似。控制項首先串連資料提供者,這個提供者也是一個寄宿在用戶端機器上的進程內COM組件。提供者決定它如何與多維資料庫進行通訊。例如,OLAP服務在用戶端和伺服器之間使用TCP/IP的socket串連。
在透視表元件連線到OLAP資料來源後,它可以通過透視表欄位列表視窗在一個指定的超立方體中顯示所有的層和尺寸。當使用者將層和尺寸拖放到透視表控制項中時,或者當開發人員使用代碼插入層和尺寸時,透視表控制項在MDX(多維度運算式,由OLE DB for OLAP標準定義的查詢語言)中產生必需的查詢請求,並在資料來源上執行它們。最後資料提供者返回查詢結果,透視表控制項將結果顯示在螢幕上。
當操作OLAP資料來源時,通過網路傳輸的資料量是非常小的。OLAP提供者通常只是將MDX查詢字串發送給伺服器,而伺服器返回的也只是您在介面上看到的儲存格和成員的名稱。伺服器只會將統計值發送回用戶端,而不是那些建立這些總值所必需的底層的細目資料。這使得透視表控制項可以快速響應請求,提高了系統的延展性,從而能夠支援大量的並發用戶端。
我應該建立一個cube,還是只需對錶列資料進行分組?
當我向人們展示透視表組件能夠對錶列資料進行分組和匯總,就好象它是一個來自OLAP cube的報表時,人們常常問我,“那麼為什麼我還要建立一個cube?”
對這個問題的回答要分為兩部分。首先,使用一個預建立,基於伺服器的超立方體常常能夠比通過透視表控制項建立表列資料的臨時立方體的方式,獲得效能上的極大提高。每當您在一個表列資料中對一個新的欄位進行分組時,透視表控制項必須重新建立cube並重建所有的統計值。而一個基於伺服器端的cube只會建立這些統計值一次,所有訪問這個cube的用戶端都會共用這些統計值。
第二,一個預建立的cube可以使用多層級來定義各層,從而建立一個在資料中進行切入的清晰的路徑。而當透視表控制項對關係型資料進行分組時,只會為日期欄位建立層;它無法知道例如Country,State和city這樣的欄位實際上是同一層的三個層級。在一個預建立的cube中,您可以定義這些層,使得資料的使用者能夠方便的找到他們所需要的資訊。
XML
透視表組件還有一個特殊的資料來源,一個返回特定格式XML資料的URL。在ADO2.1版本中,微軟的資料訪問小組(開發MDAC的小組)定義了一種儲存OLE DB的行集合的XML格式。它們也建立了一種叫做persistence provider(持久提供者)的資料訪問管道,它可以通過讀寫這種格式的XML資料來存取一個OLE DB的行集合。透視表控制項能夠使用這個提供者來將從某個URL返回的xml資料裝載到微軟遊標引擎中,圖4-13描述了這種情況下的結構。
圖4-13。使用永久提供者來將xml資料裝載到WCE中。
我會馬上解釋如果要使用這種方法,您必須將那種類型的連接字串傳遞給透視表控制項。不過,為了即將開始的討論,還要插一段,透視表控制項所需要的最重要的資訊是那個可以從中獲得XML資料流的URL。透視表控制項將這個URL傳遞給持久提供者,持久提供者接著使用Windows的Internet服務要求這個URL的返回結果。然後對結果解析,並裝載到WCE中,而透視表控制項接著開始處理結果資料――就象它處理表列資料一樣。
這種xml資料的格式是特定的,很遺憾,這種格式相應的文檔並不齊全。不過,查看這種格式最簡單的方法就是使用ADO Recordset對象的Save方法將一個Recordset的內容以adPersistXML格式儲存到一個檔案中。如果您需要動態產生這種格式的資料――例如,在一個微軟ASP頁面中,您可以使用Recordset的Open方法來測試您的輸出。如果您可以將您的XML資料裝載到一個ADO Recordset對象中,那麼它也會成功的被裝載到透視表控制項中,因為控制項使用的是和ADO Recordset對象同樣的機制。可以查看第6章介紹的解決方案的原始碼,其中有在ASP頁面中產生XML資料的例子。