Mysql

VARCHAR 主鍵 - MySQL

  • February 5, 2016

目前,我有一個categories有 2 列的表 -category VARCHAR(50) NOT NULL PRIMARY KEYparent VARCHAR(50). 該parent列是該列的外鍵 (FK) category

這似乎是最明顯的方法。但是,警鐘在我腦海中響起,因為我正在使用VARCHAR列作為主鍵,這可能會在查詢表時減慢操作速度。

我可以引入第三列cat_id INT AUTO_INCREMENT並將其設置為 PK,但它會引入一個沒有意義的新列。

除了哪一個會更快,還有什麼其他的考慮?

注意,我預測最多會有 1000 個類別左右,所以行數不是很高。但是,categoriesPK 列將成為其他表中許多外鍵的參考列。

我也應該使用(唯一)使用者名作為 PK 嗎?

VARCHAR列作為主鍵不是一個好的選擇,因為通常我們在同一列上創建集群索引。

由於預期的高碎片率,VARCHAR 列上的集群索引是一個糟糕的選擇。每個新插入的鍵值都會嘗試在現有鍵之間的某個位置找到它的位置,通常會導致頁面拆分和高索引碎片。結果導致性能不佳和額外的索引重建/重組成本。

其次,varchar與偽鍵列相比,使用鍵列作為外鍵將佔用額外的空間auto-incremented

自動遞增列上的聚集索引可能會創建“熱點”。仔細閱讀這篇文章“避免基於遞增鍵創建聚集索引”是 SQL Server 2000 天的神話嗎?

儘管熱點可能是一個問題,但是當許多使用者嘗試插入值時,但在您的情況下,與 varchar 相比,我仍然希望使用自動遞增列。

是的,我會添加一個代理 4 字節整數鍵。您目前的兩列是 100 字節,然後可以通過添加新的標識列將其減少到 58 字節。如果您確定永遠不會超過 65,535 個類別,您甚至可以將代理鍵設為 2 字節 smallint(以防萬一,保留為 INT 可能仍然是個好主意)。

對於 1,000 行的表來說,節省的空間並不大,但它是 cat_id 添加到其他表的地方,您可以節省大量空間(每個 FK 中 4 個字節而不是 50 個)。您可能還希望索引這些外鍵,因此在所有非聚集索引中節省的空間也會更大。

此外,您的聚集索引現在是順序的,以避免在添加新類別時出現碎片(頁面拆分)

表結構:-

create table dbo.Cateogory (
   CateogoryID int not null identity(1,1) constraint pkCateogory primary key clustered,
   Cateogory varchar(50) not null constraint ukCateogory unique nonclustered,
   ParentCateogoryID int null constraint fkCateogory references dbo.Cateogory(CateogoryID)
   )

您還可以根據您的要求在生產中添加索引選項(填充因子等)。

引用自:https://dba.stackexchange.com/questions/80806