Oracle 19c约束开发文档

1. 概述

1.1 约束定义

约束(Constraint)是Oracle数据库中用于确保数据完整性的规则,通过限制列中可存储的值或多列间的关系,保证数据符合业务规则。Oracle 19c支持多种约束类型,且在兼容性和性能上对约束机制进行了优化。

1.2 约束作用

  • 保证数据准确性(如主键唯一标识记录)
  • 维护数据一致性(如外键关联父表数据)
  • 减少应用层数据校验逻辑,降低冗余开发

2. 约束类型及语法

2.1 主键约束(PRIMARY KEY)

定义

唯一标识表中的每条记录,要求列值非空且唯一,一个表只能有一个主键。

语法示例-- 建表时创建(列级)
CREATE TABLE employees ( emp_id NUMBER(10) CONSTRAINT emp_pk PRIMARY KEY, emp_name VARCHAR2(50) NOT NULL );

-- 建表时创建(表级,支持复合主键) 
CREATE TABLE employee_roles ( emp_id NUMBER(10), role_id NUMBER(10), CONSTRAINT emp_role_pk PRIMARY KEY (emp_id, role_id) );

-- 建表后添加 
ALTER TABLE departments ADD CONSTRAINT dept_pk PRIMARY KEY (dept_id);

2.2 外键约束(FOREIGN KEY)

定义

用于维护两个表之间的关联关系,外键列的值必须匹配父表主键列的值或为NULL。

语法示例-- 基础外键(引用父表主键)
CREATE TABLE employees ( emp_id NUMBER(10) PRIMARY KEY, dept_id NUMBER(10), CONSTRAINT emp_dept_fk FOREIGN KEY (dept_id) REFERENCES departments(dept_id) );

-- 带级联操作的外键(Oracle 19c支持) 
CREATE TABLE orders ( order_id NUMBER(10) PRIMARY KEY, cust_id NUMBER(10), CONSTRAINT ord_cust_fk FOREIGN KEY (cust_id) REFERENCES customers(cust_id) 
ON DELETE CASCADE -- 父表记录删除时,子表关联记录同步删除 
ON UPDATE SET NULL -- 父表主键更新时,子表外键设为NULL );

2.3 唯一约束(UNIQUE)

定义

确保列或列组合的值唯一,但允许NULL值(多个NULL不视为重复)。

语法示例-- 单列唯一
CREATE TABLE users ( user_id NUMBER(10) PRIMARY KEY, email VARCHAR2(100) CONSTRAINT uk_email UNIQUE );

-- 多列唯一(组合值唯一) 
CREATE TABLE products ( prod_id NUMBER(10) PRIMARY KEY, prod_code VARCHAR2(20), version NUMBER(3), CONSTRAINT uk_prod_version UNIQUE (prod_code, version) );

2.4 检查约束(CHECK)

定义

限制列值必须满足指定条件,Oracle 19c支持更复杂的条件表达式(如子查询除外)。

语法示例-- 基础检查(数值范围)
CREATE TABLE employees ( emp_id NUMBER(10) PRIMARY KEY, salary NUMBER(10,2) CONSTRAINT chk_salary CHECK (salary > 0), hire_date DATE CONSTRAINT chk_hire_date CHECK (hire_date <= SYSDATE) );

-- 字符串匹配检查 
CREATE TABLE customers ( cust_id NUMBER(10) PRIMARY KEY, gender CHAR(1) CONSTRAINT chk_gender CHECK (gender IN ('M', 'F', 'U')) );

-- 多列关联检查(表级约束) 
CREATE TABLE orders ( order_id NUMBER(10) PRIMARY KEY, order_date DATE, ship_date DATE, CONSTRAINT chk_dates CHECK (ship_date >= order_date) );

2.5 非空约束(NOT NULL)

定义

强制列不能包含NULL值,是唯一只能定义在列级的约束。

CREATE TABLE employees (
emp_id NUMBER(10) PRIMARY KEY,
emp_name VARCHAR2(50) CONSTRAINT nn_emp_name NOT NULL,
phone VARCHAR2(20)  -- 允许NULL

);

-- 建表后添加非空约束(需确保列无NULL值) 
ALTER TABLE employees MODIFY (email VARCHAR2(100) CONSTRAINT nn_emp_email NOT NULL);

