程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> SqlServer數據庫 >> 關於SqlServer >> SQL Server表的主鍵設計應注意的問題.

SQL Server表的主鍵設計應注意的問題.

編輯:關於SqlServer

     關於數據庫的邏輯設計,是一個很廣泛的問題。本文主要針對開發應用中遇到在MS SQL Server上進行表設計時,對表的主鍵設計應注意的問題以及相應的解決辦法。

主鍵設計現狀和問題

關於數據庫表的主鍵設計,一般而言,是根據業務需求情況,以業務邏輯為基礎,形成主鍵。

比如,銷售時要記錄銷售情況,一般需要兩個表,一個是銷售單的概要描述,記錄諸如銷售單號、總金額一類的情況,另外一個表記錄每種商品的數量和金額。對於第一個表(主表),通常我們以單據號為主鍵;對於商品銷售的明細表(從表),我們就需要將主表的單據號也放入到商品的明細表中,使其關聯起來形成主從關系。同時該單據號與商品的編碼一起,形成明細表的聯合主鍵。這只是一般情況,我們稍微將這個問題延伸一下:假如在明細中,我們每種商品又可能以不同的價格方式銷售。有部分按折扣價格銷售,有部分按正常價格銷售。要記錄這些情況,那麼我們就需要第三個表。而這第三個表的主鍵就需要第一個表的單據號以及第二個表的商品號再加上自身需要的信息一起構成聯合主鍵;又或者其他情況,在第一個主表中,本身就是以聯合方式構成聯合主鍵,那麼也需要在從表中將主表的多個字段添加進來聯合在一起形成自己的主鍵。

數據冗余存儲:隨著這種主從關系的延伸,數據庫中需要重復存儲的數據將變得越來越龐大。或者當主表本身就是聯合主鍵時,就必須在從表中將所有的字段重新存儲一次。

SQL復雜度增加:當存在多個字段的聯合主鍵時,我們需要將主表的多個字段與子表的多個字段關聯以獲取滿足某些條件的所有詳細情況記錄。

程序復雜度增加:可能需要傳遞多個參數。

效率降低:數據庫系統需要判斷更多的條件,SQL語句長度增加。同時,聯合主鍵自動生成聯合索引

WEB分頁困難:由於是聯合主鍵方式(對於多數的子表),那麼在WEB頁面上要進行分頁處理時,在自關聯時,難於處理。

解決方案

從上面,我們已經看到現有結構存在著相當多的弊端,主要是導致程序復雜、效率降低並且不利於分頁。

為解決上述問題,本文提出:當應用系統後台數據庫表間存在主從關系時,數據庫表額外增加一非業務字段作為主鍵,該字段為數值型;或者當該表需要在應用中進行分頁查詢時,也應考慮如此設計。一般地,我們也可以幾乎為任何表增加一個與業務邏輯無關的字段作為該表的主鍵字段。

由於該字段要作為表的主鍵,那麼其首要條件是要保證在該表中要具有唯一性。同時,結合SQL Server數據庫自身的特性,可以為其建立一個自增列:

create TABLE T_PK_DEMO
(
U_ID  BIGINT NOT NULL IDENTITY(1,1),
–唯一標識記錄的ID
COL_OTHER VARchar(20) NOT NULL ,
–其他列
CONSTRAINT PK_T_PK_DEMO PRIMARY KEY NONCLUSTERED
(U_ID)–定義為主鍵
)
 


但是,SQL Server中的自增列卻存在一個比較尴尬的事實,那就是該字段一旦定義和使用,用戶無法直接干預該字段的值,完全由數據庫系統自身控制:

完全數據庫系統控制,用戶無法修改值

在數據庫的發布和訂閱時,使用自增列會比較麻煩

恢復部分數據時,使用自增列會比較麻煩

該列的值必須在插入數據後才能獲取

鑒於此,建議不以自增列的方式來定義,而是參考Oracle數據庫系統中序列,在SQL Server系統中實現類似Oracle數據庫系統序列功能。這個具體在下面的小節中介紹。我們只需要按照普通字段的定義方式修改表定義為:

create TABLE T_PK_DEMO
(
U_ID  BIGINT NOT NULL ,–唯一標識記錄的ID
COL_OTHER VARchar(20) NOT NULL ,–其他列
CONSTRAINT PK_T_PK_DEMO PRIMARY KEY NONCLUSTERED (U_ID)–定義為主鍵
)

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved