SQL 拓展指南:不同数据库差异对比(MySQL/Oracle/SQL Server 基础区别)

在学习 SQL 的过程中,你可能会发现:同样的 "建表语句" 在 MySQL 能运行,在 Oracle 却报错;"分页查询" 的写法在 SQL Server 和 MySQL 完全不同。这是因为 MySQL、Oracle、SQL Server 是三大主流关系型数据库,虽都支持标准 SQL,但在 "基础特性、语法细节、适用场景" 上存在明显差异。今天我们从学习和实操的角度,拆解三者的核心区别,帮你避免 "跨库踩坑"。

我整理了一些学习资料,包含课程、专业、考试等内容,还有游戏和软件的合集。

学习资料合集文档https://www.kdocs.cn/l/cjchDXwklk1B

一、三大数据库的基础特性差异

首先从 "定位、开源性、数据存储、默认配置" 等基础维度,快速建立对三者的整体认知,这是理解语法差异的前提。

|-----------|----------------------------------|-----------------------------|-------------------------------------------|
| 对比维度 | MySQL(8.0+) | Oracle(19c+) | SQL Server(2022+) |
| 开源性 | 开源免费(社区版),商业版收费 | 闭源,需付费授权 | 闭源,需付费授权(有免费开发版) |
| 定位与场景 | 轻量灵活,适合中小型项目、互联网场景(如电商网站、APP 后端) | 大型企业级应用(如银行、政务系统),支持高并发、高可用 | 微软生态项目(如.NET 开发的系统)、中小型企业应用 |
| 数据存储 | 以 "文件" 形式存储(如 InnoDB 引擎的.ibd 文件) | 以 "表空间" 为单位存储,支持分区表、大文件存储 | 以 "数据库文件(.mdf)+ 日志文件(.ldf)" 存储 |
| 默认端口 | 3306 | 1521 | 1433 |
| 默认字符集 | utf8mb4(支持 emoji 表情) | AL32UTF8(类似 UTF-8) | SQL_Latin1_General_CP1_CI_AS(需手动设置 UTF-8) |
| 事务支持 | 支持(InnoDB 引擎),默认自动提交 | 支持,默认自动提交,事务稳定性极强 | 支持,默认自动提交,与微软产品兼容性好 |

二、核心语法差异:初学者高频用到的 5 个场景

语法差异是学习中最易踩坑的地方,我们聚焦 "建表、数据类型、分页查询、函数、事务隔离级别" 这 5 个最常用的场景,对比具体写法。

场景 1:建表语句差异(自增、主键、默认值)

建表是 SQL 入门的基础操作,但三者在 "自增字段""默认值设置" 上写法不同,尤其是 Oracle 没有 "自增关键字",需要用序列(Sequence)实现。

例子:创建 "学生表(student)",含自增主键(student_id)
  • MySQL 写法:用AUTO_INCREMENT关键字实现自增
sql 复制代码
CREATE TABLE student (
    student_id INT PRIMARY KEY AUTO_INCREMENT,  -- 自增主键
    student_name VARCHAR(20) NOT NULL,
    age INT DEFAULT 18,  -- 默认值18
    enroll_date DATE  -- 日期类型
);
  • Oracle 写法:无AUTO_INCREMENT,需先建序列,再通过触发器或直接调用序列赋值
sql 复制代码
-- 1. 先创建序列(生成自增ID)
CREATE SEQUENCE seq_student_id
START WITH 1  -- 从1开始
INCREMENT BY 1  -- 每次增1
NOCYCLE;  -- 不循环(到最大值后停止)

-- 2. 创建学生表
CREATE TABLE student (
    student_id INT PRIMARY KEY,  -- 需通过序列赋值
    student_name VARCHAR2(20) NOT NULL,  -- 注意:Oracle用VARCHAR2,不是VARCHAR
    age INT DEFAULT 18,
    enroll_date DATE
);

-- 3. 插入数据时调用序列(或建触发器自动赋值)
INSERT INTO student (student_id, student_name)
VALUES (seq_student_id.NEXTVAL, '张三');  -- NEXTVAL获取序列下一个值
  • SQL Server 写法:用IDENTITY(起始值, 增量)实现自增
sql 复制代码
CREATE TABLE student (
    student_id INT PRIMARY KEY IDENTITY(1,1),  -- 自增:从1开始,每次增1
    student_name VARCHAR(20) NOT NULL,
    age INT DEFAULT 18,
    enroll_date DATE
);

