Oracle(甲骨文公司),主打一款商业级的关系型数据库,甲骨文核心的产品线:1.Java2.Mysql3.Oracle
Oracle:商业性-收费
国内现状:
互联网企业+小微企业:Mysql+PostgreSQL(PG)
大型国企、银行、电网:Oracle|互联网:偏重于Mysqli
传统行业:oracle(老项目)
互联网:头条、阿里、支付宝、百度、腾讯、京东、快手等|快速裂变、用户私域-爆发、海量用户、高并发、
传统行业:用友、金蝶、招商银行、中原银行、交通、国家电网社内部使用、并发量低

1.安装

商业版本的oracle很贵,我们个人学习阶段可以使用官方提供的免费版本

Oracle Database XE(Express Edition) 是 Oracle 官方提供的免费版本,适合个人学习、开发、小型项目甚至轻量级生产使用。

  • 免费用于开发和生产(需遵守许可协议)
  • 最多使用 2 个 CPU 核心
  • 最大 2 GB 用户数据(注意:不是总数据库大小,是用户表数据)
  • 最多使用 1 GB RAM
  • 支持大部分企业版功能(如 PL/SQL、分区、JSON、XML 等)
下载地址:

https://www.oracle.com/database/technologies/xe-downloads.html

需要oracle账户,这个也很简单,自己注册一个就行,不用去到处找体验账户。

下载之后一路安装就行了,然后用数据库工具(navicat,DBeaver)连接

创建一个个人账户开发,不要使用system系统账户,权限过大

我装的是21版本的,是多租户的模式,切换个服务连接,然后创建角色

然后执行下面的命令创建即可

-- 密码含 @,必须加双引号!
CREATE USER xiao IDENTIFIED BY "FL@5201314";

GRANT CONNECT, RESOURCE TO xiao;

ALTER USER xiao QUOTA UNLIMITED ON USERS;

这样就可以了,用新创建的这个用户连接即可,下面开始使用教程。

2.使用

使用之前我们先来对比下mysql,oracle有哪些区别

