色尼玛亚洲综合影院,亚洲3atv精品一区二区三区,麻豆freexxxx性91精品,欧美在线91

小議數(shù)據(jù)庫主鍵選取策略(原創(chuàng))

我們在建立數(shù)據(jù)庫的時(shí)候,需要為每張表指定一個(gè)主鍵,所謂主鍵就是能夠唯一標(biāo)識表中某一行的屬性或?qū)傩越M,一個(gè)表只能有一個(gè)主鍵,但可以有多個(gè)候選索引。因?yàn)橹麈I可以唯一標(biāo)識某一行記錄,所以可以確保執(zhí)行數(shù)據(jù)更新、刪除的時(shí)候不會出現(xiàn)張冠李戴的錯誤。當(dāng)然,其它字段可以輔助我們在執(zhí)行這些操作時(shí)消除共享沖突,不過就不在這里討論了。主鍵除了上述作用外,常常與外鍵構(gòu)成參照完整性約束,防止出現(xiàn)數(shù)據(jù)不一致。所以數(shù)據(jù)庫在設(shè)計(jì)時(shí),主鍵起到了很重要的作用。

常見的數(shù)據(jù)庫主鍵選取方式有:

  • 自動增長字段
  • 手動增長字段
  • UniqueIdentifier
  • “COMB(Combine)”類型

一、自動增長型字段

很多數(shù)據(jù)庫設(shè)計(jì)者喜歡使用自動增長型字段,因?yàn)樗褂煤唵巍W詣釉鲩L型字段允許我們在向數(shù)據(jù)庫添加數(shù)據(jù)時(shí),不考慮主鍵的取值,記錄插入后,數(shù)據(jù)庫系統(tǒng)會自動為其分配一個(gè)值,確保絕對不會出現(xiàn)重復(fù)。如果使用SQL Server數(shù)據(jù)庫的話,我們還可以在記錄插入后使用@@IDENTITY全局變量獲取系統(tǒng)分配的主鍵鍵值。

盡管自動增長型字段會省掉我們很多繁瑣的工作,但使用它也存在潛在的問題,那就是在數(shù)據(jù)緩沖模式下,很難預(yù)先填寫主鍵與外鍵的值。假設(shè)有兩張表:

Order(OrderID, OrderDate)
OrderDetial(OrderID, LineNum, ProductID, Price)

Order表中的OrderID是自動增長型的字段。現(xiàn)在需要我們錄入一張訂單,包括在Order表中插入一條記錄以及在OrderDetail表中插入若干條記錄。因?yàn)镺rder表中的OrderID是自動增長型的字段,那么我們在記錄正式插入到數(shù)據(jù)庫之前無法事先得知它的取值,只有在更新后才能知道數(shù)據(jù)庫為它分配的是什么值。這會造成以下矛盾發(fā)生:

首先,為了能在OrderDetail的OrderID字段中添入正確的值,必須先更新Order表以獲取到系統(tǒng)為其分配的OrderID值,然后再用這個(gè)OrderID填充OrderDetail表。最后更新OderDetail表。但是,為了確保數(shù)據(jù)的一致性,Order與OrderDetail在更新時(shí)必須在事務(wù)保護(hù)下同時(shí)進(jìn)行,即確保兩表同時(shí)更行成功。顯然它們是相互矛盾的。(此處表述有錯誤。呂震宇 2005-6-15)

【補(bǔ)充2005-6-15】---------------------------------------------

聽棠.NET指出:主檔放在事務(wù)中提交時(shí),通過@@IDENTITY 就可以取到生成值的,因此可以傳給明細(xì)當(dāng)外鍵用,而且在事務(wù)發(fā)生錯誤回滾時(shí),主檔記錄也會被回滾取消的。

呂震宇補(bǔ)充:使用自動增長字段會增加網(wǎng)絡(luò)的roundTrip。盡管可以使用@@IDENTITY取得主鍵的值,但在更新過程中,不得不增加一次數(shù)據(jù)往返(以C/S結(jié)構(gòu)為例):