-- 插入数据时无需指定自增字段
INSERT INTO student (student_name) VALUES ('张三');

场景 2:常用数据类型差异

虽然三者都支持 "数值、字符串、日期" 类型,但部分类型的名称和取值范围不同,比如 Oracle 的字符串类型是VARCHAR2,SQL Server 的长文本类型是TEXT。

|--------|----------------------------------|---------------------------------------------------|-------------------------------|
| 数据类型分类 | MySQL | Oracle | SQL Server |
| 字符串 | VARCHAR (n)、TEXT(长文本) | VARCHAR2 (n)、CLOB(大文本) | VARCHAR (n)、TEXT(长文本) |
| 整数 | INT、BIGINT | INT、NUMBER(10) | INT、BIGINT |
| 小数 | DECIMAL(p,s)、FLOAT | NUMBER(p,s) | DECIMAL(p,s)、FLOAT |
| 日期 | DATE(日期)、DATETIME(日期时间) | DATE(日期)、TIMESTAMP(日期时间) | DATE(日期时间)、DATETIME2(高精度日期时间) |
| 布尔值 | BOOLEAN(本质是 TINYINT,1 = 真,0 = 假) | 无 BOOLEAN,用 NUMBER (1) 或 CHAR (1) 模拟(1 = 真,0 = 假) | BIT(1 = 真,0 = 假) |

场景 3:分页查询差异(最易混淆)

当数据量较大时,需要分页查询(如 "查询第 2 页,每页 10 条数据"),三者的写法完全不同:MySQL 用LIMIT,Oracle 用ROWNUM,SQL Server 用OFFSET...FETCH NEXT。

需求:查询学生表中,按 student_id 升序,取第 2 页(11-20 条数据,每页 10 条)
  • MySQL 写法:LIMIT 偏移量, 每页条数(偏移量 =(页数 - 1)× 每页条数)
sql 复制代码
SELECT * FROM student
ORDER BY student_id ASC
LIMIT 10, 10;  -- 偏移量10(跳过前10条),取10条(11-20条)
  • Oracle 写法:用ROWNUM(伪列,代表行号),需嵌套子查询
sql 复制代码
-- 先排序并加行号,再筛选行号范围(11-20)
SELECT * FROM (
    SELECT s.*, ROWNUM rn  -- 给结果加行号rn
    FROM (SELECT * FROM student ORDER BY student_id ASC) s
)
WHERE rn BETWEEN 11 AND 20;  -- 筛选行号11-20
  • SQL Server 写法:OFFSET 偏移量 ROWS FETCH NEXT 每页条数 ROWS ONLY
sql 复制代码
SELECT * FROM student
ORDER BY student_id ASC
OFFSET 10 ROWS  -- 跳过前10条
FETCH NEXT 10 ROWS ONLY;  -- 取接下来10条(11-20条)

场景 4:常用函数差异(日期、字符串、聚合)

函数是 SQL 查询的核心工具,三者在 "日期函数""字符串函数" 上差异最明显,比如 "获取当前日期" 的函数完全不同。

|-------|----------------------|----------------------------|--------------------------------|-------------------|
| 函数类型 | 需求描述 | MySQL | Oracle | SQL Server |
| 日期函数 | 获取当前日期时间 | NOW() | SYSDATE | GETDATE() |
| | 提取日期中的年份 | YEAR(enroll_date) | EXTRACT(YEAR FROM enroll_date) | YEAR(enroll_date) |
| 字符串函数 | 拼接字符串(如 "张三 - 2025") | CONCAT (' 张三 ', '-', 2025) | ' 张三' | |
| | 取字符串长度 | LENGTH(student_name) | LENGTH(student_name) | LEN(student_name) |
| 聚合函数 | 统计非 NULL 值数量 | COUNT(student_id) | COUNT(student_id) | COUNT(student_id) |

场景 5:事务隔离级别差异

事务隔离级别决定了并发访问时数据的一致性,三者支持的隔离级别基本一致,但默认隔离级别不同,可能导致相同代码在不同数据库中出现不同结果(如脏读、不可重复读)。

|------------|-----------------------|--------------------------------------------------------------------|
| 数据库 | 默认隔离级别 | 支持的隔离级别(按一致性从低到高) |
| MySQL | REPEATABLE READ(可重复读) | READ UNCOMMITTED → READ COMMITTED → REPEATABLE READ → SERIALIZABLE |
| Oracle | READ COMMITTED(读已提交) | READ COMMITTED → SERIALIZABLE(不支持前两个低级别) |
| SQL Server | READ COMMITTED(读已提交) | READ UNCOMMITTED → READ COMMITTED → REPEATABLE READ → SERIALIZABLE |

