內部資料表
SQL Server 會自動建立內部資料表來支援下列功能:
主要 XML 索引
空間索引
Service Broker
查詢通知
變更追蹤
內部資料表是某些其他使用者動作的副作用。例如,當您建立主要 XML 索引時,SQL Server 就會自動建立內部資料表來保存零碎的 XML 文件資料。內部資料表會出現在每個資料庫的 sys 結構描述中,而且會具有系統產生的唯一名稱,以便表示其功能,例如 xml_index_nodes_2021582240_32001 或 queue_messages_1977058079。
內部資料表不包含使用者可存取的資料,而且其結構描述是固定且無法變更的。您無法在 Transact-SQL 陳述式中參考內部資料表名稱。例如,您無法執行 SELECT * FROM <sys.internal_table_name> 等陳述式。不過,您可以查詢目錄檢視來查看內部資料表的中繼資料。
檢視內部資料表中繼資料
您可以使用 sys.internal_tables 目錄檢視,藉以檢視與內部資料表相關聯的中繼資料。透過這項檢視,您就可以檢視內部資料表的結構描述。由於內部資料表與使用者資料表具有許多相同的特性,因此 sys.internal_tables 檢視會從 sys.objects 目錄檢視繼承資料行並且具有 'IT' 的類型。如同使用者資料表一樣,內部資料表的資料行中繼資料可在 sys.columns 目錄檢視中檢視,而且內部資料表上系統產生之索引和統計資料的中繼資料可在 sys.indexes 和 sys.stats 目錄檢視中檢視。
您也可以透過聯結至其他目錄檢視,取得有關配置和空間使用的資訊。請參閱本主題後面的「內部資料表儲存」。
下圖將顯示最上層的目錄資料模型。
檢視內部資料表中繼資料的權限
若要檢視資料庫中的內部資料表中繼資料,您會需要下列其中一項權限或群組成員資格:
CONTROL SERVER 權限。
資料庫中的 CONTROL 權限。
db_owner 或 sysadmin 群組中的成員資格。
可以檢視父實體 (XML 或空間索引或佇列) 的使用者就可以檢視該實體的內部資料表。
檢視 XML 索引中繼資料
下圖將顯示 XML 索引之內部資料表的中繼資料結構。
若要了解本圖中顯示的目錄檢視關聯性,請假設主要 XML 索引 Xp 是在資料表 T 上建立的。資料表的中繼資料是位於 sys.tables 目錄檢視中,而 XML 索引的中繼資料是位於 sys.xml_indexes 目錄檢視中。SQL Server 建立來保存 XML 索引資料之內部資料表 Ti 的中繼資料是位於 sys.internal_tables 檢視中。
若要找出內部資料表 Ti 和使用者資料表 T 之間的關聯性,您可以將 sys.internal_tables 檢視的 parent_id 資料行聯結至 sys.tables 檢視的 object_id 資料行。若要找出內部資料表 Ti 和 XML 索引 Xp 之間的關聯性,您可以將 sys.internal_tables 的 parent_id 和 parent_minor_id 資料行聯結至 sys.xml_indexes 的 object_id 和 index_id 資料行。請參閱下面的範例 G。
檢視空間索引中繼資料
空間索引的中繼資料大多與 XML 索引的中繼資料相等。兩者的差異在於空間索引會使用 sys.spatial_indexes 而不是 sys.xml_indexes,而且您需要使用 sys.spatial_index_tessellations 來檢視空間索引的空間參數。
下圖將顯示空間索引上內部資料表的中繼資料結構。
若要了解本圖中顯示的目錄檢視關聯性,請假設空間索引 Si 是在資料表 T 上建立的。資料表的中繼資料是位於 sys.tables 目錄檢視中,而空間索引的中繼資料是位於 sys.spatial_indexes 目錄檢視和 sys.spatial_index_tessellations 目錄檢視中。SQL Server 建立來保存空間索引資料之內部資料表 Ti 的中繼資料會位於 sys.internal_tables 檢視中。
若要找出內部資料表 Ti 和使用者資料表 T 之間的關聯性,您可以將 sys.internal_tables 檢視的 parent_id 資料行聯結至 sys.tables 檢視的 object_id 資料行。若要找出內部資料表 Ti 和空間索引 Si 之間的關聯性,您可以將 sys.internal_tables 的 parent_id 和 parent_minor_id 資料行聯結至 sys.spatial_indexes 的 object_id 和 index_id 資料行。如需詳細資訊,請參閱這個主題稍後的範例 L。
檢視 Service Broker 中繼資料
下圖將顯示 Service Broker 佇列之內部資料表的中繼資料結構。Service Broker 訊息、查詢通知和事件通知都會使用 Service Broker 佇列。此外,Service Broker 功能也會使用內部資料表來儲存所有資料庫中所有 Service Broker 服務的相關資訊。此內部資料表是位於 tempdb 系統資料庫中。
檢視查詢通知中繼資料
下圖將顯示查詢通知訂閱之內部資料表的中繼資料結構。內部資料表是用來儲存查詢通知訂閱的參數。
內部資料表儲存
內部資料表會與父實體放置於相同的檔案群組中。您可以使用下列範例 F 中顯示的目錄查詢,傳回內部資料表針對同資料列、資料列外和大型物件 (LOB) 資料所使用的頁面數。
您可以使用 sp_spaceused 系統程序來傳回內部資料表的空間使用資料。sp_spaceused 會使用下列方式來報告內部資料表的空間:
當您指定佇列名稱後,就會參考與此佇列相關聯的基礎內部資料表,並且報告其儲存耗用量。
XML 索引、空間索引和全文檢索索引之內部資料表所使用的頁面會包含在 index_size 資料行中。當您指定資料表或索引檢視表名稱後,該物件之 XML 索引、空間索引和全文檢索索引的頁面就會包含在資料行 reserved 和 index_size 中。
範例
下列範例將說明如何使用目錄檢視來查詢內部資料表中繼資料。
A. 顯示從 sys.objects 目錄檢視繼承資料行的內部資料表
SELECT * FROM sys.objects WHERE type = 'IT';
B. 傳回所有內部資料表中繼資料 (包括從 sys.objects 繼承的資料行)
SELECT * FROM sys.internal_tables;
C. 傳回內部資料表的資料行和資料行資料類型
SELECT SCHEMA_NAME(itab.schema_id) AS schema_name
,itab.name AS internal_table_name
,typ.name AS column_data_type
,col.*
FROM sys.internal_tables AS itab
JOIN sys.columns AS col ON itab.object_id = col.object_id
JOIN sys.types AS typ ON typ.user_type_id = col.user_type_id
ORDER BY itab.name, col.column_id;
D. 傳回內部資料表索引
SELECT SCHEMA_NAME(itab.schema_id) AS schema_name
, itab.name AS internal_table_name
, idx.*
FROM sys.internal_tables AS itab
JOIN sys.indexes AS idx ON itab.object_id = idx.object_id
ORDER BY itab.name, idx.index_id;
E. 傳回內部資料表統計資料
SELECT SCHEMA_NAME(itab.schema_id) AS schema_name
,itab.name AS internal_table_name
, s.*
FROM sys.internal_tables AS itab
JOIN sys.stats AS s ON itab.object_id = s.object_id
ORDER BY itab.name, s.stats_id;
F. 傳回內部資料表的資料分割和配置單位資訊
SELECT SCHEMA_NAME(itab.schema_id) AS schema_name
,itab.name AS internal_table_name
,idx.name AS heap_or_index_name
,p.*
,au.*
FROM sys.internal_tables AS itab
JOIN sys.indexes AS idx
-- JOIN to the heap or the clustered index
ON itab.object_id = idx.object_id AND idx.index_id IN (0,1)
JOIN sys.partitions AS p
ON p.object_id = idx.object_id AND p.index_id = idx.index_id
JOIN sys.allocation_units AS au
-- IN_ROW_DATA (type 1) and ROW_OVERFLOW_DATA (type 3) => JOIN to partition's Hobt
-- else LOB_DATA (type 2) => JOIN to the partition ID itself.
ON au.container_id =
CASE au.type
WHEN 2 THEN p.partition_id
ELSE p.hobt_id
END
ORDER BY itab.name, idx.index_id;
G. 傳回 XML 索引的內部資料表中繼資料
SELECT t.name AS parent_table
,t.object_id AS parent_table_id
,it.name AS internal_table_name
,it.object_id AS internal_table_id
,xi.name AS primary_XML_index_name
,xi.index_id as primary_XML_index_id
FROM sys.internal_tables AS it
JOIN sys.tables AS t
ON it.parent_id = t.object_id
JOIN sys.xml_indexes AS xi
ON it.parent_id = xi.object_id
AND it.parent_minor_id = xi.index_id
WHERE it.internal_type_desc = 'XML_INDEX_NODES';
GO
H. 傳回 Service Broker 佇列的內部資料表中繼資料
SELECT q.name AS queue_name
,q.object_id AS queue_id
,it.name AS internal_table_name
,it.object_id AS internal_table_id
FROM sys.internal_tables AS it
JOIN sys.service_queues AS q ON it.parent_id = q.object_id
WHERE it.internal_type_desc = 'QUEUE_MESSAGES';
GO
I. 傳回所有 Service Broker 服務的內部資料表中繼資料
SELECT *
FROM tempdb.sys.internal_tables
WHERE internal_type_desc = 'SERVICE_BROKER_MAP';
GO
J. 傳回查詢通知訂閱的內部資料表中繼資料
SELECT qn.id AS query_subscription_id
,it.name AS internal_table_name
,it.object_id AS internal_table_id
FROM sys.internal_tables AS it
JOIN sys.dm_qn_subscriptions AS qn ON it.object_id = qn.object_id
WHERE it.internal_type_desc = 'QUERY_NOTIFICATION';
K. 傳回空間索引的內部資料表中繼資料
SELECT t.name AS parent_table
,t.object_id AS parent_table_id
,it.name AS internal_table_name
,it.object_id AS internal_table_id
,si.name AS spatial_index_name
,si.index_id as spatial_index_id
FROM sys.internal_tables AS it
JOIN sys.tables AS t
ON it.parent_id = t.object_id
JOIN sys.spatial_indexes AS si
ON it.parent_id = si.object_id
AND it.parent_minor_id = si.index_id
WHERE it.internal_type_desc = 'EXTENDED_INDEXES';
GO