DB2序列 自增列 解決之Sequence 物件

2022-03-12 18:05:54 字數 3848 閱讀 7601

**:

我的上兩個專欄中已經介紹到了與版本 8 功能相關的主題。我們可能需要在今天設計的資料庫和應用程式中考慮這些功能。我們已經談論了新的資料分割槽的輔助索引和附加的索引修改。在上一期中,我們了解了 dssize 如何可以影響今後的分割槽策略。現在,我想要簡要地來介紹一下 sequence 物件以及如何用它們來代替 identity 列。我們還將介紹版本 8 中一些用以使用 identity 列的新功能。

數字生成問題

過去的許多應用程式都需要能夠生成序號(例如獲取下乙個可用的帳號)。問題是該工作通常是通過用單個控制表儲存這些數字,然後用可重複讀(repeatable read)的 select max 在隨後的 insert 中檢索並使用該數字來完成的。常常有多個事務需要使用該錶,而這就導致了應用程式中無法解決的單點競爭。這是由於每次只有乙個事務可以檢索下一值,因為事務必須鎖定該錶以使數字增量。請參閱圖 1。

在過去多年中曾經嘗試過許多創造性的解決方案,例如使用行級的鎖定,但是這些技術產生的系統開銷加上成千上萬個併發事務間的衝突仍然會導致效能瓶頸。如果用於資料共享的環境中,其中將有多個成員使用該錶,那麼它也會導致單點故障並且產生巨大的鎖定開銷。

identity 列

因而在較晚的版本 6 中就出現了 identity 列,用以解決前面提到的問題。如果乙個表指派了 identity 列,那麼當向該錶插入一行時,將根據 identity 列的定義(start with 和 increment by 值)來填充它。雖然使用 identity 列要遠勝於使用單個控制表,但是 identity 列在使用方面卻非常有限並且存在管理問題。

在版本 8 之前,identity 列還帶來了一些問題,例如:

這還僅僅只是一部分問題。許多公司圍繞這些問題開發了一種方法,他們從表中刪除 identity 列然後建立乙個只含 identity 列及其生成值的表。因此,上述問題,例如重新開始 identity 列的值或填充 ri 有關的表,都可以通過使 identity 列與表分離而得到解決。該技術仍然允許由 db2 來填充 identity 列的值,並且減少了許多限制。但還是必須要對該錶進行填充、訪問和維護,並且它無法解決 identity 列的所有問題以及無法完全開發與由 db2 執行數字生成相關的潛在效能。圖 2 是乙個展示如何使用該技術的例子。

版本 8 已經緩解了上述 identity 列的部分問題,例如使用 select 功能中的新的 insert 進行插入之前可以獲得 identity 列的值。下面這個例子展示了如何在插入時使用該功能來獲取 identity 列的值。

(假定所建立的表以自動生成的 acct_id 為 identity 列)

例 1

select acct_id  

from final table  

(insert into uid1.account (name, type, balance)  

values ('master card', 'credit', 50000) )

版本 8 中還可以更改其他一些值,例如:  

cache/no cache

cycle/no cycle  

minvalue  

maxvalue  

increment by  

restart with

這些執行更改的功能,特別是 restart with,給 identity 列的使用帶來了更大的靈活性。然而,這些功能是定義在單個表上的,這一本質使它們仍然受到了一些限制,而且應用程式對它們的利用也仍然有限。此外,這些更改還將導致表空間被置於 reorg 暫掛狀態,從而導致表無法獲得表空間。

sequence 物件

在首次宣布 sequence 物件時,我認為它們只是為了將應用程式從其他資料庫移植到 db2 而向 db2 新增的另一功能。但是我越是深入地研究它們,就越是開始喜歡這些新的物件了,因為它們消除了我們對於 identity 列的許多限制,而且它們還具有許多獨特且有用的功能。它還向我們提供了數字生成的另一備選方法。

sequence 物件是使用者定義的物件,用以根據其建立規範生成數值串行。 它們提供乙個由 db2 生成的增量計數器,並且與 identity 列十分相似。可將 identity 列當作一種特殊的 sequence 物件;但是,sequence 列與表是分開的。

sequence 物件值可因為各種理由而用於應用程式中。這樣做有一些好處,例如:

序列名由兩部分組成:128 位元組的模式名和 128 位元組的識別符號。它們是通過新的 create sequence 語句建立的,並且其所有屬性完全都是由使用者定義的(您也可以使用預設值)。sequence 物件中的值可以是任何數字資料型別。初值是用 start with 值定義的,而增量則是由 increment by(遞增的或遞減的)定義的。可以快取這些值或按請求次序來生成。

下面這個例子展示了乙個 sequence 物件的建立及其簡單用法。  

create sequence account_seq

as integer  

start with 1  

increment by 10  

cycle  

cache 20

正如您所看到的,sequence 物件的使用方法與許多人對於 identity 列的使用比較相似。但是這更為有效,而且 sequence 物件有一些極佳的使用優點。例如可以使用 next value for 和 previous value for。nextvalue for 將為 sequence 物件生成並返回下一值。而 previous value for 將為 sequence 物件生成並返回前一值。這些語句可用於下列地方:

下面的例子(右邊的表 2)展示了這些語句的用法:  

假定 acct_seq 為 start with 10 increment by 10

正如您所看到的,使用 sequence 物件代替 identity 列有許多好處。下面是兩者的乙個簡單比較。  

sequence 物件與 identity 列

sequence 物件

identity 列(帶有 v8 功能)

單獨的 sequence 物件是在使用者請求時建立的

由 db2 生成/維護和填充的內部 sequence 物件

可用於它們所選擇的任何目的,並且存在有多個

與特定的表相關聯,並且只能有乙個

迴圈(cycle)將迴繞和重複,並且無需進行惟一性考慮

如果惟一索引在 identity 列上並且建立了複製,那麼迴圈(cycle)可能會產生問題

當用於填充表時,後來可被更新

如果是 generated always,就無法被更新

可以更改(alter)sequence 物件的屬性。  

還可以進行注釋(comment)以及授予/撤銷(grant/revoke)許可權

只能更改表(alter table)(如果向已填充的表新增 identity 列,將被置於 reorg 暫掛狀態)

可被刪除

不能從表中刪除*

支援 next value for expression 和 previous value for expression

必須使用 id_val_local 並且只返回使用者提交(commit)範圍內的最後值

*  如果今後設計中使用 sequence 物件比使用 identity 列更好,那麼在選擇 identity 列時就要考慮仔細。如果它們是在已填充的表上定義的並且需要被刪除,那麼必須刪除表然後重新建立。這對於高效環境中的大型表可能是乙個大問題。

結束語identity 列和 sequence 物件在我們的設計中都占有一席之地。鑑於它們都可以達到相同的目的 —— 生成序號,所以應該由您來選擇哪乙個更適合您。這將取決於您對生成的數字所需的靈活性,以及應用程式將如何使用這些數字。

db2序列不能查詢值

最近在用db2資料庫的串行使表自增時出現了問題。首先,建立序列 create sequence student seq start with 1 increment by 2 nomaxvalue cache 20 nocycle 然後,試著查序列的值,卻出現了問題,查詢語句 select next...

DB2行列轉換

在db2資料庫中常用函式講db2行列轉換 select column1,replace replace xml2clob xmlagg xmlelement name a,column2 as name1 form tablename where 1 0 group by column1 將不需要行...

DB2行轉列(多維度)

多維度下進行行列轉換,下面的行列轉換時根據客戶,所屬銀行機構進行的行列轉換。建表 create table cust bank info cust id varchar 10 cust name varchar 100 bank no varchar 100 bank varchar 100 mon...