DBA【八股文】04:MySQL和Oracle的区别【核心语法、数据类型、函数与运算符、高级特性】

Oracle 和 MySQL 作为两种主流的关系型数据库,在 SQL 语法和功能特性上存在诸多差异。

以下从​​核心语法数据类型函数与运算符高级特性​​等维度,系统总结两者的主要区别(附示例说明):

一、核心语法差异

1、自增列

(1)Oracle

传统方式通过 SEQUENCE(序列)+ 触发器(Trigger)实现自增;Oracle 12c 及以上支持 IDENTITY 列(简化版自增)。示例(12c+):

CREATE TABLE t (id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY);

(2)MySQL

直接通过 AUTO_INCREMENT 属性实现,简单高效。示例:

CREATE TABLE t (id INT AUTO_INCREMENT PRIMARY KEY);

2、分页查询

(1)Oracle

依赖 ROWNUM 伪列(表示返回的行号),需通过子查询嵌套实现分页。示例(查询第 11-20 条数据):

SELECT * FROM (
  SELECT t.*, ROWNUM rn FROM emp t WHERE ROWNUM <= 20
) WHERE rn > 10;

(2)MySQL

使用 LIMIT 关键字直接指定偏移量和数量。示例(同上):

SELECT * FROM emp LIMIT 10, 10; -- 偏移量 10,取 10 条

3、外连接语法

(1)Oracle

支持 (+) 操作符表示外连接(左/右外连接)。示例(左外连接):

SELECT a.name, b.dept FROM emp a, dept b WHERE a.dept_id = b.id(+);

(2)MySQL

强制使用标准 LEFT JOIN/RIGHT JOIN 语法。示例(同上):

SELECT a.name, b.dept FROM emp a LEFT JOIN dept b ON a.dept_id = b.id;

4、临时表

(1)Oracle

支持​​全局临时表(GTT)​​,数据仅在会话或事务期间存在,且定义对所有会话可见。示例:

CREATE GLOBAL TEMPORARY TABLE temp_emp (
  id NUMBER,
  name VARCHAR2(50)
) ON COMMIT PRESERVE ROWS; -- 事务提交后保留数据

(2)MySQL

仅支持​​会话级临时表​​,数据仅在当前会话可见,且定义对其他会话不可见。示例:

CREATE TEMPORARY TABLE temp_emp (
  id INT,
  name VARCHAR(50)
); -- 会话关闭后自动删除

二、数据类型差异

在这里插入图片描述

三、函数与运算符差异

1、字符串拼接

(1)Oracle

使用 || 运算符(默认行为),或 CONCAT(str1, str2)(仅支持两个参数)。示例:

SELECT 'Hello' || ' ' || 'World' FROM DUAL; -- 结果:"Hello World"

(2)MySQL

默认 || 表示逻辑或(需设置 sql_mode=PIPES_AS_CONCAT 改为拼接);推荐使用 CONCAT(str1, str2, …)(支持多参数)。示例:

SELECT CONCAT('Hello', ' ', 'World'); -- 结果:"Hello World"(默认行为)
SET sql_mode='PIPES_AS_CONCAT'; SELECT 'Hello' || ' ' || 'World'; -- 结果同上(需修改模式)

2、字符串长度

(1)Oracle

LENGTH(str) 返回字符数(按字符集编码计算,如中文占 1 字符);
LENGTHB(str) 返回字节数(如 UTF-8 中文占 3 字节)。

(2)MySQL

CHAR_LENGTH(str) 返回字符数;
LENGTH(str) 返回字节数(与 Oracle 的 LENGTHB 类似)。

3、空值处理

(1)Oracle

使用 NVL(expr, default_val) 处理空值(若 expr 为 NULL,返回 default_val)。

(2)MySQL

使用 IFNULL(expr, default_val)(功能与 NVL 一致),或标准 SQL 的 COALESCE(expr1, expr2, …)(支持多个参数)。

4、日期函数

(1)Oracle

  • SYSDATE:返回当前日期时间(DATE 类型,精度秒);
  • SYSTIMESTAMP:返回当前时间戳(TIMESTAMP WITH TIME ZONE 类型,含时区);
  • MONTHS_BETWEEN(date1, date2):计算两个月份之间的月数差(结果为浮点数)。
SELECT MONTHS_BETWEEN(SYSDATE, TO_DATE('2023-01-01', 'YYYY-MM-DD')) AS months_diff FROM DUAL;

