轉載 關於資料庫表的主鍵和業務系統中流水號的一點探討

lhyvsxman發表於2009-03-18

原文:http://www.itpub.net/thread-1133732-1-1.html

一、背景從事軟體行業這些年來,我在一些軟體專案的資料庫表設計中,使用了幾種資料表主鍵方式:資料庫自動增量方式,GUID方式,主鍵流水號方式。
這裡對各種方式進行一個簡單的比較和建議。
二、業務術語2.1.資料表欄位自動增量方式資料表的主鍵欄位,使用自動增量方式,由資料庫維護其值。當使用者插入記錄到資料庫表時,使用者並不需要為自動增量欄位指定一個值,資料庫內部為自動為該欄位賦予一個值。
資料庫表的主鍵欄位如果是自動增量,一般都是數字型(整數)。
2.2.GUID/UUID式的主鍵欄位使用社會公開的演算法,產生GUID/UUID一個全球唯一的字串作為資料表欄位。當使用者插入記錄到資料庫表時,使用公開的演算法產生一個GUID/UUID,並儲存到資料庫中。
2.3.主鍵流水號在常用的軟體系統中,也常遇到使用一個資料庫表來維護各個資料庫表的主鍵值使用情。
在實際使用時,使用者呼叫一定的介面,比如:傳入資料庫表名稱,欄位名稱,軟體系統的主鍵介面程式為使用者返回一個主鍵流水號。
一般來說,主鍵流水號的資料型別是整數型別。
三、各種主鍵策略的比較

評價引數

自動增量方式

GUID方式

流水號式

資料插入成本

最好

較差

較差

資料查詢成本

較好

較差

較好

主鍵欄位排序方便性

較好

較差

較好

系統資料遷移唯一性

較差

最好

較差

iBatis跨資料庫方面

較差

最好

較好

hibernate跨資料庫方面

較好

最好

較好

多系統資料交換方面

較差

最好

較好



四、主鍵策略分析各種主鍵策略的優劣,見上表,我在這裡再給出進一步的分析。
4.1.自動增量方式如果不考慮資料遷移,資料交換,跨資料庫對建設的特定系統影響,使用自動增量作為主鍵是個不錯的選擇。
如果系統中既有iBatis,又有Hibernate作為持久化方案,建議選擇其他方案。
4.2.GUID/UUID作為主鍵使用GUID,UUID作為主鍵策略,資料插入時候,耗費的成本可能是上面三種方案較差的。當然對於傳統管理資訊系統,這個問題也許並不嚴重。
該種策略還可能遇到一個困惑:如果在一個資料庫表插入記錄一條記錄後,想要把最近插入的資料顯示在前面,可能有點麻煩,因為該資料庫表很可能沒有相應的時間或者欄位供排序使用,使用該主鍵欄位來排序也不行。
4.2.1.變種型的GUID/UUID為了滿足在使用GUID策略作為主鍵欄位的排序時候需要,我在這裡提出變種的GUID策略。
具體操作方式,使用公開的演算法生成一個GUID後,再進一步包裝下(借用了設計模式中GOF的裝飾者模式的思想),使用一個字串化的日期作為GUID的字首。例如:
lGuid:
0ad09547-1b14-4aab-b74d-39e7a42e39e0

l增加時間戳的GUID: 20081028172124640-0ad09547-1b14-4aab-b74d-39e7a42e39e0

