Oracle 19c入门学习教程,从入门到精通,Oracle 其他数据对象 —— 语法详解与综合实践(11)

Oracle 其他数据对象 ------ 语法详解与综合实践


一、环境准备(Oracle 安装与配置)

说明 :本章内容基于 Oracle Database 21c XE(Express Edition),适用于 Windows / Linux。

1. 下载与安装(简要步骤)

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;

六、综合性案例

场景描述:

某公司需构建员工管理系统,要求:

  1. 使用序列自动生成员工 ID;
  2. 为常用查询字段建立索引;
  3. 创建安全视图供 HR 部门使用;
  4. 为外部系统提供简化访问(同义词)。

步骤 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 列
视图 逻辑抽象 否(虚拟) 部分可更新 权限控制、简化查询
同义词 别名 不适用 简化跨用户访问
序列 生成唯一数 是(元数据) 主键自增

八、最佳实践建议

  1. 索引
    • 避免在频繁更新的列上建索引。
    • 定期监控索引使用情况(V$OBJECT_USAGE)。
  2. 视图
    • 复杂逻辑优先用视图封装。
    • 敏感数据通过视图限制列/行。
  3. 同义词
    • 跨 Schema 访问必用同义词。
    • 避免滥用 PUBLIC 同义词(安全风险)。
  4. 序列
    • 生产环境建议使用 CACHE 提升性能。
    • 不要依赖序列"连续"(因缓存、回滚等会跳号)。

通过本章学习,您已掌握 Oracle 四大核心辅助对象的创建、管理与综合应用,为构建高效、安全、可维护的数据库系统奠定坚实基础。

相关推荐
木风小助理2 小时前
JavaStreamAPI的性能审视,优雅语法背后的隐形成本与优化实践
java·前端·数据库
觉醒大王2 小时前
如何让综述自然引出你的理论框架?
论文阅读·深度学习·学习·自然语言处理·学习方法
Knight_AL2 小时前
MySQL InnoDB 锁机制深度解析:行锁、表锁、间隙锁、临键锁(Next-Key Lock)
数据库·mysql
知南x2 小时前
【华为昇腾DVPP/AIPP学习篇】(1)工程结构介绍
学习·华为·昇腾·cann·dvpp
良策金宝AI3 小时前
工程设计企业AI试用落地路径:从效率验证到知识沉淀
数据库·人工智能·知识图谱·ai助手·工程设计
panzer_maus3 小时前
Redis的简单介绍(2)-处理过期Key的策略
数据库·redis·缓存
仗剑恬雅人3 小时前
LINUX数据库高频常用命令
linux·运维·服务器·数据库·ssh·运维开发
Traced back3 小时前
# Windows窗体 + SQL Server 自动清理功能完整方案优化版
数据库·windows·.net
mifengxing3 小时前
操作系统(一)
大数据·数据库·操作系统