Oracle 其他数据对象 ------ 语法详解与综合实践
一、环境准备(Oracle 安装与配置)
说明 :本章内容基于 Oracle Database 21c XE(Express Edition),适用于 Windows / Linux。
1. 下载与安装(简要步骤)
-
下载地址 :
https://www.oracle.com/database/technologies/xe-downloads.html -
安装步骤(Windows):
- 运行
OracleXE213_Win64.exe(以管理员身份) - 设置统一口令(如:
oracle123) - 安装路径默认即可
- 安装完成后自动启动服务:
OracleServiceXEOracleXETNSListener
- 运行
2. 创建练习用户(推荐)
sql
-- 连接为 sysdba
sqlplus sys/oracle123@localhost:1521/XE as sysdba
-- 创建表空间(可选)
CREATE TABLESPACE app_ts DATAFILE 'app_ts.dbf' SIZE 100M AUTOEXTEND ON;
-- 创建用户
CREATE USER app_user IDENTIFIED BY app123 DEFAULT TABLESPACE app_ts;
-- 授予权限
GRANT CONNECT, RESOURCE, CREATE VIEW, CREATE SYNONYM, CREATE SEQUENCE TO app_user;
使用 app_user/app123 登录进行本章练习。
二、索引对象(Index)
1. 索引概述
- 作用:加速对表中数据的查询(尤其是 WHERE、JOIN、ORDER BY)。
- 类型 :
- B-tree 索引(默认)
- 位图索引(适用于低基数列)
- 唯一索引(UNIQUE)
- 函数索引(基于表达式)
- 反向键索引等
⚠️ 索引会降低 DML(INSERT/UPDATE/DELETE)性能,需权衡使用。
2. 创建索引(CREATE INDEX)
语法:
sql
CREATE [UNIQUE] INDEX index_name
ON table_name (column1 [ASC|DESC], column2, ...)
[TABLESPACE tablespace_name];
案例 1:创建普通索引
sql
-- 假设已有 employees 表
CREATE TABLE employees (
emp_id NUMBER PRIMARY KEY,
last_name VARCHAR2(25) NOT NULL,
email VARCHAR2(30),
dept_id NUMBER
);
-- 在 last_name 上创建索引(加速按姓名查询)
CREATE INDEX idx_emp_lastname ON employees(last_name);
案例 2:创建唯一索引(确保值唯一)
sql
-- 确保 email 唯一(即使未定义 UNIQUE 约束)
CREATE UNIQUE INDEX idx_emp_email ON employees(email);
案例 3:复合索引(多列)
sql
-- 加速 WHERE dept_id = ? AND last_name = ?
CREATE INDEX idx_emp_dept_name ON employees(dept_id, last_name);
案例 4:函数索引(基于表达式)
sql
-- 支持 WHERE UPPER(last_name) = 'SMITH'
CREATE INDEX idx_emp_upper_name ON employees(UPPER(last_name));
✅ 查询时必须使用相同表达式才能命中索引。
3. 修改索引
Oracle 不支持直接修改索引结构。通常做法是:
- 重建索引(REBUILD)以优化存储或移动表空间
- 重命名索引
案例:重建与重命名
sql
-- 重建索引(释放空间、提升性能)
ALTER INDEX idx_emp_lastname REBUILD;
-- 移动到其他表空间
ALTER INDEX idx_emp_lastname REBUILD TABLESPACE app_ts;
-- 重命名索引
ALTER INDEX idx_emp_lastname RENAME TO emp_last_name_idx;
4. 删除索引(DROP INDEX)
sql
-- 删除索引(不影响表数据)
DROP INDEX emp_last_name_idx;
⚠️ 删除主键或唯一约束时,Oracle 会自动删除关联的唯一索引。
5. 显示索引信息
查看当前用户所有索引
sql
SELECT index_name, table_name, uniqueness, status
FROM user_indexes
WHERE table_name = 'EMPLOYEES';
查看索引包含的列
sql
SELECT index_name, column_name, column_position
FROM user_ind_columns
WHERE table_name = 'EMPLOYEES'
ORDER BY index_name, column_position;
三、视图对象(View)
1. 创建视图(CREATE VIEW)
- 视图是虚拟表,基于 SQL 查询结果。
- 不存储实际数据(物化视图除外)。
- 用于简化复杂查询、权限控制、逻辑抽象。
语法:
sql
CREATE [OR REPLACE] [FORCE | NOFORCE] VIEW view_name [(alias,...)] AS
SELECT ... [WITH READ ONLY] [WITH CHECK OPTION];
OR REPLACE:存在则替换FORCE:即使基表不存在也创建(慎用)WITH CHECK OPTION:DML 操作必须满足 WHERE 条件
案例 1:简单视图
sql
-- 创建只显示 IT 部门员工的视图
CREATE OR REPLACE VIEW it_employees AS
SELECT emp_id, last_name, email, salary
FROM employees e
JOIN departments d ON e.dept_id = d.dept_id
WHERE d.dept_name = 'IT';
案例 2:带 CHECK OPTION 的可更新视图
sql
-- 创建可插入但仅限 HR 部门的视图
CREATE OR REPLACE VIEW hr_employees AS
SELECT emp_id, last_name, email, dept_id
FROM employees
WHERE dept_id = 10
WITH CHECK OPTION CONSTRAINT chk_hr_dept;
✅ 此视图允许 INSERT,但若插入
dept_id ≠ 10,将报错。
2. 管理视图
查看视图定义
sql
SELECT view_name, text
FROM user_views
WHERE view_name = 'IT_EMPLOYEES';
删除视图
sql
DROP VIEW hr_employees;
⚠️ 删除视图不影响基表数据。
视图的可更新性规则(简要):
- 不能含 DISTINCT、GROUP BY、JOIN(部分情况例外)、子查询等
- 必须操作单个基表
- 不能含伪列(如 ROWNUM)
四、同义词对象(Synonym)
概述
- 同义词是数据库对象的别名。
- 用于简化对象引用(尤其跨用户访问)。
- 分为:
- 私有同义词(默认,仅创建者可用)
- 公有同义词(PUBLIC,所有用户可用)
创建同义词
语法:
sql
CREATE [PUBLIC] SYNONYM synonym_name FOR [schema.]object_name;
案例 1:私有同义词
sql
-- 简化长表名引用
CREATE SYNONYM emp FOR employees;
-- 现在可直接查询
SELECT * FROM emp;
案例 2:跨用户访问(假设存在 hr.employees)
sql
-- 创建指向 hr 用户表的同义词
CREATE SYNONYM hr_emp FOR hr.employees;
-- 查询(需有 SELECT 权限)
SELECT * FROM hr_emp;
案例 3:公有同义词(需 DBA 权限)
sql
-- 由 DBA 执行
CREATE PUBLIC SYNONYM global_emp FOR hr.employees;
-- 所有用户可直接使用 global_emp
删除同义词
sql
DROP SYNONYM emp;
DROP PUBLIC SYNONYM global_emp; -- 需权限
五、序列对象(Sequence)
概述
- 序列用于生成唯一数字(常用于主键自增)。
- 不依赖于具体表,可被多个表共享。
1. 创建序列(CREATE SEQUENCE)
语法:
sql
CREATE SEQUENCE sequence_name
[START WITH n]
[INCREMENT BY n]
[MAXVALUE n | NOMAXVALUE]
[MINVALUE n | NOMINVALUE]
[CACHE n | NOCACHE]
[CYCLE | NOCYCLE]
[ORDER | NOORDER];
案例:创建员工ID序列
sql
-- 创建从 100 开始、每次递增 1、缓存 20 个值的序列
CREATE SEQUENCE emp_seq
START WITH 100
INCREMENT BY 1
NOMAXVALUE
NOCYCLE
CACHE 20;
✅
CACHE提高性能(减少磁盘 I/O),但实例崩溃可能丢失部分值。
2. 使用序列
sql
-- 获取下一个值
SELECT emp_seq.NEXTVAL FROM dual;
-- 获取当前值(必须先调用 NEXTVAL)
SELECT emp_seq.CURRVAL FROM dual;
-- 插入数据时使用
INSERT INTO employees (emp_id, last_name, email)
VALUES (emp_seq.NEXTVAL, 'Zhang', 'zhang@example.com');
3. 管理序列
修改序列(ALTER SEQUENCE)
sql
-- 修改增量(不能改 START WITH)
ALTER SEQUENCE emp_seq INCREMENT BY 2;
-- 改回 1
ALTER SEQUENCE emp_seq INCREMENT BY 1;
⚠️ 无法重置序列起始值。若需重置,需删除重建或使用技巧(见下文)。
删除序列
sql
DROP SEQUENCE emp_seq;
重置序列技巧(模拟"从1开始")
sql
-- 1. 获取当前值
SELECT emp_seq.CURRVAL FROM dual; -- 假设返回 150
-- 2. 设置负增量
ALTER SEQUENCE emp_seq INCREMENT BY -149;
-- 3. 调用一次 NEXTVAL
SELECT emp_seq.NEXTVAL FROM dual; -- 返回 1
-- 4. 恢复增量为 1
ALTER SEQUENCE emp_seq INCREMENT BY 1;
查看序列信息
sql
SELECT sequence_name, min_value, max_value, increment_by, cache_size, cycle_flag
FROM user_sequences;
六、综合性案例
场景描述:
某公司需构建员工管理系统,要求:
- 使用序列自动生成员工 ID;
- 为常用查询字段建立索引;
- 创建安全视图供 HR 部门使用;
- 为外部系统提供简化访问(同义词)。
步骤 1:创建基础表与序列
sql
-- 创建部门表
CREATE TABLE departments (
dept_id NUMBER PRIMARY KEY,
dept_name VARCHAR2(30) NOT NULL
);
-- 创建员工表
CREATE TABLE employees (
emp_id NUMBER PRIMARY KEY,
name VARCHAR2(50) NOT NULL,
email VARCHAR2(50) UNIQUE,
dept_id NUMBER,
salary NUMBER(10,2),
hire_date DATE DEFAULT SYSDATE
);
-- 创建序列
CREATE SEQUENCE emp_id_seq START WITH 1 INCREMENT BY 1 NOCACHE;
步骤 2:插入测试数据
sql
INSERT INTO departments VALUES (10, 'HR');
INSERT INTO departments VALUES (20, 'IT');
INSERT INTO employees (emp_id, name, email, dept_id, salary)
VALUES (emp_id_seq.NEXTVAL, 'Alice Wang', 'alice@corp.com', 10, 8000);
INSERT INTO employees (emp_id, name, email, dept_id, salary)
VALUES (emp_id_seq.NEXTVAL, 'Bob Li', 'bob@corp.com', 20, 12000);
步骤 3:创建索引
sql
-- 加速按部门查询
CREATE INDEX idx_emp_dept ON employees(dept_id);
-- 加速按姓名模糊查询(前缀匹配)
CREATE INDEX idx_emp_name ON employees(name);
步骤 4:创建视图
sql
-- HR 只能看 HR 部门员工,且不能修改部门
CREATE OR REPLACE VIEW hr_staff AS
SELECT emp_id, name, email, salary
FROM employees
WHERE dept_id = 10
WITH CHECK OPTION;
步骤 5:创建同义词(简化访问)
sql
-- 为外部应用创建同义词
CREATE SYNONYM staff FOR hr_staff;
CREATE SYNONYM depts FOR departments;
现在应用可直接查询:
sql
SELECT * FROM staff;
SELECT * FROM depts;
步骤 6:验证对象信息
sql
-- 查索引
SELECT index_name, table_name FROM user_indexes;
-- 查视图
SELECT view_name FROM user_views;
-- 查同义词
SELECT synonym_name, table_owner, table_name FROM user_synonyms;
-- 查序列
SELECT sequence_name, last_number FROM user_sequences;
七、总结对比表
| 对象类型 | 用途 | 是否占存储 | 可更新 | 典型场景 |
|---|---|---|---|---|
| 索引 | 加速查询 | 是(存储结构) | 否(自动维护) | WHERE / JOIN 列 |
| 视图 | 逻辑抽象 | 否(虚拟) | 部分可更新 | 权限控制、简化查询 |
| 同义词 | 别名 | 否 | 不适用 | 简化跨用户访问 |
| 序列 | 生成唯一数 | 是(元数据) | 否 | 主键自增 |
八、最佳实践建议
- 索引 :
- 避免在频繁更新的列上建索引。
- 定期监控索引使用情况(
V$OBJECT_USAGE)。
- 视图 :
- 复杂逻辑优先用视图封装。
- 敏感数据通过视图限制列/行。
- 同义词 :
- 跨 Schema 访问必用同义词。
- 避免滥用 PUBLIC 同义词(安全风险)。
- 序列 :
- 生产环境建议使用
CACHE提升性能。 - 不要依赖序列"连续"(因缓存、回滚等会跳号)。
- 生产环境建议使用
通过本章学习,您已掌握 Oracle 四大核心辅助对象的创建、管理与综合应用,为构建高效、安全、可维护的数据库系统奠定坚实基础。