l時間轉換成為字元規則:
年月日時分秒毫秒+GUID
4.2.2.帶資料來源的變種GUID/UUID在這裡我們就前面的思路再發散下,其實我們可以在主鍵上在賦予一定的資料業務意義。
我們可以在前面的變種GUID的基礎上,再增加一個資料來源標識號。比如:
A001-20081028172124640-0ad09547-1b14-4aab-b74d-39e7a42e39e0
其中A001是表達了我們電話號碼中的區號的作用。一看該號碼就知道資料來自於哪裡。
這種策略在一個系統在客戶的多個分支機構中部署比較有用,如果到時候這些資料彙總在一起,資料不會重複,而且也知道資料來自於那個地方,方便進一步的資料處理和資料交換。
4.3.主鍵流水號使用主鍵流水號策略來給系統各個資料庫表分配主鍵值,這種策略在一個軟體公司建設行業產品時比較經常見到。
4.3.1.弊端:介面程式每次在使用者申請主鍵時候,從主鍵流水錶獲得一個最新主鍵值給使用者。這樣認為的為系統併發性方面設定了一個瓶頸。
4.3.2.帶快取的主鍵流水號針對前面的這種主鍵流水號策略,提出主鍵快取來彌補併發性的不足。
主鍵介面程式為每個表的主鍵值做一個快取,當使用者來獲取主鍵市,介面程式從快取中分配一個主鍵給使用者,當指定資料表快取的主鍵分配完或者要分配完時,主鍵介面程式從資料庫重新獲得一批主鍵快取起來以備使用者使用。
例子:
l主鍵介面程式SEQService,入口引數是資料表名稱,欄位名稱,返回結果是一個整數。
l使用者申請Book表的ID欄位的主鍵
l主鍵介面程式SEQService使用懶漢載入模式,查詢主鍵快取去是否有該表的主鍵快取資料;
l主鍵快取區中沒有Book表的ID欄位的主鍵的快取資料,主鍵介面程式從資料庫中申請一批主鍵(假設為獲取數量100,主鍵可用值為10011100開始),同時更新主鍵流水錶的當前使用值。
l主鍵介面程式分配分配一個主鍵值(1001)給使用者使用,更新主鍵快取資訊(當前可用主鍵值為1002,最大可用值為1100)。
這種帶快取的主鍵流水號策略,可以用於叢集部署環境,同樣有效。
這種快取策略實際上可吧主鍵快取看成是記憶體快取,資料庫是硬碟儲存。
4.3.3.業務流水號!=主鍵流水號在實際業務中,可能面臨公文流水號也是採用連續號碼的情況,公文的流水號是採用:字首+公文流水+字尾組成。
實際上這個公文流水號充當的是“務系統邏輯主鍵“,並不是物理主鍵,為了保證該號碼的連續性,需要在上面快取的主鍵流水號基礎上做個變通,介面程式不再採用前面的寫回策略(先訪問主鍵快取,不滿足要求,訪問資料庫),而是採用寫通的策略,介面策略直接訪問主鍵流水錶,然後分配一個主鍵給使用者。
4.3.4.變種的帶步長的主鍵流水號帶步長的主鍵是:系統分配給使用者的主鍵值不是連續的,是有一定步長的。比如:系統主鍵開始值為1,補償為10;拿第一個使用者拿到的主鍵值為1,第二個使用者拿到的是11
l好處:
這種策略可用於系統在總部、多公司部署,同時滿足資料交換和資料整合要求。
例如:
公司甲總部的主鍵策略是,使用資料庫表的主鍵開始值為1000,主鍵步長是10;公司甲的上海分公司的主鍵開始值為1001主鍵步長是10;公司甲的東京分公司的主鍵開始值為1002鍵步長是10;公司甲的紐約分公司的主鍵開始值為1003鍵步長是10
根據公司甲的要求,可以在任何時候把總部和各個分公司的資料進行合併,卻能保證資料不會衝突。這就是主鍵流水錶的開始值不一樣補償一樣的功勞。
l不足:
如果系統在部署的時候,估計不足,步長設計過小,比如:上面例子中設計為10,當有第11個分公司冒出來需要部署系統時,這時候步長就不夠用了。
變通的方式,可採用前面的變種GUID作為主鍵,或者一開始就把系統主鍵值的補償設計大一點,比如:50或者100
五、系統中的各種業務流水號業務流水號是屬於業務模型中的內容,系統資料主鍵流水號是系統模型中的內容。這兩者既相互獨立,也有一定關係。

[@more@]

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12180666/viewspace-1018941/,如需轉載,請註明出處,否則將追究法律責任。

相關文章