資料庫物件是 Schema 的構建基石。本文詳細說明同義詞、序列、視圖、索引(含分區索引、函數索引、索引組織表)的建立、管理、優化與資料字典查詢,幫助 DBA 與開發人員高效設計結構。
同義詞為資料庫物件提供別名,隱藏 Schema 名稱與連結細節。
-- 建立使用者並授權
CONNECT system/manager;
CREATE USER myuser IDENTIFIED BY myuser;
GRANT CREATE SYNONYM TO myuser;
-- 以 myuser 建立同義詞指向 yyaccp.mytable
CONNECT myuser/myuser;
CREATE SYNONYM mytable FOR yyaccp.mytable;
所有使用者皆可見,需 CREATE PUBLIC SYNONYM 權限。
CONNECT system/manager;
GRANT CREATE PUBLIC SYNONYM TO yyaccp;
CONNECT yyaccp/accp;
CREATE PUBLIC SYNONYM jobs FOR yyaccp.jobs;
序列獨立於表格,提供高效能、無間隙(可選)的數值產生器。
CREATE SEQUENCE mytable_id
START WITH 10
INCREMENT BY 1
MAXVALUE 2000
NOCYCLE
CACHE 20;
INSERT INTO mytable VALUES (mytable_id.NEXTVAL, 'rose', 'beijing', 'rose@sdi.com', DATE '2007-10-10');
-- 取得當前值(不遞增)
SELECT mytable_id.CURRVAL FROM dual;
-- 修改增量與最大值(無法修改 START WITH)
ALTER SEQUENCE mytable_id INCREMENT BY 2 MAXVALUE 5000;
-- 刪除
DROP SEQUENCE mytable_id;
SELECT sequence_name, min_value, max_value, increment_by,
cycle_flag, order_flag, cache_size, last_number
FROM user_sequences;
視圖是預儲存的 SELECT 查詢,不儲存實體資料(物化視圖除外),可簡化複雜查詢、限制欄位存取、實現資料獨立性。
-- 簡單視圖
CREATE VIEW employee2_view AS SELECT * FROM employees2;
-- 帶條件視圖
CREATE VIEW employee2_view AS
SELECT * FROM employees2 WHERE division_id = 'BUS' OR job_id = 'PRE';
CREATE OR REPLACE VIEW employee2_view AS
SELECT * FROM employees2
WHERE division_id = 'BUS' OR job_id = 'PRE'
WITH CHECK OPTION;
若透過此視圖 UPDATE 導致資料不再符合 WHERE 條件,將拋出錯誤。
CREATE OR REPLACE VIEW employee2_view AS
SELECT * FROM employees2
WHERE division_id = 'BUS' OR job_id = 'PRE'
WITH READ ONLY;
CREATE FORCE VIEW vtable AS SELECT * FROM viewtable; -- viewtable 可不存在
CREATE VIEW emp2_job_divisions AS
SELECT e.employee_id, e.division_id, d.name AS division_name,
e.job_id, j.name AS job_name,
e.first_name, e.last_name, e.salary
FROM employees2 e, jobs j, divisions d
WHERE e.job_id = j.job_id
AND e.division_id = d.division_id;
鍵保留表:若視圖包含某表的主鍵且該主鍵也是視圖的唯一鍵,則該表為鍵保留表,可透過視圖直接 DML 修改該表資料。外部連接視圖通常無鍵保留表。
-- 允許:修改鍵保留表 employees2 的欄位
UPDATE emp2_job_divisions SET first_name = 'aaaaa' WHERE employee_id = 1;
-- 不允許:修改非鍵保留表 jobs 的欄位
UPDATE emp2_job_divisions SET job_name = 'aaa' WHERE employee_id = 1; -- ORA-01779
CREATE UNIQUE INDEX mytable_id_idx ON mytable(id);
多欄位索引,欄位順序影響選擇性,建議高選擇性欄位優先。
CREATE INDEX emp_first_last_idx ON employees2(first_name, last_name);
將索引鍵值位元反轉儲存,緩解單調遞增鍵值(如序列)導致的右側熱塊爭用。
CREATE INDEX emp_id_rev_idx ON emp(id) REVERSE;
適用於低基數欄位(如性別、狀態碼),壓縮儲存、位元運算快,但 DML 開銷大,適合資料倉庫/唯讀環境。
CREATE BITMAP INDEX emp_first_name_bmx ON employees2(first_name);
資料直接儲存在 B*-Tree 索引葉節點,必須有主鍵,適合查詢以主鍵為主的查找表。
CREATE TABLE ind_org_tab (
vencode NUMBER(4) PRIMARY KEY,
venname VARCHAR2(20)
) ORGANIZATION INDEX;
對運算式/函數結果建立索引,查詢時需使用相同運算式才能命中。
CREATE INDEX emp_firstname_fbi ON employees2(LOWER(first_name));
-- 查詢命中
SELECT * FROM employees2 WHERE LOWER(first_name) = 'john';
-- 建立範圍分區表
CREATE TABLE order_mast (
orderno NUMBER(4),
venname VARCHAR2(20)
)
PARTITION BY RANGE (orderno) (
PARTITION oe1 VALUES LESS THAN (1000),
PARTITION oe2 VALUES LESS THAN (2000),
PARTITION oe3 VALUES LESS THAN (MAXVALUE)
);
-- 局部分區索引:每個分區對應一個索引分區,維護彈性高
CREATE INDEX myind_local ON order_mast(orderno) LOCAL;
-- 查看索引分區資訊
SELECT segment_name, partition_name, segment_type, tablespace_name
FROM user_segments
WHERE segment_name = 'MYIND_LOCAL';
-- 重命名
ALTER INDEX vn_ind RENAME TO c_vn_ind;
-- 重建(消除碎片)
ALTER INDEX c_vn_ind REBUILD;
-- 刪除
DROP INDEX c_vn_ind;
-- 查詢索引欄位
SELECT index_name, table_name, column_name
FROM user_ind_columns
ORDER BY index_name, column_position;
| 物件類型 | 適用場景 | 關鍵限制 |
|---|---|---|
| 私有同義詞 | 單一使用者簡化存取 | 需 CREATE SYNONYM 權限 |
| 公共同義詞 | 全系統通用別名 | 需 CREATE PUBLIC SYNONYM 權限 |
| 序列 | 主鍵/唯一鍵自動產生 | NOCYCLE 達上限報錯;CACHE 失效會留間隙 |
| 一般視圖 | 簡化查詢/欄位權限控制 | 複雜視圖不可直接 DML |
| WITH CHECK OPTION | 防止更新脫離視圖定義 | 僅對該視圖 DML 生效 |
| 唯讀視圖 | 報表/查詢專用 | 完全禁止 DML |
| B*-Tree 索引 | 高基數/範圍查詢/連接鍵 | NULL 值不入索引(單欄) |
| 位圖索引 | 低基數/資料倉庫/多條件 AND/OR | DML 鎖定整個位圖區段,不適合 OLTP |
| 反向鍵索引 | 序列/時間戳等單調遞增鍵 | 不支援範圍掃描 |
| 函數索引 | WHERE 子句含函數運算 | 查詢必須完全匹配運算式 |
| 索引組織表 | 主鍵查找為主、資料量中小 | 需主鍵;不支援 UNIQUE/外鍵約束以外的二級索引早期版本有限制 |
| 局部分區索引 | 分區表維護/資料清除頻繁 | 分區裁剪需查詢帶分區鍵 |
合理規劃資料庫物件,是確保系統可擴展、可維護、高效能的基石。