`

oracle主键和外键

阅读更多
主键和外键

CREATE TABLE "SCOTT"."MID_A_TAB" 
   (	"A" VARCHAR2(20 BYTE), 
	"B" VARCHAR2(10 BYTE), 
	"DETPNO" VARCHAR2(10 BYTE)	
   )TABLESPACE "USERS" ;

CREATE TABLE "SCOTT"."MID_B_TAB" 
   (	"A" VARCHAR2(20 BYTE), 
	"B" VARCHAR2(10 BYTE), 
	"DEPTNO" VARCHAR2(10 BYTE)
   )TABLESPACE "USERS" ;

--给MID_A_TAB表添加主键
alter table mid_a_tab add constraint a_pk primary key (detpno);
--给MID_B_TAB表添加主键
alter table mid_b_tab add constraint b_pk primary key(a);
--给子表MID_B_TAB添加外键,并且引用主表MID_A_TAB的DETPNO列,并通过on delete cascade指定引用行为是级联删除
alter table mid_b_tab add constraint b_fk foreign key (deptno) references mid_a_tab (detpno) on delete cascade;
--向这样就创建了好子表和主表
向主表添加数据记录
SQL> insert into mid_a_tab(a,b,detpno)  values('1','1','10');

已创建 1 行。

已用时间:  00: 00: 00.00
向子表添加数据
SQL> insert into mid_b_tab(a,b,deptno) values('1','2','6');
insert into mid_b_tab values('1','2','6')
*
第 1 行出现错误:
ORA-00001: 违反唯一约束条件 (SCOTT.B_PK)


已用时间:  00: 00: 00.00
可见上面的异常信息,那时因为子表插入的deptno的值是6,然而此时我们主表中
detpno列只有一条记录那就是10,所以当子表插入数据时,在父表中不能够找到该引用
列的记录,所以出现异常。

但我们可以这样对子表的数据的进行插入(即:在子表的deptno列插入null,因为我们在建表的时候
并没有对该列进行not null的约束限制):
SQL> insert into mid_b_tab(a,b,deptno) values('3','2',null);

已创建 1 行。

已用时间:  00: 00: 00.00

现在如果我们把子表mid_b_tab中deptno列加上not null约束。

SQL> alter table mid_b_tab modify deptno not null;
alter table mid_b_tab modify deptno not null
*
第 1 行出现错误:
ORA-02296: 无法启用 (SCOTT.) - 找到空值

已用时间:  00: 00: 00.01
上面又出现异常,这是因为现在mid_b_tab表中有了一条记录,就是我们先前添加的
那条记录。
3,2,null
现在我们要把该表的deptno列进行not null约束限制,所以oracle不让我们这样干。
那我们就只有把该表给delete或truncate掉,然后在修改deptno列为非空。
SQL> delete from mid_b_tab;

已删除2行。

已用时间:  00: 00: 00.01
再次修改子表mid_b_tab表的deptno列为非空。
SQL> alter table mid_b_tab modify deptno not null;

表已更改。

已用时间:  00: 00: 00.01
修改成功!
我们再次插入数据
insert into mid_b_tab(a,b,deptno) values('13','2',null);试试。
SQL> insert into mid_b_tab(a,b,deptno) values('13','2',null);
insert into mid_b_tab(a,b,deptno) values('13','2',null)
                                                  *
第 1 行出现错误:
ORA-01400: 无法将 NULL 插入 ("SCOTT"."MID_B_TAB"."DEPTNO")


已用时间:  00: 00: 00.00
看见现在oracle不让我们插入空值了。
所以我们在创建子表的外键约束时,该表的引用列必须要进行not null限制,也可以在
该列创建unique,或primary key约束,并且引用列与被引用列的数据类型必须相同。

SQL> insert into mid_b_tab(a,b,deptno) values('13','2','10');

已创建 1 行。

已用时间:  00: 00: 00.01
此时数据插入成功,因为此时插入的10,在主表中的被引用列中已经存在了。

现在我们一系列的操作:
SQL> select * from mid_b_tab ;

A                    B          DE
-------------------- ---------- --
13                   2          10

已用时间:  00: 00: 00.00
SQL> select * from mid_a_tab;

A                    B          DE
-------------------- ---------- --
1                    1          10

已用时间:  00: 00: 00.00
SQL> delete from mid_a_tab;

已删除 1 行。

已用时间:  00: 00: 00.01
SQL> select * from mid_b_tab;

未选定行
从上边的操作中可以看出当我们删除了主表中的记录后,子表中相应的记录
也被级联删除掉了。

通过引用行为可以确定如何处理子表中的外键字段。引用类型包括3中类型:
1.on delete cascade;--级联删除
2.on set null;--删除主表中的记录后,子表中的相应记录的列被设置为null(但子表的该字段必须支持null值)。
3.on no action;--不允许删除主表中被引用的数据,该操作会被禁止。

如果有on delete cascade,而且没有在子表上加索引:那么每删除主表中的一行
都会对子表做一个全表扫描。而且如果从父表删除多行,那么每从父表中删除一行
就要扫描一次子表。

SQL> select * from mid_a_tab a,mid_b_tab b where
  2  a.detpno=b.deptno;

A                    B          DETPNO     A                    B          DEPTNO
-------------------- ---------- ---------- -------------------- ---------- ----------
1                    2          12         2                    2          12
1                    2          12         1                    1          12
2                    22         13         22                   212        13
3                    33         14         55                   6666       14

已用时间:  00: 00: 00.00

执行计划
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=7 Card=4 Bytes=208
          )

   1    0   HASH JOIN (Cost=7 Card=4 Bytes=208)
   2    1     TABLE ACCESS (FULL) OF 'MID_A_TAB' (TABLE) (Cost=3 Card=
          3 Bytes=78)

   3    1     TABLE ACCESS (FULL) OF 'MID_B_TAB' (TABLE) (Cost=3 Card=
          4 Bytes=104)





统计信息
----------------------------------------------------------
        210  recursive calls
          0  db block gets
         74  consistent gets
          0  physical reads
          0  redo size
        748  bytes sent via SQL*Net to client
        512  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          8  sorts (memory)
          0  sorts (disk)
          4  rows processed

SQL> create index mid_b_index on mid_b_tab(deptno);

索引已创建。

已用时间:  00: 00: 00.00
SQL> select * from mid_a_tab a,mid_b_tab b where
  2   a.detpno=b.deptno;

A                    B          DETPNO     A                    B          DE
-------------------- ---------- ---------- -------------------- ---------- --
1                    2          12         2                    2          12
1                    2          12         1                    1          12
2                    22         13         22                   212        13
3                    33         14         55                   6666       14

已用时间:  00: 00: 00.01

执行计划
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=6 Card=4 Bytes=208
          )

   1    0   TABLE ACCESS (BY INDEX ROWID) OF 'MID_B_TAB' (TABLE) (Cost
          =1 Card=1 Bytes=26)

   2    1     NESTED LOOPS (Cost=6 Card=4 Bytes=208)
   3    2       TABLE ACCESS (FULL) OF 'MID_A_TAB' (TABLE) (Cost=3 Car
          d=3 Bytes=78)

   4    2       INDEX (RANGE SCAN) OF 'MID_B_INDEX' (INDEX) (Cost=0 Ca
          rd=4)





统计信息
----------------------------------------------------------
         10  recursive calls
          0  db block gets
         31  consistent gets
          0  physical reads
          0  redo size
        748  bytes sent via SQL*Net to client
        512  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          2  sorts (memory)
          0  sorts (disk)
          4  rows processed

大家可以从上面的执行计划中看出,向子表添加索引前后查询的差别。如果两表中的数据量再大点
的话那么效果可能会更明显。
分享到:
评论

相关推荐

    oracle主键和外键[文].pdf

    在Oracle数据库中,主键和外键是关系型数据库中非常重要的概念,它们用于确保数据的一致性和完整性。主键是定义在一个表中用来唯一标识每一行的字段,而外键则是另一个表中的字段,它引用了主键来建立两个表之间的...

    主键和外键.doc

    #### 二、主键、外键和索引的区别 - **主键**:唯一标识一条记录,不允许有重复,不允许为空。 - **外键**:表的外键是另一表的主键,外键可以有重复,可以是空值。 - **索引**:索引字段没有重复值,但可以有一个...

    oracle表主键和外键的区别

    主键和外键都是Oracle等关系型数据库管理系统(RDBMS)中的重要概念。 **主键**是定义一个表中起主要作用的数据项,它确保这些数据项在表中的唯一性。主键的特性包括: 1. 唯一性:主键的值在表中必须是唯一的,不...

    24.Oracle的主键和外键1

    在数据库设计中,主键和外键是确保数据完整性和一致性的重要工具,特别是在Oracle这样的关系型数据库管理系统中。主键和外键的概念以及它们的作用对于理解数据库的结构和操作至关重要。 首先,主键是表的一个或多个...

    ARTools.Oracle抽取指定库的主键、外键、索引

    另附以下功能 * 生成目录树 * 生成迁移脚本 * 查找所有System.out,.err * 批量替换多关键字 详情见 http://blog.csdn.net/amosryan/article/details/6684465

    oracle_创建表空间、表、主键、外键、序列.docx

    在Oracle数据库管理系统中,创建表空间、表、主键、外键和序列是数据库设计的基础操作。以下是对这些概念的详细解释以及如何在Oracle中执行这些操作。 **创建表空间** 表空间是Oracle数据库中存储数据文件的地方。...

    oracle建表练习(主键外键)

    在本次Oracle建表练习中,我们将会重点讨论建表时使用的主键(Primary Key)和外键(Foreign Key)概念。 首先,我们来详细了解一下主键的概念。主键是数据库表中每一行记录的唯一标识,它保证了表中的每条记录都能...

    oracle设置主外键即主键序列自动增长

    下面将详细介绍如何在Oracle中创建包含主键和外键的表,并利用触发器(Trigger)和序列实现主键的自动增长。 #### 一、创建包含主键和外键的表 首先,我们来看一下创建包含主键和外键的表的基本语法和步骤。 ####...

    主键与外键的创建

    在数据库设计中,主键和外键是两个关键概念,它们是关系数据库中确保数据完整性和一致性的核心机制。本文将深入探讨主键与外键的创建,帮助初学者更好地理解这两个概念。 **主键(Primary Key)**是用于唯一标识...

    oracle创建表空间、表、主键、外键、序列

    下面将详细介绍如何创建表空间以及如何在Oracle中创建表、主键、外键和序列。 1. 创建表空间: 在Oracle中,首先需要创建一个表空间来存储未来的数据。以下是一个创建表空间的基本语法: ```sql CREATE TABLESPACE...

    删除数据库的所有表、存储过程、主键、外键、索引等

    总之,删除数据库的所有表、存储过程、主键、外键和索引是一项重要的维护任务,需要谨慎处理。理解这些元素的作用和如何删除它们是数据库管理员的基本技能。正确执行这些操作有助于保持数据库的整洁和高效,同时也为...

    oracle查看主外键约束关系

    其中,user_constraints视图记录了用户拥有的各种类型的约束信息,包括主键、唯一键、外键和检查约束等。每个约束都会有一个对应的名称,并且这个名称作为user_cons_columns视图中的外键出现,后者存储了约束涉及的...

    oracle主外键查询

    ### 一、Oracle数据库中的主键与外键 #### 1. 主键(Primary Key) 主键是用于唯一标识表中每一行记录的一个或多个字段的集合。在一个表中只能定义一个主键,且主键值不允许为空。主键可以由单个字段构成,也可以由...

    Oracle定义约束 外键约束

    ### Oracle定义约束:外键约束详解 #### 一、引言 在数据库设计与管理过程中,维护数据的一致性和完整性是非常重要的。Oracle数据库系统提供了一系列的机制来帮助开发者和管理员达到这一目标,其中最重要的机制之一...

    如何在oracle中查询所有用户表的表名、主键名称、索引、外键等

    根据提供的标题、描述以及部分代码内容,我们可以了解到这篇文章主要探讨的是如何在Oracle数据库中查询所有用户表的相关信息,包括表名、主键名称、索引、外键等元数据信息。接下来,我们将对这些知识点进行详细的...

    MLDN魔乐科技_Oracle课堂18_外键约束

    总之,"MLDN魔乐科技_Oracle课堂18_外键约束"课程旨在帮助学习者理解和掌握Oracle数据库中外键约束的概念、用法及其重要性,通过实际操作提升数据库设计和管理能力。通过观看提供的文件"MLDN魔乐科技JAVA培训_Oracle...

    PowerDesigner中的CDM设计的外键作主键的问题

    PowerDesigner中的CDM设计的外键作主键的问题 PowerDesigner是一款功能强大的数据建模工具,它提供了丰富的自定义功能,允许用户根据自己的需求对其进行修改和扩展。在PowerDesigner中,我们可以通过编写VBS脚本来...

    Oracle中检查外键是否有索引的SQL脚本分享

    在Oracle数据库管理中,外键是用来维护数据完整性和参照完整性的重要工具。外键约束确保了一个表中的数据(引用)只能指向另一个表中存在的数据(主键)。然而,为了提高查询性能,外键列通常需要创建索引。这篇分享...

    在Oracle数据库中添加外键约束的方法详解

    在Oracle数据库中,外键约束是确保数据完整性和一致性的重要机制。它定义了一个表中的一个或多个列(称为外键)的值必须匹配另一个表(称为参照表)中某些行的值,以此来维护两个表之间的关系。这有助于保证两个表...

    MLDN魔乐科技JAVA培训_Oracle课堂18_外键约束.rar

    在本MLDN魔乐科技JAVA培训_Oracle课堂18_外键约束的课程中,我们将深入探讨这个主题,帮助Java开发者更好地理解和应用Oracle数据库中的外键约束。 首先,我们了解外键的基本概念。外键是一种特殊的字段,存在于一个...

Global site tag (gtag.js) - Google Analytics