-- 创建测试主表. ID 是主键.

CREATE TABLE test_main (

id      INT,

value   VARCHAR(10),

PRIMARY KEY(id)

);

-- 创建测试子表.

CREATE TABLE test_sub (

id      INT,

main_id INT,

value   VARCHAR(10),

PRIMARY KEY(id)

);

-- 插入测试主表数据.

INSERT INTO test_main(id, value) VALUES (1,'ONE');

INSERT INTO test_main(id, value) VALUES (2,'TWO');

-- 插入测试子表数据.

INSERT INTO test_sub(id, main_id, value)VALUES (1, 1, 'ONEONE');

INSERT INTO test_sub(id, main_id, value)VALUES (2, 2, 'TWOTWO');

SQL> -- 创建外键(默认选项)

SQL> ALTER TABLE test_sub ADD CONSTRAINT main_id_cons  FOREIGN KEY (main_id)  REFERENCES test_main;

Table altered.

SQL>

SQL> -- 测试删除主表数据. 将出错 ORA-02292:违反完整约束条件

SQL> DELETE

2    test_main

3  WHERE

4    ID = 1;

DELETE

*

ERROR at line 1:

ORA-02292: integrity constraint(HR.MAIN_ID_CONS) violated - child record found

测试完毕后,删除外键约束

ALTER TABLE test_subDROP CONSTRAINT main_id_cons;

SQL> -- 创建外键(使用 ON DELETECASCADE 选项,删除主表的时候,同时删除子表)

SQL> ALTER TABLE test_sub

2    ADDCONSTRAINT main_id_cons

3     FOREIGN KEY (main_id) REFERENCES  test_main  ON DELETECASCADE;

Table altered.

SQL>

SQL> -- 测试删除主表数据. 将成功地执行.

SQL> DELETE

2    TEST_MAIN

3  WHERE

4    ID = 1;

1 row deleted.

SQL>

SQL> -- 测试检索子表,应该只有一条 main_id = 2 的数据.

SQL> SELECT

2    *

3  FROM

4    test_sub;

ID    MAIN_ID VALUE

---------- ---------- --------------------

2          2 TWOTWO

测试完毕后,删除外键约束

ALTER TABLE test_sub DROP CONSTRAINT main_id_cons;

SQL> -- 创建外键(使用 ON DELETESET NULL 选项,删除主表的时候,同时将子表的 main

_id 设置为 NULL)

SQL> ALTER TABLE test_sub

2   ADD CONSTRAINT main_id_cons

3     FOREIGN KEY (main_id) REFERENCES  test_main  ON DELETE SET NULL;

Table altered.

SQL>

SQL>

SQL> -- 测试删除主表数据. 将成功地执行.

SQL> DELETE

2    TEST_MAIN

3  WHERE

4    ID = 2;

1 row deleted.

SQL>

SQL> -- 测试检索子表,应该有一条的 main_id = null

SQL> SELECT

2    *

3  FROM

4    test_sub;

ID    MAIN_ID VALUE

---------- ---------- --------------------

2            TWOTWO

测试完毕后,删除外键约束

ALTER TABLE test_sub DROP CONSTRAINT main_id_cons;

启用/禁用

当遇到批量数据导入的时候,如果外键处于有效的状态。

那么要求 数据导入的程序, 必须先导入主表的数据,然后再导入子表的数据。

如果表多,且关系复杂的话,会增加很大的工作量。

可以在数据导入以前, 先暂时禁用外键约束。

子表、主表数据都导入完毕后, 再启用外键约束。

以下测试环境为 初始的创建表、初始数据的情况。

SQL> -- 创建外键(默认选项)

SQL> ALTER TABLE test_sub ADD CONSTRAINT main_id_cons  FOREIGN KEY (main_id)  REFERENCES  test_main;

表已更改。

SQL> -- 测试插入子表数据. 将出错 ORA-02291: 违反完整约束条件

SQL> INSERT INTO test_sub (ID, MAIN_ID, VALUE) VALUES (3, 3, 'THREETHREE');

INSERT INTO test_sub (ID, MAIN_ID, VALUE) VALUES (3, 3, 'THREETHREE')

*

ERROR 位于第 1 行:

ORA-02291: 违反完整约束条件 (TEST.MAIN_ID_CONS) - 未找到父项关键字

-- 尝试禁用外键约束.

SQL> ALTER TABLE test_sub  MODIFY   CONSTRAINT main_id_cons DISABLE;

表已更改。