​

3. 约束管理与维护

3.1 查看约束信息-- 查询表的所有约束

SELECT constraint_name, constraint_type, search_condition, status FROM user_constraints WHERE table_name = 'EMPLOYEES';

-- 查询约束对应的列 
SELECT constraint_name, column_name, position FROM user_cons_columns WHERE table_name = 'EMPLOYEES';

3.2 启用/禁用约束-- 禁用约束(保留定义,暂时不生效)

ALTER TABLE employees DISABLE CONSTRAINT emp_dept_fk;

-- 启用约束(重新生效,自动校验现有数据) 
ALTER TABLE employees enable CONSTRAINT emp_dept_fk;

-- 启用约束时跳过数据校验(适用于大量历史数据,Oracle 19c高效支持) 
ALTER TABLE employees enable NOVALIDATE CONSTRAINT emp_dept_fk;

3.3 删除约束ALTER TABLE employees

DROP CONSTRAINT uk_email;-- 删除主键约束(若有外键引用,需先删除外键或级联删除) 
ALTER TABLE departments DROP PRIMARY KEY CASCADE; -- 级联删除引用该主键的外键

3.4 修改约束(重命名)ALTER TABLE employees

RENAME CONSTRAINT chk_salary TO chk_emp_salary;

4. Oracle 19c约束增强特性

4.1 非空约束增强

支持在ALTER TABLE MODIFY时更灵活地修改非空约束,无需重建表:

-- 从非空改为可空 
ALTER TABLE employees MODIFY (phone NULL);

-- 从可空改为非空(需确保列无NULL值) 
ALTER TABLE employees MODIFY (phone CONSTRAINT nn_emp_phone NOT NULL);

4.2 检查约束性能优化

Oracle 19c对检查约束的解析和执行进行了优化,尤其是包含函数的复杂条件(如CHECK (LENGTH(emp_name) > 2)),执行效率较12c提升约30%。

4.3 延迟约束验证

支持事务提交时再验证约束(默认即时验证),适合批量插入/更新场景:-- 创建延迟约束

-- 事务中暂时允许违反约束,提交时验证
CREATE TABLE transactions ( trans_id NUMBER(10) PRIMARY KEY, amount NUMBER(10,2), CONSTRAINT chk_amount CHECK (amount > 0) DEFERRABLE INITIALLY DEFERRED );

 
INSERT INTO transactions VALUES (1, -100); -- 不报错 COMMIT; -- 提交时校验,报错并回滚

5. 最佳实践

5.1 命名规范

  • 主键:PK_<表名>(如PK_EMPLOYEES
  • 外键:FK_<子表名>_<父表名>(如FK_EMP_DEPT
  • 唯一约束:UK_<表名>_<列名>(如UK_USERS_EMAIL
  • 检查约束:CHK_<表名>_<列名>(如CHK_EMP_SALARY
  • 非空约束:NN_<表名>_<列名>(如NN_EMP_NAME

5.2 性能考虑

  • 避免在频繁更新的列上创建过多约束(尤其是检查约束)
  • 复合主键的列顺序应基于查询频率(高频过滤列在前)
  • 外键关联的列建议建立索引(避免父表删除/更新时全表扫描):
    CREATE INDEX idx_emp_dept ON employees(dept_id);  -- 外键列索引
    

5.3 业务适配

  • 历史数据迁移时,可先禁用约束,迁移完成后启用NOVALIDATE(跳过历史数据校验)
  • 复杂业务规则优先用检查约束(数据库层保障),而非仅依赖应用程序
  • 外键的级联操作需谨慎使用(ON DELETE CASCADE可能导致批量数据删除)

6. 常见问题及解决

6.1 约束冲突报错

  • 错误ORA-00001: 违反唯一约束条件
  • 解决:检查插入/更新的值是否重复,或使用MERGE语句避免重复插入

6.2 外键引用失败

  • 错误ORA-02291: 完整性约束条件 violated - 未找到父项关键字
  • 解决:确保子表外键值在父表中存在,或允许外键为NULL

6.3 启用约束失败

  • 错误ORA-02293: 无法验证约束 - 找到违反约束的数据
  • 解决:清理不符合约束的脏数据,或使用ENABLE NOVALIDATE跳过验证
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值