sql-DDL-约束


约束

对表中的数据进行限定,保证数据的正确性、有效性和完整性。

6个约束

1. 主键约束Primary Key: 唯一,不能为null
	-- 主键约束、和唯一约束不能同时设置
    1. 含义:非空且唯一
    2. 一张表只能有一个字段为主键
    3. 主键就是表中记录的唯一标识

2. 唯一约束Unique :唯一,允许为null
    -- 主键约束、和唯一约束不能同时设置
       注意:mysql中,唯一约束限定的列的值可以有多个null
3. 检查约束Check:对字段的数据范围进行限制 where后面的限制条件(age>0 and age<100)-- mysql不支持 检查约束
4. 外键约束Foreign Key:两张表之间
	用于定义主表和从表之间的关系,外键约束要定义在从表上,主要则必须具有主键约束或是unique约束,当定义外键约束后,要求外键列数据必须在主表的主键列存在或是为NULL。

5. 默认约束Default:对字段进行默认值的设置
6. 非空约束Not Null:对字段 是否可以为null进行限制
  • 主键和唯一键的区别:
    • a.主键不能为null,唯一键可以为null
    • b.一张表只能设置一次主键(主键可以是一个,也可以是复合主键),但可以设置多次唯一键

约束分类

- 列级约束
	- 6个约束类型(4个+默认、非空)	
	- 定义在列的后面
	- 多个约束之间用空格分割
	- 只能应用于一个列

- 表级约束
	- 4个(主键、外键、唯一、检查)
	- 定义在表的后面
	- 多个约束之间用逗号分割
	- 应用于一个列或多个列

列级约束

create table student
(
	stuNo  number(3) primary key,  --主键约束
	stuName  varchar(20) unique  ,--非空约束 not null、唯一约束
	stuAddress varchar(50) default '陕西西安'  check( length(stuAddress)>2 and length(stuAddress)<20 ),--默认约束、check约束
	subId number(3)   
)

注意事项

①如果一个列有多个约束(且包含default约束),则default约束必须放在第一个
②唯一约束:不适用于null
③check约束:

  • 怎么在where后面写限制语句,就怎么在check()中写。
  • check(gender in ('男','女'));
  • check(age>=0 and age<=100);

④不论违反的是 主键约束,还是唯一约束,在重复插入数据时,都报错:违反唯一约束条件

表级约束

create table student2
(
    stuNo number(3),
    stuName varchar2(20),
    stuAddress varchar2(50),
    subId number(3),
    constraint PK_stuNo1 primary key(stuNo) ,-- 表级约束
    constraint UQ_stuName_subId unique(stuName,subId) , -- 唯一约束作用于两列
    constraint CK_stuAddress1 check(length(stuAddress)>2)
);

给列级约束命名

  • constraint 约束名称
  • 命名规则

主键约束: PK _字段名
检查约束: CK _字段名
唯一约束: UQ_字段名
非空约束: NN_字段名
外键约束: FK_子表_父表
默认约束 :一般不需命名

  • 注意事项: 约束名 在当前用户下的所有表之间 共用。
create table student1
(
    stuNo  number(3) constraint PK_stuno primary key,  --主键约束
    stuName  varchar(20) constraint NN_stuName not null constraint UQ_stuName unique ,--非空约束、唯一约束
    stuAddress varchar(50) default '陕西西安' constraint CK_stuAddress check( length(stuAddress)>2 and length(stuAddress)<20 ),--默认约束、check约束
    subId number(3)
)

外键约束(完整约束条件)

主键、外键使用注意事项
a.当父表中没有对应的记录时,不能将记录添加到子表
b.不能更改父表中的值而导致子表中的记录孤立
c.子表存在与父表对应的记录,不能从父表中删除该行
d.删除父表前,先删子表

创建外键

--表级约束

create table sub
(
    sId number(3) primary key, --外键所指向的列 必须是主键或唯一键
    sname varchar(20)
);

create table student3
(
    stuNo number(3),
    stuName varchar2(20),
    subId number(3),
    constraint FK_student3_sub  foreign key(subId) references sub(sId) –- 表级外键约束
);