SQL> INSERT INTO test_sub (ID, MAIN_ID, VALUE) VALUES (3, 3, 'THREETHREE');

已创建 1 行。

SQL> INSERT INTO test_main(id, value) VALUES (3, 'THREE');

已创建 1 行。

SQL> commit;

提交完成。

-- 恢复启用外键约束.

SQL> ALTER TABLE test_sub  MODIFY   CONSTRAINT main_id_cons  ENABLE;

表已更改。

SQL> DELETE test_main  WHERE ID = 1;

DELETE test_main  WHERE ID = 1

*

ERROR 位于第 1 行:

ORA-02292: 违反完整约束条件 (TEST.MAIN_ID_CONS) - 已找到子记录

测试完毕后,删除外键约束

ALTER TABLE test_sub DROP CONSTRAINT main_id_cons;

延迟约束

在编程开发环境中,可能会遇到,要先插入子表, 然后插入主表。

或者先更新主表的 主键, 然后更新子表的外键的情况。

由于是开发环境下,因此不适合使用 先 DISABLE 再 ENABLE 的处理机制。

原因是程序中可能会存在并发处理

也就是

用户A   DISABLE -- 更新处理  -- ENABLE

用户B              DISABLE -- 更新处理  -- ENABLE

这种情况下,需要启用 延迟约束

也就是 INSERT / UPDATE 语句执行的时候, 暂时不检查数据的完整性,等到 Commit 的时候,统一做检查。

SQL> -- 创建外键(默认选项)

SQL> ALTER TABLE test_sub ADD CONSTRAINT main_id_cons

2    FOREIGN KEY (main_id)  REFERENCES  test_main

3    DEFERRABLE   INITIALLY DEFERRED;

表已更改。

SQL> INSERT INTO test_sub (ID, MAIN_ID, VALUE) VALUES (4, 4, 'FOURFOUR');

已创建 1 行。

SQL> commit;

commit

*

ERROR 位于第 1 行:

ORA-02091: 事务处理已回退

ORA-02291: 违反完整约束条件 (TEST.MAIN_ID_CONS) - 未找到父项关键字

SQL> INSERT INTO test_sub (ID, MAIN_ID, VALUE) VALUES (4, 4, 'FOURFOUR');

已创建 1 行。

SQL> INSERT INTO test_main(id, value) VALUES (4, 'FOUR');

已创建 1 行。

SQL> commit;

提交完成。

外键索引

啥时不需要外键索引?

Expert one-on-one Oracle中提到:

You do not delete from the parent table.

You do not update the parent tables unique/primary key value, either purposely or by accident (via a tool).

这两种情况下,没有外键索引,Oracle会锁子表,当使用ON DELETE CASCADE时,会进行全表扫描。

You do not join from the parent table to the child table, of more generally ‐ the foreign key columns do not support an important access path to the child table.

利用join查询时,没有外键索引,Oracle就会进行全表扫描。

当确认这些情况不会出现时,便可以不添加外键索引,但是,如何监测子表是否被锁呢?

Oracle有一个机制:

ALTER TABLE DISABLE TABLE LOCK;

这时,UPDATE和DELETE获取锁是都会失败。

不从父表删除记录很难避免,因此,如果没有外键索引,将很容易导致死锁,缺外键索引是死锁的主要原因,另外,位图索引的并发更新也是可能导致死锁。

以下是ORACLE Database Concept上的描述,记录一下:

Indexes and Foreign Keys

As a rule, foreign keys should be indexed. The only exception is when the matching unique or primary key is never updated or deleted. Indexing the foreign keys in child

tables provides the following benefits:

■ Prevents a full table lock on the child table. Instead, the database acquires a row

lock on the index.

■ Removes the need for a full table scan of the child table. As an illustration,

assume that a user removes the record for department 10 from the departments

table. If employees.department_id is not indexed, then the database must scan

employees to see if any employees exist in department 10.

