2010-05-26 104 views
1

說我看起來像這樣的數據庫;通過添加索引列來優化SQL數據庫

Product with columns [ProductName] [Price] [Misc] [Etc] 
Order with columns [OrderID] [ProductName] [Quantity] [Misc] [Etc] 

ProductName是Product的主鍵,一些字符串類型和唯一的。
OrderID是主鍵和某種整數類型,而ProductName是外鍵。

假設我將產品的主鍵更改爲整數類型的新列,即[ProductID]

這會減少數據庫大小並優化加入這兩個表(以及類似的操作)的查找,還是這些優化是由(most/general/main)自動執行的SQL數據庫實現?

從技術上講,使用(字符串)產品名稱爲Product主鍵,一個數據庫應該能夠在Order實施ProductName列作爲只是一個指向行中Product,並執行JOIN作爲quicly作爲一個有整數一個外鍵,這是一個實現SQL的標準方式。

更新: 這個問題是關於如何SQL服務器處理的外鍵,而不是產品是否表需要序列號,或者我如何處理與數據庫中的產品名稱更改。

回答

2

字符串主鍵是一個壞主意,所以將其更改爲INT將有助於提高性能。大多數數據庫使用主鍵索引進行查找和比較,如果可能的話,選擇一個簡短的主鍵 - 一列。您可以使用主鍵列進行聯接(根據聯接列中的公共值將兩個或多個表中的數據組合起來),查詢檢索以及對查詢結果集進行分組或排序。索引條目比較簡單,數據庫可以執行查找和比較的速度更快。

更何況,如果產品名稱發生變化,您如何處理?將包含產品名稱的所有行更新爲外鍵?

我不能說這更好,所以看看這個答案:Should I design a table with a primary key of varchar or int,從這個問題的答案報價:

使用VARCHAR(10)或(20)只使用 了太多的空間 - 10或20字節 而不是4,以及許多人 不知道 - 將在表上的每個非集羣 索引上的每個索引 上重複聚簇鍵值 ,因此潛在可能, 你浪費了很多空間(不是 只是在磁盤上 - 這是便宜的 - b在SQL Server的主內存中也是 )。此外, 因爲它的變量(可能是4,可能 爲20個字符),它是很難SQL服務器 正確地保持良好的指數 結構

+0

+1用於指出改變產品名稱的問題 – Donnie 2010-05-26 12:58:20

0

整數列的作用不是字符串更好地加入

整數autoinc列作爲主聚簇鍵是非常適合插入的

0

我不會減小數據庫大小(大概你會保留產品名稱字段),但應該明顯提高查找性能。在大多數實現

0

整數數據類型,會比字符串(CHARVARCHAR等)少的大小,這會讓你的索引大小。

此外,也有一些問題比較字符串:

  1. 一些數據庫,即MySQL,壓縮字符串鍵,可以使搜索效率較低。

  2. 使用自然語言標識符的字符串B-Trees傾向於比整數B-Trees更少的併發性平衡。由於自然語言單詞不是均勻分佈在整個字母表中,所以更多更新和插入操作將轉到同一個塊,從而增加頁面拆分的次數並最終增加索引大小。要解決此問題,Oracle支持索引中的REVERSE子句。

  3. 比較兩個字符串時,應該考慮整理。通常情況下,這並不重要,但它確實會增加一些開銷。

+0

B,B +和B- *樹總是*平衡的。 REVERSE不會影響B樹存儲數據的方式,它只是顛倒索引中字符串的順序,以便您可以在字符串的開頭執行LIKE搜索。在SQL Server中,您可以通過在反轉字符串上添加索引計算列來實現此目的。而CHAR列不會大於整數,只要您使用的字符少於4個。 – 2010-05-26 12:01:50

+0

@Dave:這裏的「平衡」意味着不是「身高平衡」,而是「併發平衡」,即。即頁面爭用被減少。 Oracle不會對'LIKE'謂詞使用'REVERSE'索引並帶有前導'%',它只能在等同區域上使用這樣的索引。 – Quassnoi 2010-05-26 12:36:00

0

主鍵應該是唯一的,在創建行時存在並且儘可能不可變。海事組織,關於是否使用代理鍵的討論應該是數據完整性問題的次要問題。

舉例來說,如果一個產品有蓋章的項目,其中有在被輸入數據庫中該行的時間存在一個序列號,並保證是唯一的,那麼IMO將成爲一個好主鍵。原因是這個值將被用作其他表中的外鍵,並且可以節省額外查找的費用來獲取產品的序列號。額外的存儲空間是無關緊要的,直到你進入數百萬行。但是,如果序列號由其他製造商標記,因此您不能保證唯一性(「可能是獨特的」不夠好),那麼代理是適當的。事實上,如果不是大多數「產品」表使用代理鍵,我甚至會說很好的一部分,因爲沒有保證在輸入時可用的值,保證是唯一的並且將是相對不變的關鍵。

然而,使用代理鍵許多開發商忽略了需要一個表具有代理鍵應該有另一個密鑰(即唯一性約束)。因此,就產品而言,即使您添加了一個整數主鍵,您仍然應該對產品名稱有一個唯一的約束。產品名稱的唯一約束創建了所謂的候選鍵,其中整數值是主鍵。

代理鍵的意圖是幕後黑客。雖然整數鍵表現最好,而且易於創建,但它們有一個缺點:即使應用程序開發人員向用戶顯示關鍵價值,也很容易,甚至是很誘人。這是IMO的錯誤。用戶不應該看到關鍵值,否則他們會依賴於值本身,如果您需要重新排列值(如說與數據庫合併),或者如果您使用在由身份價值,他們依賴的價值觀是順序的。只要你從不向用戶展示價值,使用整數PK就沒有問題。