在 SQL Server 中,我正在查看 TableA,它目前有一個 uniqueidentifier 聚集主鍵。 GUID 在任何上下文中都沒有任何意義。
(我會給你一點時間清理鍵盤和顯示器並放下蘇打水。)
我想刪除該主鍵並在表中新增一個新的唯一整數主鍵。我的問題是:當我刪除索引、將列從uniqueidentifier 修改為int 並將新的聚集唯一主鍵添加到修改的列時,新的PK 值將按照插入表的順序排列,還是會按照插入表的順序排列?這是去這裡的正確方法嗎?這行得通嗎? (對於表創建/修改,我有點菜鳥。)
答案1
當您刪除聚集索引時,表將變成堆疊。由於堆的物理結構與索引非常不同,因此必須將資料複製到新結構中。堆沒有任何順序。當您新增回新的聚集索引時,資料將從堆複製到新索引中,並且順序將由新的聚集鍵定義。
如果你想保留現有的順序,那麼你所要做的就是正確分配新的整數 id:
ALTER TABLE Table ADD Integer_Id INT;
GO
WITH cte AS (
SELECT ROW_NUMBER() OVER (ORDER BY Guid_Id) as RowOrderByGuid,
Guid_Id
FROM Table)
UPDATE t
SET t.Integer_Id = c.RowOrderByGuid
FROM Table t
JOIN cte c ON t.Guid_Id = c.Guid_Id;
現在 Integer_Ids 的順序將與 Guid 的順序相符。您可以刪除 Guid 欄位並在新的 Integer 欄位上新增聚集索引,並保留記錄的實體順序。
答案2
根據定義,聚集索引對實際資料頁施加物理排序;所以,是的,如果您刪除聚集索引並建立新索引,這將強制對資料進行實體重新排序。
就您的情況而言,我認為可以安全地假設會發生以下情況:
- 現有的聚集索引將被刪除,但磁碟上的實際資料不會因此而移動。
- 您將修改列類型(或刪除現有列並建立新列),將其約束設為非空、唯一、主鍵、識別碼和自動增量(這一點至關重要,否則SQL Server 甚至不會讓您這樣做)添加它,因為它不知道要放入什麼)。
- 此時,SQL Server 將自動填入該列。我不確定這裡會發生什麼,但我思考它將按照行物理儲存在資料庫中的順序進行填充。但我只是猜測這一點。
- 問題是,當涉及 UID 時,排序可能會非常混亂;所以你現在不知道資料其實是如何儲存的,也不知道以後會如何儲存;如果我對列填充的猜測是正確的,則不會有巨大的重新排序......但它可能會發生;而且,即使我是正確的,如果表足夠大,索引建立也將需要一段時間。
底線:你將要產生巨大的影響,而你可以按照您現在取得行的順序從無序 SELECT 中取得行。你必須嘗試一下。
答案3
根據定義,聚集索引決定了資料的物理順序,因此當建立新的聚集索引時,資料將重新排序;如果桌子很大,請規劃好需要一段時間。
答案4
如果您建立具有聚集主鍵的表,然後刪除聚集主鍵,則表中資料的物理順序將不會受到干擾。但是,查詢結果的物理順序不能保證與表中的順序相同,因此這種排序毫無意義。
如果您隨後新增整數列並在其上建立聚集主鍵,則該表將重新排列為鍵排序的任何順序。您可以根據 GUID 鍵的排序順序明確分配它(例如,在舊的鍵排序上使用 row_number() ),或者您可以以其他方式分配它。除非您採取措施確保明確地使排序與物理順序相同,否則表中的行不能保證驅動新鍵的排序。