(2)MySQL

  • NOW()/CURRENT_TIMESTAMP():返回当前日期时间(DATETIME 或 TIMESTAMP 类型);
  • TIMESTAMPDIFF(unit, start, end):计算两个时间的时间差(unit 支持 YEAR/MONTH/DAY 等)。

示例(计算月份差):

SELECT TIMESTAMPDIFF(MONTH, '2023-01-01', CURDATE()) AS months_diff;

5、条件判断

(1)Oracle

使用 DECODE(expr, val1, res1, val2, res2, …, default) 函数实现多条件判断(类似 CASE WHEN)。 示例:

SELECT DECODE(salary, 10000, '高', 8000, '中', '低') AS level FROM emp;

(2)MySQL

无 DECODE 函数,需用标准 CASE WHEN 语法替代。 示例(同上):

SELECT 
  CASE 
    WHEN salary = 10000 THEN '高' 
    WHEN salary = 8000 THEN '中' 
    ELSE '低' 
  END AS level 
FROM emp;

6、类型转换

(1)Oracle

使用 TO_CHAR(date, format) 转换日期为字符串,TO_DATE(str, format) 转换字符串为日期。 示例:

SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') AS now_str FROM DUAL;
SELECT TO_DATE('2023-01-01 12:00:00', 'YYYY-MM-DD HH24:MI:SS') AS date_val FROM DUAL;

(2)MySQL

使用 DATE_FORMAT(date, format) 转换日期为字符串,STR_TO_DATE(str, format) 转换字符串为日期。 示例(同上):

SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s') AS now_str;
SELECT STR_TO_DATE('2023-01-01 12:00:00', '%Y-%m-%d %H:%i:%s') AS date_val;

四、高级特性差异

1、序列

(1)Oracle

原生支持 SEQUENCE 对象,用于生成全局唯一的递增值(可独立于表存在)。示例:

CREATE SEQUENCE seq_emp START WITH 1 INCREMENT BY 1;
SELECT seq_emp.NEXTVAL FROM DUAL; -- 获取下一个值(结果:1)

(2)MySQL

无原生 SEQUENCE,但 8.0+ 支持通过 AUTO_INCREMENT 模拟自增,或通过存储过程/触发器手动实现序列(需额外代码)。

2、窗口函数

(1)Oracle

10g 及以上版本支持窗口函数(如 ROW_NUMBER()、RANK()、SUM() OVER() 等),用于复杂分组计算。 示例(计算员工工资排名):

SELECT name, salary, RANK() OVER (ORDER BY salary DESC) AS rank 
FROM emp;

(2)MySQL

仅 8.0+ 版本支持窗口函数(功能与 Oracle 类似,但部分函数名称或行为可能不同)。

3、物化视图

(1)Oracle

支持物化视图(物理存储查询结果,定期刷新),用于优化复杂查询性能。 示例:

CREATE MATERIALIZED VIEW mv_emp_dept 
BUILD IMMEDIATE 
REFRESH COMPLETE EVERY 1 DAY 
AS SELECT e.name, d.dept_name FROM emp e JOIN dept d ON e.dept_id = d.id;

(2)MySQL

不支持物化视图,需通过触发器、事件调度(EVENT)或定时任务手动维护汇总表。

4、触发器

(1)Oracle

支持行级触发器(FOR EACH ROW)和语句级触发器,可在触发时访问 :OLD(旧值)和 :NEW(新值)。 示例(更新前记录旧值):

CREATE TRIGGER trg_emp_update 
BEFORE UPDATE ON emp 
FOR EACH ROW 
BEGIN
  :NEW.update_time := SYSDATE; -- 自动更新修改时间
END;

(2)MySQL

语法类似,但 :OLD/:NEW 需改为 OLD.column/NEW.column,且不支持 FOR EACH ROW 显式声明(默认行级触发)。 示例(同上):

CREATE TRIGGER trg_emp_update 
BEFORE UPDATE ON emp 
FOR EACH ROW 
BEGIN
  SET NEW.update_time = NOW(); -- 自动更新修改时间
END;

五、总结

Oracle 和 MySQL 的差异本质上源于设计定位:

Oracle 是企业级数据库,强调功能全面性和高可靠性;MySQL 是轻量级开源数据库,注重易用性和性能。

实际开发中需根据业务场景选择,若涉及复杂事务、大数据量分析,Oracle 更合适;若为互联网高并发场景,MySQL(或其衍生版如 TiDB)更灵活。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

做一个有趣的人Zz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值