當前位置:首頁 » 數據倉庫 » db2udb資料庫實用
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

db2udb資料庫實用

發布時間: 2022-12-06 05:54:22

㈠ DB2 UDB的DB2 UDB 工作組伺服器無限製版

DB2 UDB 工作組伺服器無限製版版本 8.2(DB2 UDB WSUE)是一個功能全面的支持 Web 的客戶機和伺服器關系型資料庫管理系統。在廣域網(WAN)或區域網(LAN)上都可以部署 DB2 UDB WSUE。它提供了數據倉儲功能並可從衛星控制資料庫進行遠程管理。
DB2 UDB WSUE 提供了一個入門級的伺服器,主要用於小型企業和部門計算。它在功能上相當於 DB2 UDB ESE,但沒有集成 zSeries伺服器連接(通過 DB2 Connect 組件),而擴展性也有限(例如,DB2 UDB WSUE 不支持 64 位計算或 DB2 Data Links 文件管理器)。 而且 DB2 UDB WSUE 沒有資料庫分區功
能部件 。

㈡ DB2 聯邦資料庫功能

裡面若是sql語句的話,直接
db2 CREATE SERVER TESTDB TYPE DB2/UDB VERSION '10.5.0' WRAPPER "DRDA" AUTHID "db2inst2" PASSWORD "db2inst2" OPTIONS(ADD NODE 'TESTDB', PASSWORD 'Y')
不要帶雙引號,以及最後的分號。

㈢ 如何在 SAP 系統中監控和分析 DB2 UDB 性能

