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
相关推荐
奋斗tree2 小时前
SQL Server数据库自动备份终极指南方法三
数据库·oracle
SeSs IZED2 小时前
MySQL中查看表结构
数据库·mysql·oracle
Irene19912 小时前
Oracle 21c XE 大数据开发常用 SQL 语法总结(不同 Oracle 版本,sql 语法大部分通用)
大数据·sql·oracle
Yushan Bai12 小时前
通过oracle 自动优化任务dbms_sqltune进行SQL优化的实战
数据库·oracle
Lucifer三思而后行13 小时前
zCloud 纳管 MySQL 8.4 数据库
数据库·mysql·oracle
arronKler15 小时前
大数据量高并发的数据库优化
服务器·数据库·oracle
BduL OWED17 小时前
SQL进阶——JOIN操作详解
数据库·sql·oracle
cyber_两只龙宝18 小时前
【Oracle】 Oracle之SQL的子查询
linux·运维·数据库·sql·云原生·oracle
NCIN EXPE20 小时前
SQL sever数据导入导出实验
数据库·sql·oracle