1、客戶端發(fā)送開始事務(wù)命令
2、客戶端提交主表更新
3、服務(wù)器返回@@IDENTITY
4、客戶端根據(jù)返回的主鍵更新從表緩沖
5、客戶端將從表提交服務(wù)器更新
6、客戶端提交事務(wù)

在這里多了一次往返就會增加了事務(wù)處理的時(shí)間。降低并發(fā)性能。

如果不用自動增長型字段,將是以下情景:

1、客戶端發(fā)送開始事務(wù)命令
2、客戶端提交主表更新
3、客戶端提交從表更新
4、客戶端提交事務(wù)

因此我不贊成使用自動增長型字段作為主鍵與外鍵鏈接的紐帶。

------------------------------------------------

除此之外,當(dāng)我們需要在多個(gè)數(shù)據(jù)庫間進(jìn)行數(shù)據(jù)的復(fù)制時(shí)(SQL Server的數(shù)據(jù)分發(fā)、訂閱機(jī)制允許我們進(jìn)行庫間的數(shù)據(jù)復(fù)制操作),自動增長型字段可能造成數(shù)據(jù)合并時(shí)的主鍵沖突。設(shè)想一個(gè)數(shù)據(jù)庫中的Order表向另一個(gè)庫中的Order表復(fù)制數(shù)據(jù)庫時(shí),OrderID到底該不該自動增長呢?

ADO.NET允許我們在DataSet中將某一個(gè)字段設(shè)置為自動增長型字段,但千萬記住,這個(gè)自動增長字段僅僅是個(gè)占位符而已,當(dāng)數(shù)據(jù)庫進(jìn)行更新時(shí),數(shù)據(jù)庫生成的值會自動取代ADO.NET分配的值。所以為了防止用戶產(chǎn)生誤解,建議大家將ADO.NET中的自動增長初始值以及增量都設(shè)置成-1。此外,在ADO.NET中,我們可以為兩張表建立DataRelation,這樣存在級聯(lián)關(guān)系的兩張表更新時(shí),一張表更新后另外一張表對應(yīng)鍵的值也會自動發(fā)生變化,這會大大減少了我們對存在級聯(lián)關(guān)系的兩表間更新時(shí)自動增長型字段帶來的麻煩。

二、手動增長型字段

既然自動增長型字段會帶來如此的麻煩,我們不妨考慮使用手動增長型的字段,也就是說主鍵的值需要自己維護(hù),通常情況下需要建立一張單獨(dú)的表存儲當(dāng)前主鍵鍵值。還用上面的例子來說,這次我們新建一張表叫IntKey,包含兩個(gè)字段,KeyName以及KeyValue。就像一個(gè)HashTable,給一個(gè)KeyName,就可以知道目前的KeyValue是什么,然后手工實(shí)現(xiàn)鍵值數(shù)據(jù)遞增。在SQL Server中可以編寫這樣一個(gè)存儲過程,讓取鍵值的過程自動進(jìn)行。代碼如下:

 

CREATE PROCEDURE [GetKey]

@KeyName 
char(10), 
@KeyValue 
int OUTPUT 

AS
UPDATE IntKey SET @KeyValue = KeyValue = KeyValue + 1 WHERE KeyName = @KeyName
GO

it知識庫小議數(shù)據(jù)庫主鍵選取策略(原創(chuàng)),轉(zhuǎn)載需保留來源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 甘孜县| 白河县| 泰顺县| 习水县| 平山县| 龙川县| 呼图壁县| 银川市| 搜索| 洪湖市| 乌兰浩特市| 惠东县| 镇宁| 土默特右旗| 芦溪县| 金平| 中卫市| 金溪县| 雷山县| 和龙市| 濉溪县| 丽江市| 县级市| 通辽市| 侯马市| 平顶山市| 晋州市| 江源县| 诸暨市| 平潭县| 阳山县| 桃园市| 长宁区| 霍邱县| 密山市| 大城县| 江津市| 徐汇区| 出国| 屏南县| 繁峙县|