您现在的位置: 365建站网 > 365学习 > 什么是数据库主键约束 primary key、外键约束 foreign key、唯一约束unique)

什么是数据库主键约束 primary key、外键约束 foreign key、唯一约束unique)

文章来源:365jz.com     点击数:464    更新时间:2018-10-25 08:59   参与评论

注意:

A.表中有数据不能创建约束

B.视图下设置后,要点击保存(只有保存后在1.jpg才看的到)


2.jpg



c   别忘了,点刷新,才会出来呀!

3.jpg

一、五种约束

如果DML操作所涉及数据违反了已定义的约束,则数据库系统将拒绝执行这样的操作。

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

和数据表类似,约束也属于数据库对象,可以在建表的同时创建其相关约束,也可以在建表后单独添加;可以由用户命名,也可以由系统按照默认格式自动对约束进行命名;按照约束的定义位置,又可以分为表级约束和字段级约束两种。

建表的同时创建约束的的语法格式为:

其中,column_constraint为字段级约束,字段级约束在字段定义时一并给出,也只能约束其所属的单个字段;table_constraints为表级约束,与表中的字段并列定义,可以约束单个或多个字段。

1、非空约束(只能在字段级定义)

例子:

查询数据字典视图user_constraints可得到其具体名称,SQL语句如下:

2、唯一性约束(列中最多有一个空值)unique

Oracle会自动为唯一性约束的字段创建相应的唯一性索引。唯一性约束既可以在字段级定义、也可以在表级定义。

如果要在两个或两个以上字段上定义联合唯一键(字段组合不允许出现空值),就只能定义为表级约束了,例如:


alter table Account
    add constraint AK_AccountName    --约束名
    unique (Account_Name)    -- 列名

3、主键约束(非空且唯一)primary key

只允许一个主键,主键可以是单个字段或多字段的组合(联合主键),Oracle会自动为主键字段创建对应的唯一性索引。主键约束既可以在字段级定义、也可以在表级定义。

区别:主键是唯一的。

联合主键只能定义为表级约束:



4.jpg


alter table t_group  

  alter column id int not null      --修改字段类型

go



alter table t_group

  add constraint pk_group_Id --字段创建主键约束

  primary key(id)

go


4、外键约束 foreign key

表级、字段级均可。

外键约束的特征:

(1)子表外键字段的值必须在主表被参照字段值得范围内,或者为NULL;

(2)外键参照的必须是主表的主键或唯一键(??);

(3)主表主键/唯一键被子表参照时,主表相应记录不允许被删除。

使用外键约束的相关原则:

(1)创建数据表时,先创建主表,后创建子表;删除表的顺序相反;

(2)添加数据时,先向主表中添加/插入记录,后向子表添加记录;删除数据操作顺序相反;

(3)修改数据(UPDATE)的情况要复杂一些,通常使用触发器实现。

外键约束可以和主键约束同时使用:

外键约束也可能构建于同一个表内部的两个字段之间:


外键既能确保数据完整性,也能表现表之间的关系。添加了外键之后,插入引用表的记录要么必须被引用表中被引用列的某条记录匹配,要么外键列的值必须设置为NULL。


  外键和主键不一样,每个表中的外键数目不限制唯一性。在每个表中,每一有-~253个外键。唯一的限制是一个列只能引用一个外键。一个列可以被多个外键引用。


如果表A的主关键字是表B中的字段,则该字段称为表B的外键,表A称为主表,表B称为从表。外键是用来实现参照完整性的。


比如说:



create table t_group (   
    id int not null,   
    name varchar(30),   
    primary key (id)   
);  
 
insert into t_group values (1, 'Group1');   
insert into t_group values (2, 'Group2');
 
create table t_user (   
    id int not null,   
    name varchar(30),   
    groupid int,   
    primary key (id),   
    foreign key (groupid) references t_group(id) on delete cascade on update cascade  
);  
 
insert into t_user values (1, 'qianxin', 1); --可以插入   
insert into t_user values (2, 'yiyu', 2);    --可以插入   
insert into t_user values (3, 'dai', 3);    --错误,无法插入,用户组3不存在,与参照完整性约束不符 
 
insert into t_user values (1, 'qianxin', 1);   
insert into t_user values (2, 'yiyu', 2);   
insert into t_user values (3, 'dai', 2);   
delete from t_group where id=2;              --导致t_user中的2、3记录级联删除   
update t_group set id=2 where id=1;          --导致t_user中的1记录的groupid级联修改为2


主键表和外键表的理解

(1)以公共关键字作主键的表为主键表(父表,主表)

(2)以公共关键字作外键的表为外键表(从表,外表)

 

举个例子:

这里有2张表(student和depart)学生表和院系表,这里的字段departNum就是学生表的外键,这里的外键表是学生表,主键表是院系表。

 

外键的作用

各种书籍和网上的资料大多都是抽象空洞的解释:保证数据的完整性和一致性。

个人对此的理解与接下来的外键约束一起讲。


Mysql 下,外键设置:

on delete  规则:

1、CASCADE:级联

   (1)所谓的级联删除,就是删除主键表的同时,外键表同时删除。

   (2)以上面的例子将就是,假如院系表中的某个院系被删除了,那么在学生表中要想查询这个被删除的院系号所对应的院信息就会报错,因为已经不存在这个系了,所以,删除院系表(主键表)时必须删除其他与之关联的表,这里就说明了外键的作用,保持数据的一致性、完整性。当然反过来讲,你删除学生表中的记录,并不影响院系表中的数据,你查询院系号也能正确查询。所以删除外键表中的数据并不影响主键表。


