2010-01-23 87 views
47

我在寫一個新程序,它需要一個數據庫(SQL Server 2008)。我現在爲系統運行的所有東西都是64位的,這使我想到了這個問題。對於各種表中的所有Id列,我應該讓它們全部是INT還是BIGINT?我懷疑這個系統是否會超過INT範圍,但在我認爲的一些較大的財務表中,這是一種可能性。看起來像INT是標準的雖然...SQL Server Int或BigInt數據庫表Ids

回答

101

OK,讓我們做一個快速的數學回顧:

  • INT是32位的,給你基本上4十億價值觀 - 如果你只算值大於零,它仍然是2十億。你有這麼多員工嗎?顧客?有庫存的產品?你公司有生之年的訂單?真?

  • BIGINT遠遠超出這個範圍。你真的需要嗎? REALY ??如果你是天文學家,或者是粒子物理學 - 也許。平均線商業用戶?我強烈懷疑它

想象一下,你有一個表 - 有 - 說 - 1000萬行(貴公司的訂單)。比方說,你有一個Orders表,並且你創建BIGINT的OrderID被其他5個表引用,並且在你的Orders表中的5個非聚集索引中使用 - 沒有過度,我想對吧?

1000萬行,由5個表加上5個非聚集索引,即1億個實例,其中每個使用8個字節而不是4個字節 - 400萬字節= 400 MB。總的浪費......你需要更多的數據和索引頁面,你的SQL Server將不得不從磁盤讀取更多頁面並緩存更多頁面......這對你的性能不利 - 簡單明瞭。

PLUS:大多數程序員都沒有想到的是:磁盤空間它很便宜。但是,浪費的空間在您的SQL Server RAM內存和數據庫緩存中也很重要 - 而且這個空間並不便宜!

所以要做一個非常長的短信:使用真正適合您需要的最小類型的INT;如果你有10-20個不同的值要處理 - 使用TINYINT。如果您需要訂購表格,我相信INT應該是PLENTY ENOUGH - BIGINT只是浪費空間。

加:應您的任何表真的想知道接近達到2個或4十億行,你仍然有足夠的時間,以你的表升級到BIGINT ID,如果真正需要的...... 。

+6

我實際上不得不進行這樣的更新,你說得對,我們已經有了超過6個月的警告,而且這並不難。具有諷刺意味的是,整個關鍵在下一個版本即將消失,因爲它確實沒有必要。通常我會憎惡自然的鑰匙,但是當你的桌子上有數十億行時,就該開始考慮它們了。當插入50,000行以上時,100 GB更多的可用磁盤空間和更少的索引更新是非常好的激勵措施。 – Aaronaught 2010-01-23 21:06:07

+0

感謝您的回答! – 2010-01-23 22:14:30

+1

好點@marc_s – 2012-08-03 12:27:59

14

您應該使用對於有問題的表格有意義的最小數據類型。這包括使用smallint或甚至tinyint,如果有足夠少的行。

您將節省數據和索引的空間,並獲得更好的索引性能。當你需要的所有東西是smallint時,使用bigint類似於使用varchar(4000)當你需要的全部是varchar(50)

即使機器的本機字大小爲64位,這也只意味着64位CPU操作將不會比32位操作更慢。大多數時候,他們也不會更快,他們會一樣。但是大多數數據庫無論如何都不會受到CPU的限制,它們將受到I/O限制,並且受限於內存限制,所以當您需要執行一個非常好的事情時,數據量減少50%-90%是非常好的事情索引掃描超過2億行。

+4

@Aaronaught好帖子+1,快問問題;我的印象是varchar(50),varchar(4000)和varchar(max)全部佔用相同的空間,對於小於50的給定字符串,差別只在於限制SQL放置字段的大小可。 (http://msdn.microsoft.com/en-us/library/aa258242(SQL.80).aspx) – Hogan 2010-01-23 21:40:45

+6

@霍根:好點。爲了準確描述領域需求,明智的最大規模更好,但更好的類比可能是'char(10)'與'char(50)'。 – Aaronaught 2010-01-23 22:02:21

4

您應該分別判斷每個表的數據類型是否符合每個表的需求。如果INTEGER滿足特定表格的需求,請使用它。如果一個SMALLINT就足夠了,就使用它。使用將會持續的數據類型,而不會過多。

6

使用x86架構的32位數字或64位與64位架構的排列稱爲data structure alignment

這在一個數據庫中的數據沒有意義,因爲這是事物的磁盤空間,數據緩存和表/索引架構影響性能(如其他答案中所述)。

請記住,這不是CPU訪問數據。這是數據庫引擎代碼(可能對齊,但是誰在乎?),它運行在CPU上並操縱數據。當/如果你的數據通過CPU,它肯定不會在相同的磁盤結構中。

12

這是對性能的一些真正的答案的文章......我更喜歡回答硬數字,如果可能的問題...如果你點擊以下鏈接至少高達一百萬條記錄,你會發現在一個微不足道的差異磁盤使用率....

http://www.sqlservercentral.com/articles/Performance+Tuning/2753/

我個人覺得,使用適當的ID大小是很重要的,還要考慮的事實,你可能有一個具有隨着時間的推移一噸的活動表。這不是說你存儲了大量的數據,而是由於自動遞增的性質(隨着時間的推移發生刪除和插入)而使關鍵值增加。

考慮社區網站上的文件存儲庫或社區網站多租戶應用程序上用戶評論的標識。

我知道大多數開發人員都在構建永遠不會觸及數百萬條記錄的系統,但需要注意的是,有些原因需要使用bigint,而且我仍然不相信在設計架構時你不知道潛在的增長,因爲你不應該試圖預測未來,並且如果你覺得隨着id值的增長潛力超過int的最大值,可以考慮使用bigint。

+2

請添加鏈接文章中的相關信息,因爲它不可用,似乎需要註冊。 – xpereta 2014-06-25 11:25:36

+0

Downvote爲paywall背後的文章鏈接。 – c00000fd 2015-10-08 00:17:15

+0

它不需要註冊\ o / – 2016-10-30 01:15:02

6

其他人已經爲32位ID提供了令人信服的答案。

對於某些應用程序,64位ID確實更有意義。

如果您希望確保ID在整個數據庫集羣中是唯一的,則63位ID可以非常方便。使用32位時,在集羣中的服務器之間分發ID的生成非常困難;或跨數據中心。雖然有64位,你有足夠的空間來玩,你可以方便地在服務器間生成ID而不用鎖定,並且仍然保證唯一性。

例如見Twitter SnowflakeInstagram Engineering's blog post on "Sharding & IDs at Instagram"。兩者都提供了很好的理由,爲什麼63位或64位對他們的ID比32位計數器更有意義。

2

第一個答案是對於沒有使用TB大小數據庫或具有常量和高容量插入的表的任何人的天真答案。在任何體面大小的數據庫中,您都會在整個生命週期的某個階段遇到與INT有關的問題。如果你必須使用BIGINT,它將進一步節省很多麻煩。我看到公司在僅僅一年的數據後就遇到了廉政問題,而重新種植不是一種選擇,它造成了大量的停機時間。同樣在長期運行的系統(10年以上)中,預計系統仍不會被使用,但即使使用中等大小的數據庫來清除舊數據也會受到影響。在需要大量數據的大多數情況下使用GUID要好得多,如果需要的話,禁止使用BIGINT。