--列级约束

CREATE TABLE  table_name
(
    column_1  datatype ,
    column_2  datatype  CONSTRAINT fk_column  REFERENCES  parent_table (column_name),
    ...
);

级联置空、级联删除

参考on update cascade 和on delete cascade 作用区别

on delete cascade -- 级联删除 当父表中的列被删除时,同时会自动删除子表中对应的记录。

on delete set null -- 级联置空 当父表中的列被删除时,同时会将子表中对应字段设置为null。

  • 在子表中设置
create table student4
(
    stuNo number(3),
    stuName varchar2(20),
    subId number(3),
    constraint FK_student4_sub  foreign key(subId) references sub(sId) 
    --级联删除on delete cascade
    on delete set null -- 级联置空
);

追加约束

主键约束

-- 追加
alter table student add CONSTRAINT PK_stuNo PRIMARY key (stuNo);
-- 删除
alter table student drop constraint PK_stuNo; --oracle
alter table student drop PRIMARY key; -- mysql

唯一约束

-- 追加
alter table student add constraint UQ_name UNIQUE(stuName);
ALTER TABLE student MODIFY stuName VARCHAR(255) UNIQUE; -- mysql下追加唯一约束的另一种写法
-- 删除
alter table student drop constraint UQ_name; -- oracle
ALTER TABLE student DROP INDEX UQ_name; -- mysql

mysql下的唯一约束

检查约束

-- mysql
CREATE TABLE `student` (
  `stuNo` int(11),
  `stuName` varchar(255),
  `stuAge` int(11),
  `classId` int(11),
	constraint CK_stuAge check(stuAge > 18)
);
-- 可以执行追加检查约束的sql语句,但是不生效,包括 列级的检查约束 表级的检查约束 都不生效
alter table student add constraint CK_stuAge check(stuAge > 18);
insert into student(stuNo,stuAge,classId) value (4,16,1);  -- 该数据正常插入

alter table student drop constraint CK_stuAge;  -- 不对
ALTER TABLE student DROP check CK_stuAge; -- 不对

mysql检查约束无效可参考 mysql check约束无效

外键约束

-- mysql
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名称) REFERENCES 主表名称(主表列名称);  -- 追加外键
alter table student add constraint FK_student_class  foreign key(classId) references class(classId) ;

insert into student(stuNo,stuName,stuAge,classId) value (3,'zs',23,1);
insert into student(stuNo,stuName,stuAge,classId) value (3,'ls',23,6);

ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;  --删除外键  
ALTER TABLE student DROP FOREIGN KEY FK_student_class;

非空约束

-- oracle
alter table student MODIFY stuName CONSTRAINT nn_stuName not null;
alter table student drop CONSTRAINT nn_stuName;

-- mysql
alter table student MODIFY stuName varchar(255) not null;
alter table student MODIFY stuName varchar(255);

默认约束

-- oracle
alter table student modify stuName default '0000' ;
alter table student modify stuname default null ;

-- mysql
alter table student MODIFY stuName varchar(255) default '111111'; -- 设置默认约束
alter table student modify stuName varchar(255) default null ; -- 删除默认约束  将默认值设置为null,就相当于删除了默认约束。

-- 什么情况下字段会被赋予默认值
insert into student(stuNo,stuAge,classId) value (3,23,1); -- stuName 会被赋予默认值
insert into student(stuNo,stuName,stuAge,classId) value (3,null,23,1);-- stuName 是null

mysql查询约束

1.查询约束:SELECT * FROM information_schema.`TABLE_CONSTRAINTS`;(可以通过where table_name='student'来约定只查询某个表的约束)

其实每次添加约束都是将添加的约束的信息存储到了information_schema这个schema的table_constraints表里;(mysql里``和bash的很像,也是执行``内的表达式而不是将里面作为字符串使用)

完整性约束

- 域完整性:对“列”的数据进行限制
- 实体完整性:对“行”的数据进行限制
- 引用完整性:多张表的数据 进行限制(外键)
- 自定义完整性:开发者自己定义的 约束条件 (通过触发器实现)