2008-11-17 44 views
3

我在SQL 2008服務器中有幾個表,我需要爲其生成唯一的ID。我已經查看了「身份」列,但ID確實需要是唯一的,並在所有表格之間共享。因此,如果我有5個表「風格資產基礎設施」的表格,並且我想用它們之間的唯一ID作爲一個組合組運行,我需要某種類型的生成器來查看所有(5)五張桌子,併發行下一個身份證,這個身份證在這五(5)個故事中沒有重複。生成唯一的ID以與多個表共享SQL 2008

我知道這可以用某種存儲過程來完成,但我不知道如何去做。有任何想法嗎?

+0

@Jonathan你似乎正在修復我所有的錯別字:)乾杯。 – 2008-11-17 05:33:53

回答

4

爲什麼不使用GUID?

+0

由於guid不是用戶友好的單一原因,這一點通常是爲用戶提供一個他們可以記住的短序列,並用於快速訪問實體。 – 2009-04-30 06:47:32

4

你可以讓他們每個人都有一個身份,這個身份的種子數量足夠遠,永遠不會相互碰撞。

GUID可以工作,但它們很醜陋,而且如果這很重要,它們就是非連續的。

另一種常見技術是使用一個標識爲每列插入記錄時分配下一個值的單列表。如果你需要從一個普通的序列中抽取它們,那麼有第二個列指出它被分配到哪個表是不太可能的。

你意識到有這樣的邏輯設計問題,對吧?

+0

將ID /身份作爲查詢字符串參數傳遞是非常常見的,如果該ID是唯一的,則不能在該域的外部使用該ID,即表/上下文。這也比你想象的要聰明得多。 – 2009-04-30 06:45:18

+0

只是一小點,但自SQL2005以來,您可以創建順序的GUID。 – BlackWasp 2009-05-31 18:26:55

4

讀入一個位,這聽起來像你真正需要的是所謂的「資產」與標識列一個表,然後設計之一:

一)5資產的亞型附加表,每個都帶有一個外鍵給Asset上的主鍵;或

b)資產上的5個視圖,每個視圖選擇行的一個子集,然後對用戶顯示,就像現在的5個原始表一樣。

如果表中的列全部相同,(b)是更好的選擇;如果它們完全不同,(a)是更好的選擇。這是超類型/子類型關係的典型數據庫旋轉。

或者,你可以做你正在談論的事情,並用存儲過程自己重新創建IDENTITY功能,該存儲過程包裝所有5個表的INSERT訪問權限。請注意,如果您希望保證唯一性,則必須在其中放置TRANSACTION,並且如果這是一個受歡迎的表,那可能會使其成爲性能瓶頸。如果這不是一個問題,這樣的一個進程可能採取的形式:

CREATE PROCEDURE InsertAsset_Table1 (
    BEGIN TRANSACTION 
    -- SELECT MIN INTEGER NOT ALREADY USED IN ANY OF THE FIVE TABLES 
    -- INSERT INTO Table1 WITH THAT ID 
    COMMIT TRANSACTION -- or roll back on error, etc. 
) 

此外,SQL是高度幫助你出去了優化,如果你選擇我上面提到的方式,而不能用於這種事情優化(在創建事務時會有開銷,並且在進行此過程時您將在所有5個表上發佈共享鎖)。與使用上面的PK/FK方法比較,SQL Server確切地知道如何在沒有鎖的情況下或者只在1個表中插入視圖方法。

0

我在谷歌搜索時發現了這個。我第一次面臨類似的問題。我有想法有專門的ID表來生成ID,但我不確定它是否被認爲是OK設計。所以我只想說感謝確認..它看起來是一個足夠的溶劑,雖然不理想。

5

最簡單的解決方案是在每張桌子上設置您的身份種子和增量,以免它們重疊。 表1:種子1,遞增5 表2:種子2,增量5 表3:種子3,增量5 表4:種子4,增量5 表5:種子5,增量5

的身份列模塊5會告訴您該記錄位於哪個表中。您將快速使用您的身份空間五倍,因此請確保數據類型足夠大。

0

我有一個非常簡單的解決方案。它應該是很好的情況下,當表的數量少:

create table T1(ID int primary key identity(1,2), rownum varchar(64)) 

create table T2(ID int primary key identity(2,2), rownum varchar(64)) 

insert into T1(rownum) values('row 1') 
insert into T1(rownum) values('row 2') 
insert into T1(rownum) values('row 3') 

insert into T2(rownum) values('row 1') 
insert into T2(rownum) values('row 2') 
insert into T2(rownum) values('row 3') 

select * from T1 

select * from T2 

drop table T1 
drop table T2 
0

使用一桌子的人(稱爲人稱單數,請)和每個人進行分類,例如醫生時,例如,這是一個普遍的問題,患者,僱員,護士等

爲每個這些人創建一張表,包含他們的特定類別信息(如員工開始日期和工資以及護士資格和數量)是很有意義的。

A例如,患者可能有許多護士和醫生在他身上工作,因此在PERSON表中將患者鏈接到其他人的多對多表可以很好地促進這一點。在這張表中應該有一些關於這些人之間的關係的描述,這將我們帶回到人們的分類。

由於Doctor和Patient可以在其​​自己的表中創建相同的主鍵ID,因此具有全局唯一ID或對象ID變得非常有用。

建議這樣做的一個好方法是讓一個表指定爲自動增量主鍵。首先在該表上執行插入操作以獲取OID,然後將其用於新PERSON。

我想更進一步。當事情變得醜陋時(某些新開發人員將他的手放在數據庫上,或者甚至更糟糕,是一個非常老的開發人員,那麼它對OID增加更多的含義非常有用。數據庫引擎,但是如果你使用BIG INT來表示所有的主鍵ID,那麼你就有很多空間給一個數字加上可視的可識別序列,例如所有的醫生ID都可以從100開始,所有的患者都是110,所有的護士有120 。

要,我會追加說Julian日期或Unix的日期+時間,最後追加自動遞增ID

這將導致相同的數字:

110,2455892,00000001 
120,2455892,00000002 
100,2455892,00000003 

自從Julian從現在開始的100年後只有2492087年,您可以看到7位數將充分存儲此值。

BIGINT是一個範圍爲-9.22x10^18到9.22x10^18(-2^63到2^63 -1)的64位(8字節)有符號整數。注意exponant是18.這是你必須使用的18位數字。

使用此設計,您僅限於1億OID,999類別的人員,並且可以...儘可能超過數據庫的保質期,但我認爲這對於大多數解決方案來說已經足夠了。

像這樣創建OID所需的操作都是乘法和除法,它可以避免所有的文本操作磨齒。

缺點是INSERT需要的不僅僅是一個簡單的TSQL語句,而是它的優點是當你追蹤錯誤的數據或者在你的查詢中很聰明時,你的OID可視化地告訴你不僅僅是一個隨機數或者更糟的是,像GUID這樣的眼神。