说明:MySQL 的默认隔离级别(REPEATABLE READ)能避免 "不可重复读",而 Oracle 和 SQL Server 的默认级别(READ COMMITTED)允许 "不可重复读",但能避免 "脏读",这在并发场景中需要特别注意。

三、适用场景与学习建议

了解差异后,更重要的是知道 "什么时候用哪个数据库",以及 "大学生该如何学习"。

1. 适用场景选择

  • 选 MySQL:如果做个人项目、互联网方向实习(如电商、短视频后端),或学习轻量级数据库,优先学 MySQL------ 开源免费,资源多,上手快,是企业中使用最广泛的数据库之一。
  • 选 Oracle:如果未来想进银行、国企、大型企业做后端开发,需要学 Oracle------ 它适合处理海量数据和高并发,稳定性极强,但学习成本较高,语法较复杂。
  • 选 SQL Server如果学.NET 开发,或在微软生态的公司实习(如用 C# 做系统),需要学 SQL Server------ 与 Visual Studio、.NET 框架兼容性好,操作界面友好,但跨平台能力弱(主要支持 Windows)。

2. 初学者学习建议

  • 先精通一个,再触类旁通:建议先把 MySQL 学透(开源免费,资料多),掌握标准 SQL 语法后,再对比学习 Oracle 或 SQL Server 的差异点 ------ 比如学会 MySQL 的LIMIT后,再记 Oracle 的ROWNUM和 SQL Server 的OFFSET,避免同时学多个导致混淆。
  • 重点关注 "标准 SQL":大部分查询语句(如SELECT、JOIN、GROUP BY)是标准 SQL,在三个数据库中通用,优先掌握这些通用语法,再针对性学习差异语法。
  • 多实操验证差异:比如把 MySQL 的建表语句改成 Oracle 写法,运行后观察报错,再根据报错调整(如把VARCHAR改成VARCHAR2,添加序列),通过实操加深记忆。

四、总结:核心差异速查表

为方便快速查阅,整理三者最核心的差异点:

|--------|-----------------|-------------------|---------------------|
| 差异类型 | MySQL | Oracle | SQL Server |
| 自增实现 | AUTO_INCREMENT | 序列(Sequence)+ 触发器 | IDENTITY(1,1) |
| 分页查询 | LIMIT 偏移量,条数 | ROWNUM(嵌套子查询) | OFFSET...FETCH NEXT |
| 字符串类型 | VARCHAR、TEXT | VARCHAR2、CLOB | VARCHAR、TEXT |
| 当前日期函数 | NOW() | SYSDATE | GETDATE() |
| 默认隔离级别 | REPEATABLE READ | READ COMMITTED | READ COMMITTED |

掌握这些差异,能帮你在学习和工作中快速适应不同数据库环境,避免 "语法报错" 和 "逻辑异常",更高效地使用 SQL 处理数据。

相关推荐
QH139292318801 天前
是德科技KEYSIGHT N5183B 9 kHz~40 GHz微波模拟信号发生器
网络·数据库·科技·嵌入式硬件·集成测试
暗暗别做白日梦1 天前
Redisson 延迟队列实现订单支付超时自动取消(源码 + 原理全解)
数据库·redis
数厘1 天前
2.13 sql数据更新(UPDATE)
数据库·sql·oracle
一江寒逸1 天前
零基础从入门到精通MongoDB(附加篇):面试八股文全集
数据库·mongodb·面试
星晨雪海1 天前
Redis 分布式 ID 生成器
数据库·redis·分布式
有味道的男人1 天前
抖音关键词搜索,视频详情api
linux·数据库·音视频
丁丁点灯o1 天前
Oracle中金额数字转换为大写汉字
数据库·oracle
fly spider1 天前
MySQL之Buffer Pool
数据库·mysql
程序员老邢1 天前
【技术底稿 13】内网 Milvus 2.3.0 向量数据库全流程部署(商助慧 AI 底座,Attu 可视化)
java·数据库·人工智能·ai·语言模型·milvus
XDHCOM1 天前
ORA-38456: 属性集状态不一致,Oracle报错修复对比,远程处理方案选择
数据库·oracle