性能問題總是資料庫領域裡面永恆的話題,使用 DB2 作為底層數據平台的 SAP 系統為我們提供了許多方法監控和檢測資料庫性能問題。本文從資料庫性能問題檢測的一般思路和方法論入手,介紹了如何通過 SAP 系統對 DB2 的性能進行監控和分析。回頁首資料庫性能問題檢測的思路及方法論在資料庫運維工作中遇到性能問題時,通常會讓資料庫管理員感到無從下手,不容易斷定問題的根源所在。如果能有一種可操作的一般性的方法作為指導,我們通常就能夠發現大部分資料庫性能問題的根源。那麼,首先根據我們對資料庫性能監控的一些實踐經驗來總結一下在遇到性能問題時應該進行哪些檢查。我們不能保證通過文中介紹的方法就能找到所有性能瓶頸,性能問題的原因很多,解決方法也多種多樣,我們在這里只是提供一些普遍的,一般性的方法,具體的實施還需要根據系統的具體情況和不斷的實踐經驗積累。同時,通過進行這些監控,也有利於為技術支持人員提供更詳細診斷信息,以便於快速定位性能問題。當遇到一個性能問題,我們首先進行以下排查: 性能問題是在何時發生的; 性能問題持續存在的還是間斷性的; 系統范疇的性能問題還是資料庫本身的性能問題; 性能問題是否只存在於某一個應用; 性能問題是隨機出現的還是必然出現的。如果性能問題存在於所有應用,我們可以進行以下排查: 如果發現系統存在大量的 I/O 操作: 檢查設備使用情況; 檢查排序情況和臨時表空間; 檢查查詢性能是否有效的得到優化; 檢查緩沖池的使用狀況。 如果發現 CPU 具有很高的負載: 檢查排序狀況; 檢查緩沖池的使用狀況。 如果發現 CPU 和 I/O 操作的負荷都很大: 檢查用戶數量; 檢查排序狀況。 如果發現 CPU 和 I/O 操作的負荷都很小而資料庫響應仍然很慢: 檢查並發性和鎖的使用狀況; 檢查緩沖池的使用狀況。如果性能問題可以被定位在一個應用,我們可以進行以下排查: 檢查排序情況。 檢查並發性和鎖的使用狀況。 檢查統計信息是否更新。回頁首通過SAP 系統的工具對 DB2 UDB 進行監控通過前一部分的描述,我們了解到了在遇到性能問題以後應該用什麼思路尋找性能的瓶頸,從而想辦法解決性能問題。在對資料庫進行檢查的過程中,我們通常會用到數據管理工具,命令行以及操作系統的工具,還要結合 SAP 的自身特點尋找性能問題的根源,這將是一個比較繁瑣和費事的工作。在使用 SAP 作為底層資料庫的 SAP 系統中,由於 SAP 實現了與 DB2 緊密的結合。SAP 的 DBA Cockpit 提供了許多功能來支持資料庫的管理工作,使得資料庫性能監控和分析變得更加簡單。下面我們就來看看,SAP 為 DB2 性能監控和分析提供了哪些支持。磁碟I/O 性能監控概念對於資料庫來說,最消耗時間的操作實際上是從磁碟中檢索數據。這是由磁碟的物理特性決定的。盡管磁碟存儲技術已經取得了極大的進步,但磁碟的讀寫速度與內存的讀寫速度仍然相差幾個數量級。從性能調整的角度來說,如果一個機器的磁碟出現問題,那麼其他的任何優化工作都無法提供幫助。因此我們應該保證運行資料庫的磁碟系統是健康的。SAP 系統為我們提供了監控磁碟讀寫速度的功能,讓我們可以直接了解當前磁碟的性能狀況。監控我們首先進入 SAP 的 DBA Cockpit ( 可以直接輸入 st04),然後在 Performance 的目錄下雙擊 Database, Buffer Pool 的標簽內,可以看到當前資料庫磁碟的讀寫狀況。圖1. 磁碟 I/O 信息從圖中我們可以看到磁碟物理平均讀速度為 3.25ms,寫速度為 7.45ms。分析磁碟物理讀寫速度反應了磁碟子系統的性能。一般情況下,磁碟讀寫速度應該小於 5ms,讀速度一般要大於寫速度,但在一些具有大量緩存的存儲系統中,寫速度可能會快於讀速度。磁碟性能的優化已經超出了本文討論的范圍,這里只是提供一些基本的指導。緩沖池監控概念緩沖池是資料庫單獨開辟的一塊存儲區域,這片區域用來緩存從磁碟讀出的包含數據表和索引的數據頁。當數據第一次被檢索出來以後便被暫時緩存在緩沖池中,當數據下次被訪問時,資料庫將直接從緩沖池中讀取數據,這樣減少了相對緩慢的磁碟 I/O 操作。因此,緩沖池的配置對於資料庫性能十分重要。在緩沖池中,目前還不支持存儲大對象和長數據記錄。反映緩沖池質量的一個重要性能指標是緩沖池命中率。緩沖池命中率指資料庫管理器不需從磁碟讀入頁就能處理頁請求的時間百分比。其計算方法為:緩沖池命中率 = (1 - (( 緩沖池數據物理讀 + 緩沖池索引物理讀 ) / ( 緩沖池數據邏輯讀 + 緩沖池索引邏輯讀 ) ) ) * 100%另外兩個重要性能指標是索引命中率和數據命中率。索引命中率反映了可以在緩沖池中找到的頁面能夠滿足的對索引頁的所有讀請求所佔的百分比。其計算方法為:索引命中率 = (1 - ( 緩沖池索引物理讀 / 緩沖池索引邏輯讀 ) ) ) * 100%數據命中率說明了可以在緩沖池中找到的頁面能夠滿足的對數據頁的所有讀請求所佔的百分比。其計算方法為:數據命中率 = (1 - ( 緩沖池數據物理讀 / 緩沖池數據邏輯讀 ) ) ) * 100%監控我們可以從三個級別來看緩沖池的質量,這三個層次分別是資料庫級,緩沖池級,表空間級。在 SAP 系統中我們可以使用 DBA Cockpit 來查看不同級別的緩沖池質量。首先可以在資料庫級查看緩沖池的質量,我們進入 SAP 的 DBA Cockpit,然後在 Performance 的目錄下雙擊 Database, 在 Buffer Pool 的標簽內,可以看到當前資料庫總體的緩沖池質量。圖2. 緩沖池總體狀況我們從圖中可以看出,資料庫緩沖池的總體命中率是 99.81%,數據命中率為 99.86%,索引命中率為 99.70%。如果在 st04 中選中 Performance -> Buffer pools, 我們也可以在緩沖池級別看到命中率,如果一個資料庫只有一個緩沖池,那麼這個命中率與我們在資料庫級別看到的命中率相同。圖3. 資料庫級別緩沖池信息如果在 st04 中選中 Performance -> Tablespaces,我們就可以在表空間級別看到緩沖池的命中率。圖4. 表空間級別緩沖池信息分析緩沖池的理想命中率對於索引應該大於 90%, 對於數據應該大於 95%。要提高緩沖池的命中率,可以增加緩沖池的大小,也可以為不同類型數據分配不同緩沖池,可以為每個經常訪問的具有自己的表空間的大型表使用一個緩沖池,也可以為一組小型表使用一個緩沖池。緩存監控概念資料庫的緩存主要有包緩存 (Package Cache) 和編目錄緩存 (Catalog Cache)。它們與資料庫的查詢性能息息相關。包緩存(Package Cache) :SQL 語句編譯通常消耗的資源比較大,為了提高系統性能,動態 SQL 語句在被編譯後一般存放於包緩存中。當用戶下一次請求同一條 SQL 語句,就無需再次編譯 SQL 語句。包緩存的質量一般通過包緩存命中率來衡量,它表明了包緩存的設置是否成功的避免了 SQL 語句的重新編譯。其計算方法為:包緩存命中率 = (1 - ( 在包緩存中的插入次數 / 查詢包緩存的次數 )) * 100編目錄緩存 (Catalog Cache):編目錄緩存用來緩存系統編目錄信息,如系統表,許可權,系統存儲過程。系統編目錄的訪問速度對於系統的性能有著十分重要的影響。在 DPF 環境下,系統編目錄的訪問速度至關重要。通過使用編目錄緩存可以大大提高訪問系統編目錄的速度。編目錄緩存質量一般通過編目錄命中率來衡量,它表明了編目錄緩存是否成功的避免了從磁碟中讀取編目錄信息。其計算方法為:包緩存命中率 = (1 - ( 在編目錄緩存中的插入次數 / 查詢編目錄緩存的次數 )) * 100監控我們進入 SAP 的 DBA Cockpit,然後在 Performance 的目錄下雙擊 Database, 在 Cache 的標簽內,可以看到當前資料庫緩存的統計信息。圖5. 資料庫緩存信息從圖中我們可以看到編目錄緩存的質量是 99.93%,在圖中的 quality 就是我們前面所說的命中率。當前資料庫編目錄緩存的大小為 10240KB,沒有緩存溢出。在左邊一欄,我們可以看到,包緩存的質量是 97.64%,包緩存的大小為 62080KB,沒有緩存溢出。分析包緩存的理想命中率應該大於 98%,用戶通常不用關注包緩存的大小,如果 PCKCACHESZ 被設置為 automatic,其大小由 DB2 自動調節。編目錄緩存的理想命中率也應該大於 98%,其大小應該保證編目錄緩存不應該發生任何溢出。我們可以調整資料庫配置參數 CATALOGCACHE_SZ 來改變編目錄緩存大小,由於編目錄緩存是從資料庫堆中分配的,因此,在改變 CATALOGCACHE_SZ 變數的同時,應該注意到資料庫堆的大小也會相應改變。排序監控概念DB2 在運行過程中時經常要做排序操作。一般說來,在 OLTP 類型的資料庫中,排序操作通常少於 OLAP 類型的資料庫環境。排序操作通常會在三種情況下發生,第一種情況是數據的查詢處理,比如 order by, group, 哈希連接,索引操作,內存的表操作等等。第二種是當我們載入操作的對象是帶有索引的表時,再載入操作過程中就會涉及到對索引鍵的列表和排序,這樣就會產生排序操作。第三種情況發生在創建索引的時候。排序的效率因而直接影響到資料庫的響應時間,我們必須對排序進行有效監控。監控我們進入 SAP 的 DBA Cockpit,然後在 Performance 的目錄下雙擊 Database, 在 Sorts 的標簽內,可以看到當前資料庫的排序狀況。圖6. 資料庫排序狀況可以從圖中看出,共享排序堆的大小為 1676KB, 私有排序堆的大小為 1340KB。如果沒有索引滿足所取的行的要求順序,或者 DB2 查詢優化器認為排序的代價低於索引掃描,那麼就需要在排序堆中進行排序。DB2 的排序分為私有排序和共享排序。私有排序發生在代理的私有代理內存中,而共享排序發生在資料庫的資料庫共享內存中。我們還可以看出,排序堆溢出次數 1174 次,總的排序次數為 310642 次。分析如果資料庫分配的排序堆大小不夠大,就會出現排序溢出的情況,這樣就需要動用臨時表空間來輔助排序的進行,由於臨時表空間存在於磁碟,這將大大影響排序的速度。理想情況下,排序溢出率 ((Sort overflows * 100) / Total sorts ) 不應該超過 1%。如果這個溢出率過高,那麼資料庫中很可能發生了大的排序,我們就需要調查出現過度排序的原因。在發現根源之前,一個簡易的解決方案是增加 SORTHEAP 的大小。然而,這樣做通常是治標不治本並且掩蓋了真實的性能問題。比較徹底的解決方案應該是確定引起排序的 SQL 並更改該語句,或通過增加索引來避免或減少排序開銷。並發性和鎖的監控概念資料庫的鎖是資料庫管理器用來控制應用程序並發訪問資料庫數據並且保證資料庫數據的一致性的重要機制,資料庫中行和表都可以上鎖。資料庫的鎖在保證了資料庫數據一致性同時也在一定程度上降低了資料庫的響應速度。鎖等待和死鎖是影響資料庫相應速度的重要因素,糟糕的應用程序設計和不合理的 SQL 查詢計劃的生成都會導致鎖等待和死鎖。鎖升級 (Lock Escalation):一個鎖通常作為一個記錄存儲在內存鎖表中,鎖表的大小可以由資料庫自動調節。鎖升級一般發生在鎖的數量超過了資料庫配置參數 MAXLOCKS 所指定的大小,為了減少鎖的數量,資料庫會把若干行一級的鎖合並為表鎖。這樣資料庫的並發性就會受到影響。監控我們進入 SAP 的 DBA Cockpit,然後在 Performance 的目錄下雙擊 Database, 在 Locks and Deadlocks 的標簽內,可以看到當前資料庫的鎖的狀況。圖7. 資料庫鎖狀況從圖中可以看到,當前鎖表的大小為 22144KB,已經使用了 94KB。鎖等待的平均時間為 10.40ms,沒有鎖升級和死鎖被檢測到。分析影響數據性能的有關鎖的問題主要集中在鎖等待,死鎖和鎖升級。這些問題的根源很可能是資料庫應用的設計問題。因此,我們應該仔細調查造成死鎖,鎖等待和鎖升級的應用程序,以及其用到的 SQL 語句。同時,在問題定位之前,我們也可以通過下面方法來解決資料庫鎖造成的性能問題。鎖等待和死鎖:如果要避免鎖等待和死鎖的問題我們需要注意資料庫參數中的 DLCHKTIME 和 LOCKTIMEOUT 兩個參數的設置。其中 DLCHKTIME 單位是毫秒,是 DB2 檢查死鎖的間隔時間,如果該值為 10000ms,則表明每隔 10 秒鍾資料庫會檢查一下有無死鎖存在,如有死鎖,會選擇回滾其中的某一個事務,讓另外一個事務完成交易。LOCKTIMEOUT 單位是秒,是鎖等待最長時間,超過該時間仍未獲得鎖,則返回錯誤。LOCKTIMEOUT 的默認值為 -1,這意味著鎖等待時間無限大,一般不推薦這種設置。DLCHKTIME 時間通常要設得比 LOCKTIMEOUT 時間小一些,否則還未發現死鎖,就會返回鎖等待超時錯誤 (SQL0911N 返回碼 68) 。鎖升級:要避免鎖升級,我們應該正確設置資料庫參數 LOCKLIST 和 MAXLOCKS。LOCKLIST 表明分配給鎖表的內存大小。每個資料庫都有一個鎖表,鎖表包含了並發連接到該資料庫的所有應用程序所持有的鎖。MAXLOCKS 定義了應用程序可以佔有鎖表空間的百分比,當一個應用程序所使用的鎖表百分比達到 MAXLOCKS 時,資料庫管理器會升級這些鎖,用表鎖代替行鎖,從而減少列表中鎖的數量。我們一般可以通過增加鎖表大小的方法解決鎖升級問題。日誌性能監控概念DB2 事務日誌對於恢復來說極其重要。它們記錄對資料庫對象和數據所做的更改。在 DB2 中數據和索引的改變都會先被寫入日誌緩沖區,保證對數據所做的修改在記錄到資料庫之前,總是被具體化為日誌文件。日誌緩沖區的數據由日誌處理器寫入磁碟。在下列情況下,查詢處理必須等待日誌數據寫入磁碟後才能進行: 事務提交時。 在將相應數據頁寫入磁碟之前,因為 DB2 使用預寫日誌記錄。預寫日誌記錄的好處是當執行 COMMIT 語句完成事務之後,並非所有更改的數據和索引頁都需要寫入磁碟。 在元數據更改(一般通過執行 DDL 語句產生的)之前。 日誌緩沖區已滿。DB2 以這種方法管理向磁碟寫入日誌數據的目的是盡可能地縮短處理延遲時間。在存在許多較小的並發事務的環境中,許多處理延遲是由 COMMIT 造成的,因為它必須等待日誌數據寫入磁碟後才能進行。因此,日誌處理器進程頻繁地將少量日誌數據寫入磁碟會造成大量處理延遲,另外一些延遲是由日誌 I/O 開銷造成的。監控我們進入 SAP 的 DBA Cockpit,然後在 Performance 的目錄下雙擊 Database, 在 Logging 的標簽內,可以看到當前資料庫日誌的狀況。圖8. 資料庫日誌狀況我們在圖中可以看到日誌文件以及日誌緩沖區的情況。包括日誌文件的數量,大小,資料庫使用的日誌空間以及可用日誌空間的大小。還可以看到日誌緩沖區的情況,當前日誌緩沖區的命中率為 100%。分析由於資料庫中的處理必須等待日誌數據寫入磁碟才能進行,日誌文件的讀寫速度對資料庫的響應速度也會產生很大影響。因此,應該把日誌文件放到速度比較快的磁碟上,以減少磁碟 I/O 開銷。日誌文件寫入的性能可以通過平均寫時間來觀察。另外,我們可以通過調整資料庫配置參數 LOGBUFSZ 來指定日誌緩沖區的大小。如果資料庫對於日誌磁碟有相當多的讀操作,或者希望有較高的磁碟利用率。一般來說,如果日誌緩沖區的命中率小於 98%,那麼可以增加這個緩沖區的大小以提高命中率。當增加這個參數的值時,也要考慮 DBHEAP 參數,日誌緩沖區使用的空間是 DBHEAP 參數所定義的內存空間的一部分。資料庫統計信息監控概念資料庫的統計信息反映了表及其相關索引的物理特點。統計信息主要包含: 表信息:表的行數,使用的數據頁,溢出的行數,列的平均長度,列的最大最小值等。 索引信息:索引條目的數量,索引所關聯列的不同值的數量,索引的層數等。這些信息被資料庫查詢優化器用來生成查詢計劃。好的訪問計劃對於 SQL 語句的快速執行至關重要。我們需要想辦法保證統計信息准確地反映了當前資料庫的狀況。由於資料庫的表和索引總是隨著資料庫處理各種更新請求而不斷發生變化的,因此,總會出現統計信息過時,而不能正確反映資料庫數據現狀的情況。這時,資料庫查詢優化器生成的查詢計劃可能不是最優的,這將大大影響資料庫的查詢性能。我們應該經常檢查資料庫的統計信息是否為最新的,並及時更新統計信息。SAP 系統為我們提供了監控和執行統計信息收集的方法。監控我們進入 SAP 的 DBA Cockpit,然後在 Performance 的目錄下雙擊 Tables, 在 Table 列表中雙擊要監控的表,在 Table 的標簽中,我們可以看到當前表的基本信息。這時,如果我們點擊 Count 按鈕,就會看到統計信息的質量。圖9. 表的統計信息狀況從圖中我們看到,表的當前行數為 27,Deviation 為 8%。分析如果我們監控到一個表的 Deviation 超過了 15%,我們就應該重新收集這個表的統計信息。在 SAP 中我們可以選擇手動收集統計信息。我們也可將系統配置成自動收集統計信息,這樣大大減少了系統手動維護的工作量。自動統計信息收集通常每隔 2 個小時觸發一次,它會自動選擇在 24 小時之內沒有收集過統計信息的持久的基表。如果 SAP 系統進行 Client Copy 或在 BI 表中載入大量數據,由於這些操作在短時間就可以改變表的數據狀況及分布,因此會導致統計信息的過時。在 DB2 V9.5 中,為了解決這個問題,提供了一種 RTS (Real Time Statistics) 的特性,該特性可以允許在查詢被處理並優化前對表的統計信息進行收集或采樣,如果優化器認為重新收集統計信息比用過時的統計信息進行查詢的速度快,那麼會在處理該查詢之前重新收集表的統計信息,從而達到實時收集統計信息的目的。我們一般需要將資料庫配置參數 AUTO_STMT_STATS 設為 ON 來開啟 RTS 特性,但在 SAP 系統中,RTS 已經是默認設置,我們無需進行任何改變。回頁首結束語本文從資料庫問題檢測的一般思路和方法論出發,介紹了如何通過 SAP 系統對 DB2 的性能進行監控。