2、NO ACTION(非活动,默认)、RESTRICT:约束/限制
  当取值为No Action或者Restrict时,则当在主键表中删除对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除。(即外键表约束主键表)
3、SET NULL
    当取值为Set Null时,则当在主键表中删除对应记录时,首先检查该记录是否有对应外键,如果有则设置子表中该外键值为null(,一样是外键表约束主键表,不过这就要求该外键允许取null)。

NO ACTION和RESTRICT的区别:只有在及个别的情况下会导致区别,前者是在其他约束的动作之后执行,后者具有最高的优先权执行。

实际应用

对象模型中的数据如下:

package org.model;  
  
public class Student {  
private String stuNum;  
private String stuName;  
<span style="color:#FF0000;">private Depart depart;</span>  
public String getStuNum() {  
    return stuNum;  
}  
public String getStuName() {  
    return stuName;  
}  
public Depart getDepart() {  
    return depart;  
}  
public void setStuNum(String stuNum) {  
    this.stuNum = stuNum;  
}  
public void setStuName(String stuName) {  
    this.stuName = stuName;  
}  
public void setDepart(Depart depart) {  
    this.depart = depart;  
}  
  
}

 

这里设计对象模型时的属性并不是设计成departNum这个外键,而是整个Depart对象,这样做的好处是在查询时,就不用通过外键或者连接查询再多查询一次

 

若要通过外键查询:

  

Query query=session.createQuery("from Student as stud where stud.depart.departNum=:num");  
query.setString("num","890");



5、检查约束 CHECK

表级、字段级均可。

检查约束的条件表达式中不允许出现如下内容:
- currval, nextval, level, rownum等伪劣
- sysdate, uid, user, userenv等函数
- 对其它字段值的引用

其中, uid, user, userenv函数分别用于获取当前数据库用户ID,用户名及客户端计算机信息,如:

CHECK约束约束可以和一个列关联,也可以和一个表关联,因为它们可以检查一个列的值相对于另外一个列的值,只要这些列都在同一个表中以及值是在更新或者插入的同一行中。CHECK约束还可以用于检查列值组合是否满足某一个标准。


  可以像使用where子句一样的规则来定义CHECK约束。CHECK约束条件的示例如下:


目标


SQL


限制Month列为合适的数字


BETWEEN 1 AND 12


正确的SSN格式


LIKE'[0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]'


限制为一个快递公司的特定列表


IN('UPS','Fed Ex',EMS')


价格必须为正数


UnitPrice >= 0


引用同一行中的另外一列


ShipDate >= OrderDate


  上面给出的列表只是一小部分,而条件实际上市无限多的。几乎所有可以放到where子句的条件都可以放到该约束中。而且和其他选择(规则和触发器)相比,CHECK约束执行速度更快。


  在已存在的表中添加一个CHECK约束:


alter table Account


    add constraint CN_AccountAge


    check 


    (Account_Age > 18);    -- 插入年龄必须大于18


  如果此时视图添加一条不满足的记录,将报如下错误:


insert into Accountvalues (22,'洪',17)


消息547,级别16,状态0,第1 行


INSERT 语句与 CHECK 约束"CN_AccountAge"冲突。该冲突发生于数据库"Nx",表"dbo.Account", column 'Account_Age'。


语句已终止。


二、约束管理

1、查看约束

如要查看当前用户的所有约束,可查询用户字典视图user_constrains:

其返回结果中的"CONSTRAINT_TYPE"字段以缩写的方式标明约束条件的具体类型:"P"代表主键约束、 代表外键约束、"U"代表唯一键约束,检查和非空约束均使用"C"标明。

如果想知道约束建立在哪个字段上,则需要查询用户字典视图user_cons_columns:

2、添加约束(添加非空约束格式特别)

建表后添加非空约束的格式有些特别——必须使用MODIFY子句添加,实际上是修改了整个字段的定义(也可以同时修改字段类型、缺省值等),例如:

3、删除约束

其中,CASCADE用于指定删除当前约束的级联约束。

删除主键约束还有另外一种方式,其语法格式为:

删除约束时,如果还存在与该约束相关联的其他约束(如外键/关联)称为级联约束,则删除操作会失败,此时可使用CASCADE子句将其他关联约束一并删除。如:

删除表中字段时,如果该字段处于多字段联合约束条件(联合主键、联合唯一键、存在参照当前字段的外键)中,则删除会失败,此时可使用CASCADE CONSTRAINT子句将与该字段相关的约束一并删除。例如:

4、禁用约束

在ALTER TABLE语句中,还可以使用DISABLE CONSTRAINT子句禁用已有约束,即关闭数据校验功能,还可以使用CASCADE选项将相关联的约束一并禁用。其语法格式如下:

相应地,可以使用ENABLE CONSTRAINT子句启用先前被禁用的约束,例如:

和关闭约束操作的情形有所不同,此时无法再使用CASCADE选项一并启用相关联的其它约束。


如对本文有疑问,请提交到交流论坛,广大热心网友会为你解答!! 点击进入论坛


发表评论 (464人查看0条评论)
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
用户名: 验证码: 点击我更换图片
最新评论
------分隔线----------------------------