对比项 Oracle MySQL
授权模式 商业软件(有免费版 XE) 开源(社区版免费,企业版收费)
默认大小写敏感 对象名不区分大小写(存为大写)
密码区分
Linux 下:表名区分大小写
Windows/macOS:不区分
列名/值通常不区分(取决于 collation)
自增主键 12c 前:需 SEQUENCE + 触发器
12c+:支持 IDENTITY
原生支持 AUTO_INCREMENT
事务支持 完全 ACID,默认不自动提交
(需显式 COMMIT
InnoDB 引擎支持 ACID
默认自动提交(可关闭)
默认隔离级别 READ COMMITTED REPEATABLE READ
字符串类型 VARCHAR2(n)(最大 4000/32767)
CHAR 定长
VARCHAR(n)(最大 65535)
CHAR 定长
日期类型 DATE(含时分秒)
TIMESTAMP(更高精度)
DATETIME(含时分秒)
TIMESTAMP(带时区转换)
分页机制 LIMIT,用 ROWNUMFETCH(12c+) 原生支持 LIMIT offset, size
空值处理 NULL 与空字符串 '' 视为相同 NULL'' 是不同值
默认端口 1521 3306
管理工具 SQL Developer(官方免费) MySQL Workbench(官方免费)

oracle使用场景如下

场景 推荐
企业级应用、高并发、强一致性 Oracle(功能强大,稳定性高)
Web 应用、快速开发、成本敏感 MySQL(生态丰富,上手快)
学习 SQL 标准 两者都学,注意分页、自增、事务差异

2.1基本概念和类型

Oracle的约束条件:

1.主键约束,2.外键约束,3.默认约束,4.⾮空约束,5.unique 唯⼀约束,Oracle没有⾃增约束

数值类型

类型 说明 示例
NUMBER(p, s) 最常用!p=总位数(1~38),s=小数位(-84~127) NUMBER(10,2) 表示最多 8 位整数 + 2 位小数
INTEGER NUMBER(38) 的别名,无小数 INTEGER
FLOAT(b) 二进制精度浮点数,b 是二进制位(1~126) FLOAT(10)
BINARY_FLOAT / BINARY_DOUBLE IEEE 754 单/双精度浮点(10g+) 高性能科学计算
DECIMAL, NUMERIC NUMBER,兼容 SQL 标准

 字符串类型

类型 最大长度 说明
CHAR(n) 2000 字节 定长,不足补空格(查询时自动去尾空格)
VARCHAR2(n) 4000 字节(12c 之前)
32767 字节(12c+ 开启 extended)
变长,推荐用于所有字符串字段
NCHAR(n) 2000 字符 定长 Unicode(国家字符集)
NVARCHAR2(n) 4000 字符 变长 Unicode
LONG 2GB 已废弃! 不能用于索引、不能在 WHERE 中使用

日期时间类型

类型 精度 说明
date 秒级 包含 年月日时分秒(不含时区)
✅ 最常用
timestamp 纳秒级(默认 6 位小数) DATE 更精确
TIMESTAMP WITH TIME ZONE 带时区 存储时区信息(如 +08:00
TIMESTAMP WITH LOCAL TIME ZONE 本地时区转换 自动转为数据库时区
INTERVAL YEAR TO MONTH 年-月间隔 INTERVAL '2-3' YEAR TO MONTH
INTERVAL DAY TO SECOND 日-秒间隔 INTERVAL '5 12:30:45' DAY TO SECOND

大对象类型

类型 最大容量 用途
CLOB 128TB 存储大文本(如文章、JSON)
NCLOB 128TB Unicode 大文本
BLOB 128TB 存储二进制数据(图片、PDF、视频)
BFILE 操作系统文件指针 指向数据库外部的文件

1. 主键约束(PRIMARY KEY)

  • 自动创建 唯一索引
  • 不允许 NULL
  • 一个表只能有一个主键
CREATE TABLE users (
    id NUMBER PRIMARY KEY,
    name VARCHAR2(50)
);

 2. 唯一约束(UNIQUE)

  • 允许 NULL(且多个 NULL 不冲突)
  • 自动创建唯一索引
ALTER TABLE users ADD CONSTRAINT uk_email UNIQUE(email);

 3. 非空约束(NOT NULL)

  • 只能定义在列级别(不能表级)
  • 不会创建索引
name VARCHAR2(50) NOT NULL

4. 外键约束(FOREIGN KEY)

  • 默认行为:禁止删除父记录ON DELETE NO ACTION
  • 可选:ON DELETE CASCADE(级联删除)
  • 可选:ON DELETE SET NULL(设为空)
CREATE TABLE orders (
    user_id NUMBER REFERENCES users(id) ON DELETE CASCADE
);

 外键列必须有索引(否则 DML 性能极差)


 5. 默认值(DEFAULT)

  • 插入时若未指定值,则用默认值
  • 不会阻止插入 NULL(除非同时加 NOT NULL
created_at DATE DEFAULT SYSDATE

6. 检查约束(CHECK)

这是非常重要的约束类型:

ALTER TABLE employees 
ADD CONSTRAINT chk_salary CHECK (salary > 0 AND salary < 100000);
  • 可用于验证业务规则
  • 支持复杂表达式(但不能用子查询、SYSDATE 等非确定性函数)

7.自增主键

序列直接作为默认值(12c+ 以上)

CREATE TABLE users (
    id NUMBER DEFAULT seq_user_id.NEXTVAL PRIMARY KEY,
    name VARCHAR2(50)
);

IDENTITY 列(新版本推荐)

CREATE TABLE users (
    id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    name VARCHAR2(50)
);
-- 或
    id NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY

2.2sql语句

2.2.1创建表

create table t_user(
id NUMBER primary key,
phone varchar2(11),
pass VARCHAR2(20),
ctime date
);

2.2.2新增

insert into t_user(id,phone,pass,ctime) values(1,'110','66666',
TO_DATE('2020-01-01 12:00:00', 'yyyy-MM-dd HH:mi:ss'));
insert into t_user(id,phone,pass,ctime) values(2,'210','66666',
TO_DATE('2020-01-01 12:00:00', 'yyyy-MM-dd HH:mi:ss'));

2.2.3查询

select * from t_user;

select * from t_user where id in (12);
select * from t_user where phone like '1%';

--子查询和联合查询都和mysql一致

2.2.4修改

update t_user set pass='168' where id=1;

2.2.5删除

delete FROM t_user where id=1;

2.2.6分页查询

oracle11版本之前:

-- 查询第 0~10 条
SELECT * FROM (
    SELECT a.*, ROWNUM rn FROM (
        SELECT * FROM t_users ORDER BY id
    ) a WHERE ROWNUM <= 10
) WHERE rn > 0;

执行效果如下:

  • ROWNUM 是 Oracle 伪列,从 1 开始编号
  • 不能直接写 ROWNUM > 20(因为 ROWNUM 在过滤前生成,>20 永远为空)
  • 必须嵌套两层:先限制上限(≤30),再过滤下限(>20)

Oracle 12c 及以上 —— 标准 SQL 分页

-- 查询第 1~10 条
SELECT * FROM users
ORDER BY id
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;
  • 语法清晰,接近 MySQL 的 LIMIT
  • 符合 SQL 标准
  • 性能优化更好

执行效果如下:

注意这种适用于数据量小的情况下,有深分页问题

数据库 高效分页建议
MySQL ORDER BY 索引列 LIMIT N
避免深度分页(如 LIMIT 1000000, 10
Oracle (11g) 同样避免深度分页,考虑用“游标分页”(基于上一页最大 ID)
Oracle (12c+) 优先用 OFFSET/FETCH,但深度分页仍慢

2.2.7分组查询、聚合函数

select count(*),max(id),min(id),avg(id),sum(id) from t_user;
group by  --分组
having   --限制
max min avg sum count -- 聚合函数

2.3存储过程

存储过程:也是函数的⼀种,只是没有返回值
参数类型:
1 .输⼊参数-只读
2 .输出参数-只写
3 .输⼊ 输出参数-读写

接下来代码展示

设置自增主键:

-- 创建序列,从 3 开始,每次加 1 因为我已经加了两条数据
CREATE SEQUENCE seq_t_user_id
    START WITH 3
    INCREMENT BY 1
    NOCACHE;

插入用户:

CREATE OR REPLACE PROCEDURE proc_insert_user(
    p_phone IN VARCHAR2,
    p_pass  IN VARCHAR2
)
AS
BEGIN
    -- 简单插入(实际项目建议对密码加密,如用 DBMS_CRYPTO)
    INSERT INTO t_user (id, phone, pass, ctime)
    VALUES (seq_t_user_id.NEXTVAL, p_phone, p_pass, SYSDATE);
    
    COMMIT;  -- 显式提交(可选,也可由调用者控制)
EXCEPTION
    WHEN DUP_VAL_ON_INDEX THEN
        RAISE_APPLICATION_ERROR(-20001, '手机号已存在(假设 phone 唯一)');
    WHEN OTHERS THEN
        ROLLBACK;
        RAISE;  -- 抛出原始错误
END;
/

调用:

BEGIN
    proc_insert_user('13800138000', 'mypass123');
END;
/

我们来看下执行效果:

我们可以看到调用存储过程成功。

2.4视图

视图:封装查询语句,操作视图就跟操作表⼀样
-- 直接创建视图:取前 2 条(按 id 排序)
CREATE VIEW v_u AS
SELECT *
FROM t_user
ORDER BY id
FETCH FIRST 2 ROWS ONLY;

--使⽤视图
select * from v_u;
--删除视图
drop VIEW v_u;

2.5触发器

触发器:满⾜⼀定条件就会⾃动执⾏定义好的SQL语句
--创建
create trigger t_triu after insert on t_user
for each row
begin
 insert into t_userlog(id,userid,content,ctime)
values(:NEW.id,:NEW.id,'新增了⽤户-',to_date('2021-03-01','yyyy-MM-dd'));
end;
--触发使⽤
insert into t_user(id,phone,pass,ctime)
values(3,'120','abcd',to_date('2021-03-01','yyyy-MM-dd'));
select * from t_userlog;
--删除
drop trigger t_triu;

2.6索引

索引:提⾼查询的效率
底层存储结构: 1 .BTree索引 2 .位图索引
逻辑划分: 1.主键索引 2 .唯⼀索引 3 .普通索引 4 .复合索引
-- 普通索引
CREATE INDEX idx_user_phone ON t_user(phone);

-- 函数索引
CREATE INDEX idx_user_upper_phone ON t_user(UPPER(phone));

-- 位图索引(企业版)
CREATE BITMAP INDEX idx_user_gender ON t_user(gender);

之后准备单独出一篇文章将索引,这不在仔细描述

2.7函数

函数:实现特定功能的代码块
-- 函数
create FUNCTION f_u(n1 NUMBER,n2 NUMBER) return NUMBER
as
begin
 return n1+n2;
end;
--使⽤
select f_u(id,userid) from t_userlog;
-- 删除
drop FUNCTION f_u;

2.8序列

序列:Oracle独有的,专⻔⽤来⽣成数字的⼀种结构体
常常⽤来所为主键的⾃增
-- 序列
create sequence 序列名称
increment by 增量
start with 起始值
max|min 最⼤|最⼩
cache|nocache 是否缓存
cycle|nocycle 是否循环
--创建
create sequence seq_id;
--使⽤序列
insert into t_userlog(id,userid,content,ctime)
values(seq_id.nextval,1,'测试序列',to_date('2021-03-01','yyyy-MMdd'));
select seq_id.currval from t_userlog;
--删除
drop sequence seq_id;
重要属性:
nextval:下⼀个值
currval:当前值

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