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
相关推荐
阿演2 小时前
DataDjinn 新版本更新:新增 Oracle 支持,查询窗口、表预览和连接树继续打磨
数据库·oracle·ai编程·数据库连接工具
lixora3 小时前
Oracle 11g Active Data Guard Go 自动化部署工具 v1.0
数据库·oracle
mN9B2uk173 小时前
大数据量高并发的数据库优化
服务器·数据库·oracle
蓝鸟19746 小时前
Oracle超大DMP备份文件瘦身、日志精简、磁盘空间优化实战方案日志
数据库·oracle·数据库运维·生产运维实战·oracle避坑·磁盘空间优化·oracle日志清理
asdfg12589637 小时前
一文通俗理解JDBC中的核心概念+案例
java·数据库·oracle·jdbc
折哥的程序人生 · 物流技术专研7 小时前
Tomcat 严重警告:JDBC 驱动未注销 + 工作线程泄漏 —— 原因、影响与彻底修复(生产级终极指南)
java·运维·数据库·mysql·oracle·tomcat
闪电悠米9 小时前
黑马点评-Redis 消息队列-04_stream_seckill_order
数据库·redis·分布式·缓存·oracle·junit·lua
雨辰AI10 小时前
生产级实战|SpringBoot3 + 达梦DM9 数据库权限收敛与三权分立完整落地方案
数据库·mysql·oracle·政务
念何架构之路10 小时前
存储层技术:其他NoSQL数据库和RPC
数据库·oracle
曹牧20 小时前
oracle:“not all variables bound”
数据库·oracle