簡介
我們所知道的所有關於數據庫的信息幾乎都可以在稱作 系統編目的元數據存儲庫中找到。元數據是 關於數據庫中數據的信息。元數據與數據本身是分開來維護的。系統編目描述數據的邏輯和物理結構。DB2 UDB 系統編目(或簡稱為“編目”)由很多表和視圖組成,這些表和視圖由數據庫管理器來維護。在創建一個數據庫時,也會順帶創建一組編目表和視圖。這些編目描述了數據庫對象,例如表、列和索引,並包含關於用戶所擁有的訪問這些對象的訪問類型的信息。將數據庫對象和特權添加到數據庫中時,編目表也會隨之增長。在創建、修改或刪除一個對象時,數據庫管理器會插入、更新或刪除編目表中描述該對象以及描述該對象與其他對象之間的關系的行。
當然,不能顯式地創建或刪除這些系統編目表,但是可以查詢和顯示這些表的內容。這些視圖中收藏了豐富的有用信息,其中包括可以幫助您理解數據庫如何運行的信息。在本文中,我將通過實際的例子展示如何從 DB2 UDB 系統編目檢索有用的信息。
系統編目基表(SYSIBM 模式)
編目表是在 SYSIBM 模式下創建的,存儲在 SYSCATSPACE 表空間中。分區數據庫的編目表只存儲在發出 CREATE DATABASE 命令時所在的那個分區上。有些編目表還存在父子關系。例如,SYSIBM.SYSCOLAUTH 包含列級權限的詳細信息,它是 SYSIBM.SYSTABAUTH 的子表,後者記錄了表級權限。
很多組成系統編目的表存儲了關於數據庫對象的信息,這些表的名稱標識了它們所描述的對象。例如 SYSINDEXES、SYSTRIGGERS 和 SYSVIEWS。根據所存儲數據的類型,可以將編目表分成很多類。例如:
授權(Authorization) 數據存儲在諸如 SYSDBAUTH(用於數據庫級的權限)、SYSTBSPACEAUTH(用於表空間上的權限)、SYSTABAUTH(用於表和視圖上的權限)以及 SYSCOLAUTH(用於列級權限)之類的表中。
數據類型和例程 數據存儲在諸如 SYSDATATYPES(用於內置數據類型和用戶定義數據類型)、SYSROUTINES(用於函數或過程) 和 SYSROUTINEPARMS(用於在 SYSROUTINES 中列出的例程的參數)之類的表中。
約束(Constraint) 數據存儲在諸如 SYSCHECKS(用於檢查約束)、SYSRELS(用於外鍵約束)和 SYSKEYCOLUSE(用於參與主鍵、惟一性或外鍵約束的列)之類的表中。關於約束的更多信息,請參閱 DB2 基礎:約束。
依賴性(Dependency) 數據存儲在諸如 SYSCONSTDEP(對其他某種對象上的約束的依賴性)、SYSDEPENDENCIES(對其他某種對象上的觸發器、函數、索引或索引擴展的依賴性)和 SYSVIEWDEP(對其他某種對象上的視圖的依賴性)之類的表中。
存儲管理(Storage management) 數據存儲在諸如 SYSTABLESPACES(用於表空間)和 SYSTABLES(用於與某個特定表關聯的表空間)之類的表中。關於表空間 的更多信息,請參閱 DB2 基礎: 闡明表和表空間的狀態。
數據庫分區(Database partition) 數據存儲在諸如 SYSNODEGROUPS(用於數據庫分區組)和 SYSPARTITIONMAPS(用於將散列鍵值與數據庫分區關聯的分區映射)之類的表中。
數據庫管理器創建和維護兩組系統編目視圖,這些視圖是在基本系統編目表之上定義的。其中一組只讀視圖在 SYSCAT 模式下創建,另一組更小的可更新視圖則是在 SYSSTAT 模式下創建的。一個編目視圖可以基於一個或多個編目表,並且視圖中的列名常常與它們在編目表中對應的列不同。為了更好地理解這一點,讓我們看兩個例子。其中一個例子是一個簡單的只基於一個表的視圖,即 SYSCAT.KEYCOLUSE。該視圖基於 SYSIBM.SYSKEYCOLUSE 編目表,您應該記得,這個表是用來存儲與主鍵、惟一性或外鍵約束涉及的列有關的信息。下面是這個視圖的定義:
清單 1. SYSCAT.KEYCOLUSE 編目視圖的定義
create vIEw syscat.keycoluse (constname, tabschema, tabname, colname, colseq)
as select constname, tbcreator, tbname, colname, colseq
from
sysibm.syskeycoluse
在這種情況下,所有 5 個表列都出現在視圖中,但是其中有些列名有所不同。這樣做只是為了一致性和清晰。
另一個例子是一個更復雜的基於多個表的視圖,即 SYSCAT.STATEMENTS。該視圖包含與數據庫中每個包中的每條 SQL 語句有關的信息,它基於 SYSIBM.SYSPLAN 和 SYSIBM.SYSSTMT 這兩個編目表。下面是這個視圖的定義:
清單 2. SYSCAT.STATEMENTS 編目視圖的定義
create vIEw syscat.statements (pkgschema, pkgname, unique_id, version,
stmtno, sectno, seqno, text)
as select s.plcreator, s.plname, s.unique_id,
(select p.pkgversion from
sysibm.sysplan p
where s.plcreator = p.creator
and s.plname = p.name
and s.unique_id = p.unique_id),
s.stmtno, s.sectno, 1, s.text
from
sysibm.sysstmt s
面向用戶的編目視圖(SYSCAT 模式)
SYSCAT 模式包含編目表的有用只讀視圖。SYSCAT 中所有視圖上的 SELECT 特權都是 PUBLIC,可以只通過這些視圖以及 SYSSTAT 中的視圖(後面會更詳細地談到)與系統編目進行交互。
下面的代碼將建立到 SAMPLE 數據庫的連接,並返回 SYSCAT 模式中所有編目視圖的一個列表:
清單 3. 識別 SYSCAT 模式中的所有編目視圖
connect to sample
list tables for schema syscat
or, alternatively:
select tabname from syscat.tables where tabschema = 'SYSCAT'
connect reset
對於需要知道可用視圖中的列,以及這些視圖本身的名稱和用途,以構造對編目視圖更有意義的查詢的用戶, IBM DB2 Universal Database SQL Reference, Volume 1 中描述了 DB2 UDB 系統編目視圖,或者,如果您更喜歡在線信息,那麼還可以在 DB2 Information Center(依次訪問 Reference → SQL → catalog vIEws → DB2 Universal Database)找到相同的內容。您也可以在 DB2 Control Center 中研究編目視圖(參見圖 1)。
圖 1. 在對象樹中選中 VIEws 時,與 DB2 Control Center 的內容面板中列出特定數據庫相關聯的視圖。這個列表已經在模式 SYSCAT 上進行了過濾
查看原圖(大圖)
通過 Open VIEw 窗口可以查看視圖的詳細內容,通過它可以很方便地浏覽視圖列(圖 2)。
圖 2. Open VIEw 窗口為查看視圖的數據提供了一種方便方法
如果您感興趣的話,甚至還可以訪問視圖定義本身,方法是從彈出式菜單(圖 3)選中 Alter。
圖 3. 通過 Alter VIEw 窗口可以查看視圖定義
檢索授權數據
如前所述,沒有哪個單獨的系統編目視圖可以包含所有可用的授權數據。雖然關於授權和權限的元數據包含在多個編目視圖中,但是可以構造一條查詢,檢索所有擁有特權的授權 ID。我們將利用 UNION 操作來完成查詢任務,並(在這裡和在其他例子中)使用 SUBSTR 內置函數來幫助格式化結果集:
清單 4. 識別擁有特權的授權 ID
select distinct substr(grantee,1,16) as grantee, granteetype, 'Database'
from syscat.dbauth
union
select distinct substr(grantee,1,16) as grantee, granteetype, '表空間'
from syscat.tbspaceauth
union
select distinct substr(grantee,1,16) as grantee, granteetype, 'Schema'
from syscat.schemaauth
union
select distinct substr(grantee,1,16) as grantee, granteetype, 'Table'
from syscat.tabauth
union
select distinct substr(grantee,1,16) as grantee, granteetype, 'Index'
from syscat.indexauth
union
select distinct substr(grantee,1,16) as grantee, granteetype, 'Column'
from syscat.colauth
union
select distinct substr(grantee,1,16) as grantee, granteetype, 'Package'
from syscat.packageauth
union
select distinct substr(grantee,1,16) as grantee, granteetype, 'Routine'
from syscat.routineauth
union
select distinct substr(grantee,1,16) as grantee, granteetype, 'Server'
from syscat.passthruauth
order by grantee, granteetype
GRANTEE GRANTEETYPE 3
---------------- ----------- -----------
MELNYK U Database
MELNYK U Index
MELNYK U Package
MELNYK U Table
MELNYK U 表空間
PUBLIC G Database
PUBLIC G Package
PUBLIC G Routine
PUBLIC G Schema
PUBLIC G Table
PUBLIC G 表空間
11 record(s) selected.
可以構造很多其他的查詢來檢索授權數據。下面是另外兩個例子:
清單 5. 檢索授權數據
connect to sample
檢索所有被顯式地授予 DBADM 權限的授權名稱:
select distinct grantee from syscat.dbauth
where dbadmauth = 'Y'
檢索授給其他用戶的一組表權限:
select * from syscat.tabauth where grantor = user
connect reset
檢索數據類型和例程數據
可以使用系統編目視圖來輕松地檢索關於用戶定義數據類型或例程的信息。例如:
清單 6. 檢索數據類型和例程數據
connect to sample
檢索關於所有用戶定義類型(即不屬於 SYSIBM 模式的類型)的信息:
select typeschema, typename, sourcename, metatype from syscat.datatypes
where typeschema != 'SYSIBM'
檢索關於所有用戶定義例程(即所屬模式的名稱不是以 SQL 或 SYS 開頭的例程)的信息:
select routineschema, routinename, routinetype, origin, language, text
from syscat.routines
where substr(routineschema,1,3) != 'SQL' and substr(routineschema,1,3) != 'SYS'
connect reset
檢索約束數據
也可以使用系統編目視圖來檢索關於 NOT NULL、惟一、主鍵、外鍵和表檢查約束的信息。例如:
清單 7. 檢索約束數據
connect to sample
檢索由用戶 MELNYK 創建的表中所有不能為空的一組列:
select substr(tabname,1,16) as tabname, substr(colname,1,16) as colname, nulls
from syscat.columns
where tabschema = 'MELNYK' and nulls = 'N'
檢索其上定義了惟一性約束(不是主鍵約束)的一組表:
"select substr(tabschema,1,16) as tabschema, substr(tabname,1,16) as tabname, keyunique
from syscat.tables
where keyunique > 0"
檢索所有為 SAMPLE 數據庫定義的主鍵。如果一個列是它所屬表的主鍵的一部分,
那麼 KEYSEQ 包含一個非空的值。該值表示這個列在主鍵中所處的以數字表示的位置:
select substr(tabschema, 1, 16) as tabschema, substr(tabname, 1, 16) as tabname,
substr(colname, 1, 16) as colname, keyseq
from syscat.columns
where keyseq is not null
檢索參與由惟一性、主鍵或外鍵約束定義的一個鍵的所有列。識別約束名和類型,
以及該列在鍵中所處的以數字表示的位置(起始位置是 1):
select substr(k.constname,1,20) as constname, t.type, substr(k.tabname,1,20) as tabname,
substr(k.colname,1,16) as colname, k.colseq
from syscat.keycoluse k, syscat.tabconst t
where k.constname = t.constname
檢索每個表檢查約束:
select substr(constname,1,20) as constname, substr(tabname,1,20) as tabname,
substr(text,1,32) as text
from syscat.checks
connect reset
檢索依賴數據
可以使用系統編目視圖來檢索關於對象相互之間依賴關系的信息。
清單 8. 檢索依賴數據
connect to sample
檢索 SYSCAT.COLUMNS 視圖所依賴的所有表:
select distinct substr(a.tabschema,1,16) as tabschema,
substr(a.tabname,1,16) as tabname, a.type, substr(a.tbspace,1,16) as tbspace
from syscat.tables a, syscat.vIEwdep b
where a.type = 'T'
and a.tabname = b.bname
and a.tabschema = b.bschema
and b.btype = 'T'
and b.vIEwname = 'COLUMNS'
and b.vIEwschema = 'SYSCAT'
connect reset
TABSCHEMA TABNAME TYPE TBSPACE
---------------- ---------------- ---- ----------------
SYSIBM SYSCHECKS T SYSCATSPACE
SYSIBM SYSCOLCHECKS T SYSCATSPACE
SYSIBM SYSCOLPROPERTIES T SYSCATSPACE
SYSIBM SYSCOLUMNS T SYSCATSPACE
4 record(s) selected.
該查詢實際上與您選擇 SYSCAT.COLUMNS 視圖的 Show Related 動作時由 DB2 Control Center 生成的底層查詢(圖 4 和圖 5)是一樣的。
圖 4. 通過 Show Related 窗口可以查看視圖與其他對象之間的初級依賴關系。在這種情況下,我們看到 SYSCAT.COLUMNS 視圖所依賴的一組編目表
圖 5. Show SQL 窗口提供了對圖 4 中顯示的一組依賴關系的底層查詢
檢索存儲管理數據
可以使用系統編目視圖來檢索關於表空間之類的存儲管理對象的信息。
清單 9. 檢索存儲管理數據
connect to sample
檢索關於與用戶 MELNYK 創建的表相關聯的表空間的信息:
select substr(t.tabname, 1, 12) as tabname, t.tbspaceid as tsp_id,
s.tbspacetype as tsp_type, s.datatype, s.extentsize, s.pagesize, s.dbpgname
from syscat.tables t, syscat.tablespaces s
where tabschema = 'MELNYK' and type = 'T' and t.tbspaceid = s.tbspaceid
connect reset
TABNAME TSP_ID TSP_TYPE DATATYPE EXTENTSIZE PAGESIZE DBPGNAME
------------ ------ -------- -------- ----------- ----------- ------------------
CL_SCHED 2 S A 32 4096 IBMDEFAULTGROUP
DEPARTMENT 2 S A 32 4096 IBMDEFAULTGROUP
EMP_ACT 2 S A 32 4096 IBMDEFAULTGROUP
EMP_PHOTO 2 S A 32 4096 IBMDEFAULTGROUP
EMP_RESUME 2 S A 32 4096 IBMDEFAULTGROUP
EMPLOYEE 2 S A 32 4096 IBMDEFAULTGROUP
IN_TRAY 2 S A 32 4096 IBMDEFAULTGROUP
ORG 2 S A 32 4096 IBMDEFAULTGROUP
PROJECT 2 S A 32 4096 IBMDEFAULTGROUP
SALES 2 S A 32 4096 IBMDEFAULTGROUP
STAFF 2 S A 32 4096 IBMDEFAULTGROUP
11 record(s) selected.
檢索數據庫分區數據
還可以使用系統編目視圖來檢索關於數據庫分區和數據庫分區組的信息。
清單 10. 檢索數據庫分區數據
connect to sample
檢索關於每個數據庫分區和它所屬的數據庫分區組的信息:
select n.dbpgname, substr(n.definer, 1, 16) as definer, n.pmap_id, n.create_time,
d.dbpartitionnum, d.in_use
from syscat.dbpartitiongroups n, syscat.dbpartitiongroupdef d
where n.dbpgname = d.dbpgname
connect reset
DBPGNAME DEFINER PMAP_ID CREATE_TIME DBPARTITIONNUM IN_USE
------------------ -------... ------- -------------------------- -------------- ------
IBMCATGROUP SYSIBM 0 2004-10-18-08.27.54.045000 0 Y
IBMDEFAULTGROUP SYSIBM 1 2004-10-18-08.27.54.125000 0 Y
2 record(s) selected.
可更新編目視圖(SYSSTAT 模式)
SYSSTAT 模式包含少量的基於系統編目表的可更新視圖。這些視圖包括一些包含對查詢優化器有用的統計信息的列。優化器使用特定表和索引列(如果這些列也參與了行選擇或表連接)中關於數據分布的信息,它使用該信息來比較用於特定查詢的不同數據訪問計劃的開銷。
您可能對更改其中某些統計值來影響優化器、或者在開發或測試環境中調查研究數據庫性能感興趣。實際上,您可以使用 SQL UPDATE 語句來更改可更新編目視圖中的統計列。如果在某個表上擁有 CONTROL 權限,那麼就可以更新屬於該表的值,但是如果擁有數據庫上顯式的 DBADM 授權的話,那麼您可以更新任何可更新的列。
可以使用 runstats 實用程序來更新系統編目表中的統計信息,使查詢優化過程更容易一些。建議在手動更新任何統計信息之前,先調用 RUNSTATS 命令,以便起始點能夠准確地反映當前狀態。
關於如何使用可更新編目視圖來優化性能的討論超出了本文的范圍。您可以在 DB2 UDB 產品庫中發現更多關於這一主題的信息。
控制對系統編目的訪問
在創建一個數據庫時,系統編目視圖上的 SELECT 權限便被授給 PUBLIC(圖 6)。如果數據庫包含敏感信息,您可能希望限制對編目視圖的訪問,因為編目描述了數據庫中的每一個對象。在從 PUBLIC 撤消 SELECT 權限之後,可以在必要時將該權限授給特定的用戶。必須要有 DBADM 或 SYSADM 權限,來授予或撤消系統編目視圖上的 SELECT 權限。
圖 6. 通過 VIEw Privileges 窗口可以查看或更改所擁有的視圖上的權限
考慮一個包含每個表的名稱的視圖,並且用戶的授權 ID 被顯式地授予了這些表上的 SELECT 權限。 清單 11 中的代碼就創建了這樣一個名為 MYSELECTS 的視圖。該視圖基於另一個視圖 SYSCAT.TABAUTH 編目視圖。我們指定一個被授權者類型 U(用於用戶;也可以是 G,用於組)和一個被授權者值 USER(引用指定運行時授權 ID 的專用寄存器)。並且還將過濾出那些 SELECT 權限標志被設為 YES 的行。
創建 MYSELECTS 視圖之後,我們可以構造一條查詢,從該視圖和 SYSCAT.TABLES 視圖中檢索數據。這種同時從兩個或更多個表中檢索數據的查詢稱作連接(join)。我們的連接將從 MYSELECTS 視圖檢索表模式和表名,並從 SYSCAT.TABLES 視圖檢索相應的表類型(例如 表示視圖的 V)。在這個例子中,查詢返回了一行結果,這對應於剛才創建的視圖。授權 ID MELNYK 只被顯式地授予該表或視圖上的 SELECT 權限。