Sql-Server
在 SQL Server 中將堆更改為聚群表時會發生什麼?
據我了解,堆是一個無序的對象。當您插入一條記錄時,SQL Server 使用 IAM 頁面來獲取屬於該堆的頁面,並使用 PFS 頁面找到一個有足夠空間容納該記錄並插入其中的特定頁面。
當您在其上創建聚集索引時,它就變成了聚集表,而聚集索引本身也變成了表。但是由於聚集索引和原始堆是兩種不同的結構,SQL Server 是否會創建一個新結構(聚集索引)並將所有內容從幫助移動到新結構然後丟棄堆?
可以在表上定義很多東西,比如觸發器、約束、權限等。如果我的假設是正確的,這意味著 SQL Server 也會將所有這些東西移動到新結構中。我在文件中沒有找到任何相關資訊。我的理解正確嗎?
是的,當您在堆上創建聚集索引時,所有行都已排序移動到新的聚集索引。使用新的聚集索引鍵作為行定位符來重建任何非聚集索引。
不過,它是同一張表,因此觸發器、約束等不必更改。
然而,反之亦然。當您在表上刪除聚集索引時,聚集索引的葉級頁面保留在原地,它們成為新的堆。當行定位器從 CI 鍵切換到 rowid (file:page:slot) 時,仍會重建非聚集索引。
可以在表上定義很多東西,比如觸發器、約束、權限等。如果我的假設是正確的,這意味著 SQL Server 也會將所有這些東西移動到新結構中。我在文件中沒有找到任何相關資訊。我的理解正確嗎?
正確,一切都移至新結構
object_id
表保持不變,並且權限也自動“移動”(實際上它們沒有移動但保持不變,因為它們object_id
保持不變)使用下面的 T-SQL 進行測試:
-- use any db to test use TestDB -- create a Heap create table TestHeap (ID int identity, tName varchar(10)) insert into TestHeap (tName) values ('aaaaa'),('bbbbb'),('ccccc') -- check the object_id and type_desc select * from sys.indexes where [object_id] = object_id('TestHeap') -- create a test user create user TestHeapUser without login grant select on TestHeap to TestHeapUser -- select from table as test user execute as user = 'TestHeapUser' select * from TestHeap revert -- let's turn the table into clustered index create clustered index CIX_ID on TestHeap (ID) -- see if object_id changed (it is not), and type_desc turned into "CLUSTERED" select * from sys.indexes where [object_id] = object_id('TestHeap') -- test permissions again (object_id has not changed so Test user still should have permissions!) execute as user = 'TestHeapUser' select * from TestHeap revert -- lets turn table into Heap again drop index CIX_ID on TestHeap -- test permissions again (object_id has not changed so Test user still should have permissions!) execute as user = 'TestHeapUser' select * from TestHeap revert