Oracle 数据库综合教程
目录
-
第一部分:Oracle 基础入门
- 1 什么是 Oracle 数据库?
- 2 为什么选择 Oracle?(特点与优势)
- 3 Oracle 数据库体系结构概览
- 4 安装与配置 Oracle 数据库
- 5 连接到 Oracle 数据库
-
第二部分:SQL 语言核心
- 1 SQL 简介
- 2 数据定义语言
- 3 数据操纵语言
- 4 数据查询语言 -
SELECT语句详解 - 5 事务控制语言
-
第三部分:数据库对象管理
- 1 表
- 2 约束
- 3 视图
- 4 索引
- 5 序列
- 6 同义词
-
第四部分:PL/SQL 编程
- 1 PL/SQL 简介
- 2 PL/SQL 块结构
- 3 变量与数据类型
- 4 控制结构
- 5 异常处理
- 6 游标
- 7 存储过程与函数
-
第五部分:高级主题与性能优化
- 1 索引与性能
- 2 分区表
- 3 用户与权限管理
- 4 数据库备份与恢复
第一部分:Oracle 基础入门
1 什么是 Oracle 数据库?
Oracle Database,简称 Oracle,是由 Oracle Corporation(甲骨文公司)开发的一款关系型数据库管理系统,它是目前世界上市场占有率最高的商业数据库之一,以其高性能、高可靠性、高安全性和强大的功能而闻名,广泛应用于金融、电信、政府、大型企业等核心业务系统。
2 为什么选择 Oracle?(特点与优势)
- 高性能与可扩展性:通过先进的内存管理、并行查询等技术,能处理海量数据和高并发请求。
- 高可靠性:提供强大的数据保护机制,如 RAC (Real Application Clusters),确保系统 24x7 不间断运行。
- 高安全性:提供细粒度的访问控制、数据加密、审计等企业级安全功能。
- 完整的产品生态:提供从数据库、中间件到应用软件的一整套解决方案。
- 标准化与兼容性:遵循 SQL 和 ANSI/ISO 标准,同时提供了丰富的扩展功能。
3 Oracle 数据库体系结构概览
理解 Oracle 的核心组件是学习的关键:
- 实例:一组后台进程和内存结构的集合,负责管理数据库,一个数据库可以有多个实例(如 RAC 环境)。
- SGA (System Global Area):系统全局区,是实例共享的内存区域,包含数据缓冲区、共享池、日志缓冲区等。
- 后台进程:如 PMON (进程监控进程)、SMON (系统监控进程)、DBWn (数据库写进程)、LGWR (日志写进程) 等,负责处理各种任务。
- 数据库:存储在物理磁盘上的数据文件、控制文件、重做日志文件等的集合。
- 数据文件:存储实际的数据和索引。
- 控制文件:记录数据库的物理结构信息,是数据库启动的“钥匙”。
- 重做日志文件:记录所有对数据库的更改,用于故障恢复。
简单比喻:实例 像是“公司”的管理层(大脑和决策中心),而 数据库 则是公司的“仓库和账本”(实际资产),管理层(实例)通过读写账本(数据库文件)来管理公司。
4 安装与配置 Oracle 数据库
对于初学者,推荐使用 Oracle Database Express Edition (XE),它是免费且功能齐全的版本,非常适合学习和开发。
安装步骤 (以 XE 为例):
- 下载:从 Oracle 官网下载适用于您操作系统的 Oracle Database XE 安装包。
- 安装:双击安装包,按照向导进行安装,安装过程中会提示设置
SYS和SYSTEM用户的密码,请务必记住。 - 配置:安装完成后,系统会自动启动数据库服务,可以通过 Windows 的服务管理器或 Linux 的
systemctl命令查看OracleXETNSListener和OracleServiceXE的状态。
5 连接到 Oracle 数据库
有多种方式可以连接到 Oracle 数据库:
-
*SQLPlus**:Oracle 自带的命令行工具,是学习和执行 SQL 的基础。
- 启动:在命令行中输入
sqlplus / as sysdba以管理员身份登录,或sqlplus username/password@service_name以普通用户身份登录。 - 服务名:安装 XE 时,默认的服务名通常是
XE。
- 启动:在命令行中输入
-
SQL Developer:Oracle 提供的免费图形化客户端,功能强大,推荐使用。
- 下载与安装:从官网下载并安装。
- 配置连接:
- 打开 SQL Developer,点击左上角的 "+" 号新建连接。
- 连接名称:自定义(如
MyOracleXE)。 - 用户名:
system(或其他你创建的用户)。 - 密码:你在安装时设置的密码。
- 角色:默认
Default。 - 连接标识符:
XE(这是 XE 的服务名)。 - 点击 "Test" 测试连接,成功后保存并连接。
第二部分:SQL 语言核心
SQL (Structured Query Language) 是与 Oracle 数据库交互的标准语言。
1 SQL 简介
SQL 主要分为四类:
- DDL (Data Definition Language):定义数据库结构。
- DML (Data Manipulation Language):操作数据。
- DQL (Data Query Language):查询数据(通常被认为是 DML 的一部分)。
- TCL (Transaction Control Language):控制事务。
2 数据定义语言
- 创建表
CREATE TABLE employees ( employee_id NUMBER(6) PRIMARY KEY, first_name VARCHAR2(20), last_name VARCHAR2(25), email VARCHAR2(25), hire_date DATE, job_id VARCHAR2(10), salary NUMBER(8, 2) ); - 修改表结构
-- 添加一列 ALTER TABLE employees ADD (department_id NUMBER(4)); -- 修改列的数据类型 ALTER TABLE employees MODIFY (first_name VARCHAR2(50));
- 删除表
DROP TABLE employees;
3 数据操纵语言
- 插入数据
INSERT INTO employees (employee_id, first_name, last_name, email, hire_date, job_id, salary) VALUES (1001, 'John', 'Doe', 'john.doe@example.com', TO_DATE('2025-01-15', 'YYYY-MM-DD'), 'IT_PROG', 6000); - 更新数据
UPDATE employees SET salary = 6500 WHERE employee_id = 1001;
- 删除数据
DELETE FROM employees WHERE employee_id = 1001;
4 数据查询语言 - SELECT 语句详解
这是 SQL 中最核心、最复杂的部分。
SELECT column1, column2, ... FROM table_name WHERE condition GROUP BY column1, column2, ... HAVING group_condition ORDER BY column1 ASC|DESC;
示例:
假设我们有一个 employees 表。
-- 1. 查询所有员工姓名和薪资 SELECT first_name, salary FROM employees; -- 2. 查询薪资大于 5000 的员工 SELECT * FROM employees WHERE salary > 5000; -- 3. 查询每个部门的员工人数 SELECT department_id, COUNT(*) AS employee_count FROM employees GROUP BY department_id; -- 4. 查询员工人数超过 5 人的部门 SELECT department_id, COUNT(*) AS employee_count FROM employees GROUP BY department_id HAVING COUNT(*) > 5; -- 5. 按薪资降序排序,并限制只显示前 10 名 SELECT * FROM employees ORDER BY salary DESC FETCH FIRST 10 ROWS ONLY;
5 事务控制语言
事务是一个逻辑工作单元,它包含一个或多个 DML 操作,这些操作要么全部成功,要么全部失败。
- COMMIT:提交事务,将更改永久保存到数据库。
- ROLLBACK:回滚事务,撤销未提交的更改。
- SAVEPOINT:在事务中设置一个保存点,可以回滚到这个点,而不是整个事务。
-- 开始一个事务(隐式) UPDATE employees SET salary = 7000 WHERE employee_id = 1001; -- 设置一个保存点 SAVEPOINT before_raise; UPDATE employees SET salary = 7500 WHERE employee_id = 1002; -- 如果发现第二个更新有问题,可以回滚到保存点 ROLLBACK TO before_raise; -- 第一个更新仍然有效,第二个更新被撤销 -- 最后提交所有更改 COMMIT;
第三部分:数据库对象管理
1 表
表是数据库中存储数据的结构化集合,Oracle 表有多种类型,如堆表、索引组织表、分区表等。
2 约束
约束用于保证数据的完整性和一致性。
PRIMARY KEY:主键,唯一标识表中的每一行。FOREIGN KEY:外键,用于建立两个表之间的引用关系。UNIQUE:唯一约束,确保列中的值是唯一的(但可以为空)。NOT NULL:非空约束,确保列不能有 NULL 值。CHECK:检查约束,确保列中的值满足特定条件。
CREATE TABLE departments (
department_id NUMBER(4) PRIMARY KEY,
department_name VARCHAR2(30) NOT NULL
);
CREATE TABLE employees (
employee_id NUMBER(6) PRIMARY KEY,
first_name VARCHAR2(20),
department_id NUMBER(4),
CONSTRAINT fk_department FOREIGN KEY (department_id) REFERENCES departments(department_id)
);
3 视图
视图是一个虚拟表,其结果集由存储的查询定义,它不存储数据,而是动态地从基表中检索数据。
用途:简化复杂查询、限制数据访问、提供数据的不同视角。
-- 创建一个视图,只显示 IT 部门的员工 CREATE VIEW it_employees_view AS SELECT employee_id, first_name, last_name, salary FROM employees WHERE department_id = (SELECT department_id FROM departments WHERE department_name = 'IT'); -- 像查询普通表一样使用视图 SELECT * FROM it_employees_view;
4 索引
索引是一种用于快速查询数据的数据库对象,它类似于书的目录,可以极大地提高查询速度,但会降低 INSERT, UPDATE, DELETE 的速度,并占用存储空间。
-- 在 last_name 列上创建索引 CREATE INDEX idx_employees_lastname ON employees(last_name);
5 序列
序列用于生成唯一的、连续的数字,通常用作主键。
-- 创建一个序列 CREATE SEQUENCE employees_seq START WITH 1001 INCREMENT BY 1 NOCACHE; -- 使用序列 INSERT INTO employees (employee_id, first_name, ...) VALUES (employees_seq.NEXTVAL, 'Jane', ...);
6 同义词
同义词是数据库对象(如表、视图、序列)的别名,它可以简化对象名称的引用,或者隐藏对象的实际所有者。
-- 为 employees 表创建一个公共同义词 CREATE PUBLIC SYNONYM emp FOR hr.employees; -- 现在可以直接使用 emp 来访问 hr.employees 表 SELECT * FROM emp;
第四部分:PL/SQL 编程
PL/SQL (Procedural Language/SQL) 是 Oracle 对 SQL 的过程化扩展,它允许在数据库中编写存储过程、函数、触发器等程序。
1 PL/SQL 简介
PL/SQL 将 SQL 的数据操作能力和高级语言的过程化结构(如变量、循环、条件判断)结合在一起,使得在数据库内部进行复杂计算和逻辑处理成为可能。
2 PL/SQL 块结构
PL/SQL 程序由块组成,基本结构如下:
DECLARE
-- 声明部分:定义变量、游标等
v_emp_name VARCHAR2(100);
BEGIN
-- 执行部分:包含 SQL 语句和 PL/SQL 逻辑
SELECT first_name INTO v_emp_name FROM employees WHERE employee_id = 1001;
DBMS_OUTPUT.PUT_LINE('Employee Name: ' || v_emp_name);
EXCEPTION
-- 异常处理部分:处理执行过程中可能出现的错误
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Employee not found.');
END;
/
注意:要在 SQL Developer 或 SQL*Plus 中看到
DBMS_OUTPUT.PUT_LINE的输出,需要先执行SET SERVEROUTPUT ON;。
3 变量与数据类型
PL/SQL 变量必须在 DECLARE 部分声明。
DECLARE
v_num NUMBER := 10; -- 初始化
v_name VARCHAR2(50);
v_date DATE := SYSDATE; -- 使用系统当前日期
BEGIN
-- ...
END;
/
4 控制结构
- IF-THEN-ELSIF-ELSE
IF v_salary > 10000 THEN DBMS_OUTPUT.PUT_LINE('High earner'); ELSIF v_salary > 5000 THEN DBMS_OUTPUT.PUT_LINE('Medium earner'); ELSE DBMS_OUTPUT.PUT_LINE('Low earner'); END IF; - LOOP
v_counter := 1; LOOP DBMS_OUTPUT.PUT_LINE(v_counter); v_counter := v_counter + 1; EXIT WHEN v_counter > 5; END LOOP; - FOR LOOP
FOR i IN 1..5 LOOP DBMS_OUTPUT.PUT_LINE(i); END LOOP;
5 异常处理
使用 EXCEPTION 块来捕获和处理运行时错误。
DECLARE
v_salary employees.salary%TYPE;
BEGIN
SELECT salary INTO v_salary FROM employees WHERE employee_id = 9999; -- 假设此ID不存在
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('错误:找不到该员工。');
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('错误:查询返回了多行数据。');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('发生未知错误: ' || SQLERRM);
END;
/
6 游标
游标用于处理查询返回的多行数据,它像一个指针,指向结果集的当前行。
- 显式游标
DECLARE CURSOR c_employees IS SELECT first_name, salary FROM employees WHERE department_id = 10; v_name employees.first_name%TYPE; v_sal employees.salary%TYPE; BEGIN OPEN c_employees; -- 打开游标 LOOP FETCH c_employees INTO v_name, v_sal; -- 获取一行数据 EXIT WHEN c_employees%NOTFOUND; -- 当没有更多数据时退出 DBMS_OUTPUT.PUT_LINE('Name: ' || v_name || ', Salary: ' || v_sal); END LOOP; CLOSE c_employees; -- 关闭游标 END; /
7 存储过程与函数
- 存储过程:执行特定任务的 PL/SQL 块,没有返回值(但可以通过
OUT参数返回)。CREATE OR REPLACE PROCEDURE give_raise ( p_emp_id IN NUMBER, p_raise_amount IN NUMBER ) AS BEGIN UPDATE employees SET salary = salary + p_raise_amount WHERE employee_id = p_emp_id; COMMIT; DBMS_OUTPUT.PUT_LINE('Raise given to employee ' || p_emp_id); END give_raise; / -- 调用存储过程 EXECUTE give_raise(1001, 500); - 函数:返回一个值的 PL/SQL 块。
CREATE OR REPLACE FUNCTION get_employee_name ( p_emp_id IN NUMBER ) RETURN VARCHAR2 AS v_name employees.first_name%TYPE; BEGIN SELECT first_name INTO v_name FROM employees WHERE employee_id = p_emp_id; RETURN v_name; END get_employee_name; / -- 调用函数 SELECT get_employee_name(1001) FROM DUAL;
第五部分:高级主题与性能优化
1 索引与性能
- B-Tree 索引:最常用的索引类型,适合高基数(值唯一性高)的列。
- 位图索引:适合低基数(值重复性高,如性别、状态)的列,常用于数据仓库。
- 索引策略:在
WHERE子句、JOIN条件和ORDER BY子句中经常使用的列上创建索引,但索引不是越多越好,过多的索引会降低写操作性能。
2 分区表
当表非常大时(例如数亿行),可以将表按某种规则(如范围、列表、哈希)分割成多个更小的、更易于管理的部分,这就是分区。
优点:查询性能大幅提升(可以只扫描特定分区)、维护操作(如备份、归档)更灵活、数据加载更快。
-- 创建一个按范围分区的表
CREATE TABLE sales (
sale_id NUMBER,
sale_date DATE,
amount NUMBER
)
PARTITION BY RANGE (sale_date) (
PARTITION sales_q1_2025 VALUES LESS THAN (TO_DATE('01-APR-2025', 'DD-MON-YYYY')),
PARTITION sales_q2_2025 VALUES LESS THAN (TO_DATE('01-JUL-2025', 'DD-MON-YYYY')),
PARTITION sales_q3_2025 VALUES LESS THAN (TO_DATE('01-OCT-2025', 'DD-MON-YYYY')),
PARTITION sales_q4_2025 VALUES LESS THAN (TO_DATE('01-JAN-2025', 'DD-MON-YYYY'))
);
3 用户与权限管理
- 创建用户
CREATE USER my_user IDENTIFIED BY my_password;
- 授予权限
-- 授予连接数据库的权限 GRANT CONNECT TO my_user; -- 授予创建会话和表的权限 GRANT CREATE SESSION, CREATE TABLE TO my_user;
- 授予对象权限
-- 允许 my_user 查询 hr.employees 表 GRANT SELECT ON hr.employees TO my_user;
- 撤销权限
REVOKE SELECT ON hr.employees FROM my_user;
4 数据库备份与恢复
这是数据库管理员的核心职责,Oracle 提供了多种备份和恢复方法。
- RMAN (Recovery Manager):Oracle 的专用备份和恢复工具,功能强大,是生产环境的首选。
- 导出/导入:使用
expdp(Data Pump Export) 和impdp(Data Pump Import) 工具,这主要用于逻辑备份、数据迁移或表空间传输,不适合大型数据库的完整灾难恢复。# 示例:导出整个数据库 expdp system/password DIRECTORY=dpump_dir DUMPFILE=full_db.dmp FULL=Y
学习资源推荐
- 官方文档:Oracle Database Documentation (最权威、最全面)
- Oracle Learning Library (OLL):提供大量免费的学习路径和教程。
- Oracle Live SQL:一个在线的 Oracle 数据库环境,无需安装即可学习和练习 SQL 和 PL/SQL。
- 书籍:
- 《Oracle Database 12c SQL》: 由 Oracle Press 出版,是学习 SQL 的经典教材。
- 《Oracle PL/SQL Programming》: Steven Feuerstein 著,PL/SQL 编程的“圣经”。
- 社区与论坛:
这份教程为您勾勒出了 Oracle 数据库学习的完整路径,建议您从第一部分开始,动手实践每一个示例,逐步深入,最终掌握这个强大的数据库系统,祝您学习愉快!