㈣ DB2 UDB的DB2 UDB通用資料庫簡介

DB2是 IBM公司研製的一種關系型資料庫管理系統。UDB是Universal Database,即通用資料庫的簡稱。80年代初DB2的發展重點放在大型的主機平台上,從80年代中期到90年代初DB2已經發展到中型機、小型機以及微型機等多種平台上,它具有極強的伸縮性和擴充能力,資料庫的使用和管理也非常方便。 DB2 UDB 企業伺服器版隨 DWE 基本版和 DWE 企業版提供,DB2 UDB 工作組伺服器無限製版隨 DWE 標准版提供。

㈤ 如何用代理鍵實現 DB2 UDB 主鍵麻煩告訴我

2004 年 9 月 01 日如何將代理鍵(surrogate key)用作 DB2 UDB 中的主鍵?代理鍵是生成惟一序列號的一種有效方法。從本文中可以了解三種實現:傳統方法,使用鍵管理器,以及使用新的 DB2 UDB 特性。簡介使用代理鍵解決方案是為了發現一種生成惟一序列號的有效方法。本文描述了三種實現: 使用傳統方法。 使用鍵管理器。 使用DB2 UDB 特性。 代理鍵也叫 內鍵(internal key)。當創建一個表時,可以添加一個額外的列作為代理鍵。這個列應該是 NOT NULL,並且沒有商業意義。可以將該代理列指定為主鍵列。例如可以有一個數字代理列。代理鍵的值從某一個數字開始,例如 "1",以這個數字作為該列在表中第一行的值,之後的每一行中該列的值都按 1 遞增。 例如,如果我們有表 EMPLOYEE:CREATE TABLE EMPLOYEE ( FIRSTNAME CHAR(64), LASTNAME CHAR(64), SALARY DECIMAL(10, 2)) 那麼可以添加一個代理鍵列 SERIALNUMBER,並將其指定為主鍵列。這樣,這個表的定義就變為:CREATE TABLE EMPLOYEE ( SERIALNUMBER BIGINT NOT NULL, FIRSTNAME CHAR(64), LASTNAME CHAR(64), SALARY DECIMAL(10, 2), PRIMARY KEY (SERIALNUMBER)) 那麼,怎樣將惟一的值賦給每一行的 SERIALNUMBER 列呢?首先需要為代理鍵生成惟一的值。下面我將討論三種可行的解決方案。回頁首使用傳統方法解決方案的思想傳統方法是使用簡單的 SQL 或觸發器生成惟一的值。示例以表EMPLOYEE 為例。您可以在 INSERT 語句中實現代理鍵生成函數:INSERT INTO EMPLOYEE (SERIALNUMBER, FIRSTNAME, LASTNAME, SALARY) VALUES ((SELECT MAX(SERIALNUMBER) FROM EMPLOYEE)+1, 『John』, 『Smith』, 999.99) SQL 語句 " (SELECT MAX(SERIALNUMBER) FROM EMPLOYEE)+1 " 將找出最大的 SERIALNUMBER 並將其加 1,這樣新行就有一個惟一的 SERIALNUMBER。 這樣做存在的一個問題是,當將第一行插入表中時,可能會得到如下錯誤: SQL0407N Assignment of a NULL value to a NOT NULL. SQLSTATE=23502. 得到上述錯誤的原因是,當表為空時," SELECT MAX(SERIALNUMBER) FROM EMPLOYEE " 的返回為 NULL。因此,我們必須使用 COALESCE() 來處理這個問題: INSERT INTO EMPLOYEE (SERIALNUMBER, FIRSTNAME, LASTNAME, SALARY) VALUES (COALESCE((SELECT MAX(SERIALNUMBER) FROM EMPLOYEE), 0)+1, 『John』, 『Smith』, 999.99) 另一種傳統方法是使用觸發器來生成代理鍵: CREATE TRIGGER AUTOSURROGATEKEY NO CASCADE BEFORE INSERT ON EMPLOYEE REFERENCING NEW AS N FOR EACH ROW MODE DB2SQL BEGIN ATOMIC SET N.SERIALNUMBER = COALESCE((SELECT MAX(SERIALNUMBER) FROM EMPLOYEE), 0)+1; END 優點及問題傳統方法易於理解,而且容易在所有系統上實現。但是,這種實現實際上會導致事務處理系統中出現並發問題。因為該實現只允許一次執行一條 INSERT 操作。 因此,在獲得最大的 SERIALNUMBER 之前," SELECT MAX(SERIALNUMBER) FROM EMPLOYEE " 必須等待其他所有事務完成對表 EMPLOYEE 的 INSERT 或 UPDATE 操作。例如,如果有兩個事務正在對 EMPLOYEE 表進行 INSERT 操作,那麼其中有一個事務會被另一個事務阻塞。顯然,這種「逐次插入」的解決方案不適合多用戶的事務處理系統。 回頁首使用鍵管理器解決方案的思想很多大型的應用程序使用鍵管理器方法維護所有表的代理鍵。鍵管理器可以是一個助手類。每當需要向表插入一個行時,便可以調用鍵管理器生成新的鍵值,然後將獲得的鍵值插入新行。示例首先,需要創建表 KEYS 來記錄每個表的當前代理鍵值。鍵管理器類將使用該表生成新鍵值。CREATE TABLE KEYS ( TABLENAME CHAR(256), COLNUMNAME CHAR(256), SURROGATEKEYVALUE BIGINT, INCREMENT BIGINT, PRIMARY KEY(TABLENAME, COLNUMNAME)); 第二,將新表(例如表 EMPLOYEE)注冊到表 KEYS 中。INSERT INTO KEYS (TABLENAME, COLUMNNAME, SURROGATEKEYVALUE, INCREMENT) VALUES (『EMPLOYEE』, 『SERIALNUMBER』, 0, 1); 第三,編寫 KeyManger 類來維護每個已注冊表的代理鍵。KeyManager 將提供兩個方法:/** *Intialize the KeyManger */ KeyManager.singleton(); /** *Return the unique surrogate key value according to the input table *name and column name. */ KeyManager. GetSurrogateKey(String tableName, String columnName); 要查看更詳細的 KeyManger 的代碼,請參考附錄。 第四,調用 KeyManger 來獲得主鍵值: … KeyManager km = KeyManager.singleton(); Long surrogateKey = km.getSurrogateKey("EMPLOYEE", "SERIALNUMBER"); … 優點和問題顯然,鍵管理器是模塊化設計的一個很好的例子。鍵管理器封裝了代理鍵生成函數。這種實現也易於定製。您可以在 KEYS 表中為 SURROGATEKEYVALUE 或 INCREMENT 指定不同的值,以得到不同的代理鍵。而且,這種實現可以在大多數資料庫系統上實施。但是,為了進行維護,需要一個單獨的表和編寫代碼。所以,這種方法更適合於大型的跨資料庫系統。 回頁首使用DB2 UDB 特性DB2 UDB 提供了三種方法來生成惟一值。您可以使用這些方法來實現代理鍵。DB2 UDB Version 6.1 中的 GENERATE_UNIQUE() SQL 函數。 DB2 UDB Version 7.2 中 CREATE TABLE 語句的 IDENTITY 選項。 DB2 UDB Version 7.2 中的 SEQUENCE 對象。 GENERATE_UNIQUE()解決方案的思想GENERATE_UNIQUE() 最初是在 DB2 UDB Version 6.1 中提供的一個 SQL 函數。該函數返回當前系統時間戳。我們可以使用該函數為代理鍵列生成惟一值。示例CREATE TABLE EMPLOYEE ( SERIALNUMBER CHAR(13) FOR BIT DATA NOT NULL, FIRSTNAME CHAR(64), LASTNAME CHAR(64), SALARY DECIMAL(10, 2), PRIMARY KEY (SERIALNUMBER)) 然後可以用下面的 SQL 語句插入一行:INSERT INTO EMPLOYEE (SERIALNUMBER, FIRSTNAME, LASTNAME, SALARY) VALUES(GENERATE_UNIQUE(), 『John』, 『Smith』, 999.99) 優點和問題這里需要清楚兩件事情。首先,當多個事務在同一時刻插入行時,GENERATE_UNIQUE() 可能會返回相同的時間戳。在這種情況下,GENERATE_UNIQUE() 不能為每個事務生成一個惟一的返回值,因而這種方法不適合有大量事務的系統。第二,一旦系統時鍾需要向後調整,那麼 GENERATE_UNIQUE() 將可能返回重復的值。 由於上述限制,我決不會在生產系統中使用 GENERATE_UNIQUE()。但是,當您需要在有限的時間內完成一個原型時,這也許是一種選擇。 CREATE TABLE 語句中的 IDENTITY 選項解決方案的思想IDENTITY 是 DB2 UDB Version 7.1 和後期版本提供的 CREATE TABLE 語句中的一個選項。在創建表時,可以將某個列指定為 IDENTITY 列。對於每條 INSERT 語句,DB2 將負責為其中的這一列生成一個惟一的值。 示例CREATE TABLE EMPLOYEE ( SERIALNUMBER BIGINT NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1), FIRSTNAME CHAR(64), LASTNAME CHAR(64), SALARY DECIMAL(10, 2), PRIMARY KEY (SERIALNUMBER)) 然後可以用下面的語句插入一行: INSERT INTO EMPLOYEE (FIRSTNAME, LASTNAME, SALARY) VALUES ( 『John』, 『Smith』, 999.99) INSERT 語句不需要指定 SERIALNUMBER 列的值。DB2 UDB 將根據列的定義自動生成惟一值,即 "GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1)"。優點和問題IDENTITY 函數在大多數情況下是代理鍵函數的一個好的解決方案。DB2 import 和 export 實用程序也支持 IDENTITY 選項。然而,在某種情況下,這種解決方案不大方便。在運行 INSERT 語句之後,應用程序將永遠都不知道放入了主鍵列中的是什麼值。如果應用程序必須繼續向子表插入一個行,那麼它就不得不對父表運行一條 SELECT 語句,以得到主鍵值。不過,如果這一點對於您的系統不成問題的話,那麼使用 IDENTITY 選項是一個好主意。 SEQUENCE 對象解決方案的思想SEQUENCE 對象是在 DB2 UDB Version 7.2 中引入的一個特性。用戶可以在資料庫中創建一個 SEQUENCE 對象,就像創建表對象或視圖對象一樣,然後從 SEQUENCE 中請求值。DB2 保證用戶每次可以得到一個惟一的序列值。 示例您可以在資料庫中創建一個 SEQUENCE 對象:CREATE SEQUENCE EMPSERIAL AS BIGINT START WITH 1 INCREMENT BY 1 如果有一個如下所示的 EMPLOYEE 表: CREATE TABLE EMPLOYEE ( SERIALNUMBER BIGINT NOT NULL, FIRSTNAME CHAR(64), LASTNAME CHAR(64), SALARY DECIMAL(10, 2), PRIMARY KEY (SERIALNUMBER)) 那麼可以用下面的語句插入一個行: INSERT INTO EMPLOYEE ( SERIALNUMBER, FIRSTNAME, LASTNAME, SALARY) VALUES(NEXTVAL FOR EMPSERIAL, 'John', 'Smith', 99.99) 在這里使用 " NEXTVAL FOR EMPSERIAL " 從 SEQUENCE 中獲得惟一值。 您可以使用 " PREVVAL FOR EMPSERIAL " 獲得當前連接會話中最近生成的序列值。應用程序就可以知道放入主鍵列中的是什麼值,從而繼續向子表插入一個行。這里,「在當前連接會話中」這一點很重要,這意味著 "PREVVAL" 將只返回在相同連接會話中生成的值。 例如,考慮這樣的情況:有兩個應用程序連接到資料庫,並按照如下順序運行下面的 SQL 語句。 (假設 SEQUENCE " EMPSERIAL " 的當前值是 3)。 應用程序 1:
INSERT INTO EMPLOYEE ( SERIALNUMBER, FIRSTNAME, LASTNAME, SALARY) VALUES(NEXTVAL FOR EMPSERIAL, 'Martin', 'Wong', 1000.00)從EMPSERIAL 生成的 " NEXTVAL " 是 4。 應用程序 2:
INSERT INTO EMPLOYEE ( SERIALNUMBER, FIRSTNAME, LASTNAME, SALARY) VALUES(NEXTVAL FOR EMPSERIAL, 'Patrick', 'Chan', 99.99) 從EMPSERIAL 生成的 " NEXTVAL " 是 5。 應用程序 1:
SELECT PREVVAL FOR EMPSERIAL FROM EMPLOYEE " PREVVAL " 將返回 4,而不是 5。 而且, PREVVAL 和NEXTVAL 的值不會受事務回滾的影響。 例如,假設 SEQUENCE " EMPSERIAL " 的當前值是 30。某個應用程序開始了一個事務: INSERT INTO EMPLOYEE ( SERIALNUMBER, FIRSTNAME, LASTNAME, SALARY) VALUES(NEXTVAL FOR EMPSERIAL, 'William', 'Chen', 99.99) 執行ROLLBACK 操作。 然後,如果運行: SELECT PREVVAL FOR EMPSERIAL FROM EMPLOYEE 則" PREVVAL " 將返回 31,而不是 30。 優點和問題SEQUENCE 是最近 DB2 UDB 為生成惟一值而實現的函數。它還有一個緩存函數,用於提高性能(要了解詳細信息,請參閱 IBM DB2 UDB SQL Reference)。該函數比 IDENTITY 函數更靈活,因為它是資料庫中的一個獨立對象。必要時候,可以通過運行 ALTER SEQUENCE 語句更改其設置。 如果系統只在 DB2 UDB 上運行,那麼 SEQUENCE 也許是最好的解決方案,因為它易於使用,而且不像鍵管理器那樣需要額外的代碼,並且可以隨需求的變化很輕易對其進行更改。回頁首結束語本文描述了實現作為主鍵的代理鍵的三種方法。文中主要討論了如何為代理鍵生成惟一的序列值。傳統方法適合於簡單的、單用戶(非並發)系統。對於實現對於大型系統和跨平台系統,鍵管理器是一個好選擇。