Oracle vs MySQL 核心概念对比

如果你熟悉 MySQL,学习 Oracle 最大的障碍在于架构哲学的不同。MySQL 追求简单直观,Oracle 追求严谨和企业级管控。

以下是用 MySQL 的概念来类比讲解 Oracle 的核心概念:


1. 实例与数据库 (Instance vs Database)

概念 MySQL Oracle 核心区别
实例 进程 + 内存 (mysqld) 进程 + 内存 (SGA/PGA) 类似
数据库 数据文件集合 (data dir) 数据文件集合 (data files) 类似
关系 通常视为一体 严格分离 ⚠️ 最大区别
  • MySQL :启动 mysqld 服务,就能访问数据文件。通常说"启动数据库"就是指启动服务。
  • Oracle
    • 实例 (Instance):内存结构 + 后台进程(相当于发动机)。
    • 数据库 (Database):磁盘上的文件(相当于车身)。
    • 关系:实例可以挂载(Mount)和打开(Open)数据库。
    • 影响:Oracle 可以重启实例而不删除数据文件;RAC 架构下多个实例可以同时打开一个数据库。
sql 复制代码
-- MySQL: 启动服务即可用
service mysql start

-- Oracle: 需要启动实例并打开数据库
sqlplus / as sysdba
startup  -- 启动实例 + 挂载 + 打开数据库

2. 用户与模式 (User vs Schema) ⭐⭐⭐

这是 MySQL 用户最不适应的地方。

概念 MySQL Oracle 核心区别
数据库 CREATE DATABASE db1 无直接对应 MySQL 的 DB ≈ Oracle 的 Schema
用户 CREATE USER 'u1'@'%' CREATE USER u1 类似
模式 DATABASESCHEMA 用户即模式 ⚠️ 绑定关系
对象归属 表属于数据库 (db1.table) 表属于用户 (u1.table) 命名空间不同
  • MySQL
    • 创建数据库 db1
    • 创建用户 u1
    • 授权 u1 访问 db1
    • 用户和数据库是分离的
  • Oracle
    • 创建用户即创建模式CREATE USER u1 会自动创建一个名为 u1 的 Schema。
    • 对象归属u1 创建的表自动属于 u1 模式。
    • 访问方式 :其他用户访问需加前缀 SELECT * FROM u1.table_name
    • 没有"数据库"概念:整个实例就是一个大数据库,通过 Schema 隔离数据。
sql 复制代码
-- MySQL: 切换数据库
USE db1;
SELECT * FROM table1;

-- Oracle: 切换用户 (类似切换数据库)
CONNECT u1/password;
SELECT * FROM table1;  -- 实际是 u1.table1

-- Oracle: 跨用户访问
SELECT * FROM u1.table1;  -- 需要授权

3. 表空间 (Tablespace)

概念 MySQL (InnoDB) Oracle 核心区别
逻辑容器 DATABASE TABLESPACE Oracle 多了一层抽象
物理文件 .ibdibdata1 .dbf (Data File) 类似
管理粒度 每表一个文件或共享 表空间管理多个段 Oracle 更灵活
  • MySQL :表直接属于数据库,数据存在 .ibd 文件中。
  • Oracle :表属于 表空间 ,表空间对应多个 数据文件
    • 层级:数据库 → 表空间 → 段 (表) → 区 → 块
    • 好处:可以移动表空间文件而不影响逻辑结构,便于存储管理。
sql 复制代码
-- MySQL: 建表指定存储引擎
CREATE TABLE t1 (id INT) ENGINE=InnoDB;

-- Oracle: 建表指定表空间
CREATE TABLE t1 (id NUMBER) TABLESPACE users;

4. 命名空间 (Namespace) ⭐

概念 MySQL Oracle 核心区别
对象重名 表、视图、存储过程可同名 表、视图、过程不可同名 ⚠️ 冲突规则
范围 数据库内唯一 用户 (Schema) 内唯一 类似
  • MySQL :在同一个库中,可以有一个表叫 test,同时有一个存储过程也叫 test
  • Oracle :在同一个用户(Schema)下,表、视图、序列、存储过程共享命名空间
    • 如果有表 EMP,就不能创建视图 EMP 或过程 EMP
    • 索引有独立的命名空间(可以和表同名,但不建议)。
sql 复制代码
-- MySQL: ✅ 允许
CREATE TABLE test (id INT);
CREATE PROCEDURE test() BEGIN END;

-- Oracle: ❌ 报错 ORA-00955
CREATE TABLE test (id NUMBER);
CREATE VIEW test AS SELECT * FROM dual;  -- 名称已由现有对象使用

5. 自增主键 (Auto Increment)

概念 MySQL Oracle (12c 前) Oracle (12c 后)
语法 AUTO_INCREMENT 序列 (Sequence) Identity 列
实现 表属性 独立对象 表属性 (类似 MySQL)
灵活性 每表独立 序列可多表共享 每表独立
  • MySQL :直接在列上定义 AUTO_INCREMENT
  • Oracle (传统) :需要创建独立的 SEQUENCE 对象,然后在插入时调用 seq.NEXTVAL
  • Oracle (12c+) :支持 IDENTITY 列,语法接近 MySQL。
sql 复制代码
-- MySQL
CREATE TABLE t (id INT AUTO_INCREMENT PRIMARY KEY);

-- Oracle (12c 之前)
CREATE SEQUENCE t_seq;
INSERT INTO t VALUES (t_seq.NEXTVAL);

-- Oracle (12c 之后)
CREATE TABLE t (id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY);

6. 空值处理 (NULL Handling) ⚠️