Oracle外键约束reference,oracle外键约束相关推荐

  1. oracle_sqlserver和mysql获取表外键的方法_mysql、sqlserver、oracle三种数据库维护索引、外键、字段语法总结...

    mysql.sqlserver.oracle三种数据库维护索引.外键.字段语法总结 1.     MYSQL数据库 1)    创建索引 CREATE INDEX index_name ON tabl ...

  2. 数据库六大约束用法:主键(primary key)、外键(foreign key)、非空(not null)、默认(default)、检查(check)、唯一(unique)

    1. 数据库有六大约束 主键(primary key) 外键(foreign key):被参照的键必须有唯一约束或是主键 非空(not null) 默认(default) 检查(check):orac ...

  3. mysql中ak替换键_数据库:唯一性约束_alternate key(替换键) mySQL Oracle 数据库 ak 唯一性约束...

    数据库:唯一性约束_alternate key(替换键) mySQL Oracle 数据库 ak 唯一性约束 数据库:唯一性约束 所谓唯一性约束(unique constraint)不过是数据表内替代 ...

  4. [数据库03]-约束(唯一性-主键-外键/存储引擎/事务/索引/视图/DBA命令/数据库设计三范式

    [数据库03]-约束(唯一性-主键-外键)/存储引擎/事务/索引/视图/DBA命令/数据库设计三范式 一.约束 1.1 唯一性约束(unique) 1.2 主键约束 1.3 外键约束 二.存储引擎 2 ...

  5. 数据库名词解释 主键外键检查 非空、唯一性约束 父表 子表

    Oracle数据库中,约束具体包括非空(NOT NULL)约束.唯一键(UNIQUE)约束.主键(PRIMARY KEY)约束.外键(FOREIGN KEY)约束和检查(CHECK)约束五种. 1:主 ...

  6. SQL约束(主键约束 primary key、外键约束 foreign key、唯一约束unique 、CHECK约束)

    注意: A.表中有数据不能创建约束 B.视图下设置后,要点击保存(只有保存后在才看的到) c   别忘了,点刷新,才会出来呀! 1.主键约束 primary key 主键是每行的唯一标识符,仅仅通过它 ...

  7. oracle主键约束删除,oracle删除主键查看主键约束及创建联合主键

    oracle删除主键查看主键约束及创建联合主键 1,主键的删除 ALTER TABLE TABLENAME DROP PRIMARY_KEY 执行上面的SQL可以删除主键:如果不成功可以用 ALTER ...

  8. mysql 约束基本概念 主键约束 外键约束

    constraint   约束数据(对表中数据的限制条件) 四种条件约束:非空  唯一性  主键约束 外键约束 非空约束(not null)约束的字段不能为空值,必须赋具体的数据 CREATE TAB ...

  9. oracle删除unique key,【PK】Oracle 10g删除主键约束后无法删除唯一约束索引问题的模拟与分析...

    当先创建唯一约束后再创建主键约束的情况下,如果使用普通方法删除主键约束后,唯一约束索引不会被删除,这是Oracle 10g的一个PROBLEM.本文通过一个实验给大家演示一下这个问题的出现过程及处理方 ...

最新文章

  1. Cell子刊:粘上你-细菌生长素介导的植物根部细菌定殖
  2. Apache Tuscany 宣布停止维护
  3. shardingjdbc全局表_Sharding-JDBC 分库分表概述
  4. mysql执行底层_天天写order by,你知道Mysql底层如何执行吗?
  5. 【图像处理opencv】_图像几何变换
  6. 浅析WebRtc中视频数据的接收和渲染流程
  7. Tech.Ed 2008
  8. idea在分屏拖不回来_朋友圈赏花晒照新玩法,宫格分屏视频!
  9. 查阅 arXiv 论文新神器,一行代码比较版本差别,Github 新开源!
  10. java实现定时任务 schedule_Java定时任务的三种实现方式
  11. Rails UVA - 514(栈)
  12. 从“No space left on device”到删除海量文件
  13. bzoj 2326: [HNOI2011]数学作业(矩阵快速幂)
  14. Web服务器 之 关于Apache (httpd)服务器防DDOS模块mod_evasive的使用说明
  15. [C/C++11语法]_[0基础]_[lamba 表达式介绍]
  16. mysql group by 分组查询
  17. 【Sentry使用】自定义transaction
  18. android mcc mnc,SystemUI如何获得SIM卡相关的mcc/mnc值
  19. Django 可重用注册登录系统
  20. 如何快速增加qq名片赞

热门文章

  1. 控制理论与应用latex模板用texlive
  2. RBF网络插值、MNIST识别简例
  3. matlab 思维进化算法,差分进化算法介绍及matlab实现
  4. “好奇号”火星车的坚固车轮
  5. java获取inputstream_java InputStream读取数据问题
  6. C#从电子秤读取称重数值
  7. 分布式事务数据一致性解决方案(一)
  8. ARTONE的艺术美学:为笔记本注入时尚灵魂
  9. 【编译原理】计算机考研复试问答题总结
  10. 记重装Win10踩过的坑