概念 MySQL Oracle 核心区别
空字符串 '' != NULL '' = NULL ⚠️ 重大差异
长度 LENGTH('') = 0 LENGTH('') = NULL 逻辑不同
索引 空字符串可索引 NULL 不被普通索引存储 影响查询优化
  • MySQL:空字符串是有效的值,不等于 NULL。
  • Oracle空字符串自动转换为 NULL
    • 影响:WHERE col = '' 在 Oracle 中永远查不到数据(应使用 IS NULL)。
    • 影响:唯一索引允许多个 NULL 值(因为 NULL != NULL)。
sql 复制代码
-- MySQL
SELECT * FROM t WHERE col = '';  -- 能查到空字符串

-- Oracle
SELECT * FROM t WHERE col = '';  -- 查不到 (被当作 NULL)
SELECT * FROM t WHERE col IS NULL;  -- 才能查到

7. 大小写敏感 (Case Sensitivity)

概念 MySQL Oracle 核心区别
表名 Linux 敏感,Windows 不敏感 默认不敏感 (转大写) 存储方式不同
标识符 保持原样 未加引号自动转大写 ⚠️ 易踩坑
字符串 取决于 Collation 取决于比较设置 类似
  • MySQLCREATE TABLE MyTab,查询时 SELECT * FROM MyTabmytab (取决于配置)。
  • Oracle
    • CREATE TABLE MyTab → 内部存储为 MYTAB
    • SELECT * FROM MyTab → 自动转大写查询 MYTAB
    • SELECT * FROM "MyTab"加引号区分大小写 ,内部存储为 MyTab(后续查询必须加引号)。
    • 建议 :Oracle 中永远不要给对象名加双引号,统一大写。
sql 复制代码
-- Oracle: 推荐写法
CREATE TABLE employees;  -- 存储为 EMPLOYEES
SELECT * FROM employees; -- 自动转大写,成功

-- Oracle: 不推荐写法
CREATE TABLE "employees"; -- 存储为 employees (小写)
SELECT * FROM employees;  -- 报错 (找 EMPLOYEES)
SELECT * FROM "employees"; -- 成功 (必须加引号)

8. 事务与 DDL (Transaction & DDL)

概念 MySQL Oracle 核心区别
DML 提交 默认自动提交 (autocommit=1) 默认不自动提交 需手动 COMMIT
DDL 提交 隐式提交 隐式提交 类似
回滚 可回滚 DML DDL 不可回滚 类似
  • MySQL :默认 autocommit=1,每条 SQL 立即生效。
  • Oracle :默认 autocommit=0
    • INSERT/UPDATE/DELETE 后必须显式 COMMIT 否则其他会话不可见。
    • CREATE/ALTER/DROP 会自动提交当前事务(无法回滚 DDL)。
sql 复制代码
-- Oracle 脚本习惯
UPDATE employees SET salary = 10000;
-- 此时数据未提交,其他会话看不到
COMMIT;  -- 必须显式提交

DROP TABLE temp;  -- 执行前会自动 COMMIT 之前的未提交事务

9. 总结对比表

特性 MySQL Oracle 迁移/学习建议
隔离单元 Database (库) Schema (用户) 把 Oracle 用户当 MySQL 库用
对象命名 表/过程可同名 表/过程不可同名 命名时加前缀 (PKG_, V_)
空字符串 '' 是值 '' 是 NULL 代码中避免判空串,用 IS NULL
大小写 依赖操作系统 默认大写 对象名不要加双引号
自增 AUTO_INCREMENT Sequence / Identity 12c 后用 Identity,之前用序列
分页 LIMIT offset, size ROWNUM / OFFSET FETCH 12c 后用 OFFSET FETCH
提交 默认自动提交 手动 COMMIT 脚本末尾记得加 COMMIT
函数 IFNULL, NOW() NVL, SYSDATE 记忆常用函数对应关系

10. 给 MySQL 开发者的 Oracle 速记口诀

  1. 用户即库:Oracle 里没有"库",创建一个用户就当创建了一个库。
  2. 大写优先:对象名别加引号,Oracle 会自动转大写。
  3. 空串即空 :别判断 col = '',要判断 col IS NULL
  4. 手动提交 :写完 UPDATE 别忘了 COMMIT,否则数据"消失"了。
  5. DDL 提交:建表删表会自动提交,之前的修改别想回滚。
  6. 命名冲突:表名别和视图、存储过程重名。
  7. 分页写法 :12c 以前用 ROWNUM,12c 以后用 OFFSET FETCH
  8. 双引号禁忌 :除非必须小写,否则永远别用 "name",只用 name
相关推荐
六月雨滴8 小时前
CDB/PDB 多租户存储架构(12c+)
数据库·oracle·dba
六月雨滴8 小时前
Oracle 存储体系架构概述
数据库·oracle
残 风21 小时前
快速理解什么是MVCC?
数据库·postgresql·oracle·数据库开发
咖啡里的茶i1 天前
实验三 数据完整性实验
数据库·oracle
韶博雅1 天前
oracle + parfile(数据泵)
数据库·oracle
Chockmans1 天前
春秋云境CVE-2022-32991(手注和sqlmap)保姆级教学
数据库·安全·web安全·网络安全·oracle·春秋云境·cve-2022-32991
newnazi1 天前
RedHart安装Oracle 12C
数据库·oracle
m0_653031361 天前
Oracle OCP19C 报名考试流程
数据库·oracle·ocp报名·ocp考试流程
六月雨滴1 天前
Oracle 参数文件管理
数据库·oracle·dba
Mike117.1 天前
GBase 8c 逻辑复制槽停住以后,xlog 为什么越堆越多
数据库·oracle