第11章:约束

本文详细介绍了数据库中的数据完整性约束,包括实体完整性、域完整性、引用完整性和用户自定义完整性。重点讨论了非空约束、唯一性约束、主键约束和外键约束的概念、特点以及在MySQL中的创建、修改和删除方法。此外,还提到了检查约束和默认值约束,并探讨了在实际开发中是否应该使用外键约束的问题。
摘要由CSDN通过智能技术生成

一、数据完整性与约束的分类

1.为什么需要约束constraint

SQL以约束方式对表数据进行额外的条件限制。

为了保证数据的完整性,SQL对表数据进行条件限制

①实体完整性:同一个表,不能存在两条相同无法区分的记录

②域完整性:年龄范围0-120,性别是男/女

③引用完整性:员工表员工所在的部门,要在部门表里找到

④用户自定义完整性:用户名唯一,密码不为空

2.什么是约束

约束是表级的强制规定

在创建表create table规定约束,创建表后alter table规定约束

3.约束的分类

角度1:约束的字段个数

单列约束 vs 多列约束

角度2:约束的作用范围

列级约束:将声明约束在对应字段的后面

表级约束:在表中所有字段声明完成后,在所有字段后面声明的约束

角度3:约束的作用

①not null 非空约束

②unique 唯一性约束

③primary key 主键约束

④foreign key 外键约束

⑤check 检查约束

⑥default 默认值约束

4.查看约束

SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE table_name='表名';

5.添加约束总结、

alter table ***

modify 字段名 数据类型  default/not null

alter table ***

add unique(字段名,字段名);

add primary key (字段名);

add foreign key (从表.字段) references 主表名(主表.字段);

二、非空约束not null

1.作用

限制值不能为空

 

2.特点

①默认情况下所有类型是NULL

②某个列单独为非空,不能组合列非空

③很多列可以设置非空

④空字符’’不是NULL,0也不是NULL

3.创建表添加非空not null 约束

 

CREATE TABLE test1 (

  id int(11) NOT NULL,

  last_name varchar(15) NOT NULL,

  email varchar(25),

  salary decimal(10,2)

)

 

4.已有表添加非空约束

①格式

alter table 表名称 modify 字段名 数据类型 not null;

②举例

alter table test1

modify email varchar(25) not null

5.删除约束

①格式

alter table 表名称 modify 字段名 数据类型

或者

alter table 表名称 modify 字段名 数据类型 null

②举例

alter table test1

modify email varchar(25) null

三、唯一性约束unique

1.作用

用来限制字段的值不能重复,但是可以为NULL,允许出现多个NULL

 

2.特点

①同一个表可以有多个唯一约束。

②唯一约束可以是某一个列的值唯一,也可以多个列组合的值唯一。

③唯一性约束允许列值为空。

④在创建唯一约束的时候,如果不给唯一约束命名,就默认和列名相同。

⑤MySQL会给唯一约束的列上默认创建一个唯一索引。

3.创建表添加唯一约束

 测试:id和email不能重复

create table test2(
id int unique, #列级约束
last_name varchar(15),
email varchar(15),
salary decimal(10,2),
# 表级约束
constraint uk_test2_email unique(email)
);

4.已有表添加唯一约束

alter table test2
modify salary decimal(10,2) unique

5.复合(多列)唯一性约束

创建表 name-password为组合约束

create table user(
id int,
name varchar(15),
password varchar(25),
# 表级约束
constraint uk_user_name_pwd unique(name,password)
);

测试 name和pawword看成整体

insert into user(id,name,password)
values
(1,'z','w'),
(2,'z','z')

6.删除唯一性约束:根据唯一索引删除

添加唯一性约束的时候,会自动创建唯一索引。删除根据索引名(跟约束名相同)删除。

alter table user

drop index uk_user_name_pwd

7.查看表的索引

show index from 表名称

四、主键约束primary key

1.作用

用来唯一标识表中的一行记录

2.关键字

primary key

3.特点:非空且唯一

 

①一个表里面有且仅有一个主键,可以存在复合主键

②复合主键的列都不为空,组合的值不重复

③主键名是primary,创建主键时会建立主键索引

4.新建表创建主键

 

①举例

create table temp(

id int primary key,

name varchar(20)

);

create table temp2(

id int,

name varchar(20),

primary key(id)

);

5.已有表添加主键

#字段列表是一个字段,也可以是多个字段

ALTER TABLE 表名称 ADD PRIMARY KEY(字段列表);

举例

ALTER TABLE student ADD PRIMARY KEY (sid);

ALTER TABLE emp5 ADD PRIMARY KEY(name,pwd);

6.复合主键

方式一:创建表添加复合主键

 方式二:已有表添加复合主键

ALTER TABLE 表名称 ADD PRIMARY KEY(字段列表);

7.删除主键约束

alter table 表名称 drop primary key;

删除主键约束,此时的非空还存在,只是不唯一了

五、自增列 auto_increment

1.作用

某个字段的值自增

2.关键字

auto_increment

3.特点

①一般加在主键/唯一性约束的后面

②类型必须是int

4.创建表时创建自增列

create table test7(
id int PRIMARY key AUTO_INCREMENT,
name varchar(15)
);

测试

省略自增列

insert into test7(name)

values

('wang'),

('zhang'),

('sun')

 如果自增列指定了 0 和 null,会在当前最大值的基础上自增

insert into test7(id,name)
values 
(0,'wang1'),
(null,'zhang1')

 如果自增列手动指定了具体值,直接赋值为具体值。

insert into test7(id,name)
values 
(8,'wang1')

5.修改表时创建自增列

alter table 表名称

modify 字段名 数据类型 auto_increment;

create table test8(
id int primary key,
name varchar(15)
);

alter table test8
modify id int auto_increment;

6.开发中遇到auto_increment字段时

不要给该字段赋值,省略过去

7.删除自增列auto_increment

alter table 表名称

modify 字段名 数据类型

alter table test8
modify id int

六、外键 foreign key

1.作用

限定表中的某个字段的引用完整性

比如:员工表所在的部门号,必须在部门表里有这个部门号。

2.关键字

foreign key

3.特点

①子表的外键必须引用父表的主键或唯一约束。因为添加外键时被引用父表的值是唯一的

②创建外键时,要先有主表

③删表时,先删除子表(有外键的表)在删除父表

④要删除父表的记录时(部门表)先删除子表(员工表)引用的该部门记录,然后才能删除成功。

⑤一个表可以有多个外键约束

⑥主键和外键的名称可以不一样,但是类型必须一样

⑦创建外键约束时,会在所在的列创建普通索引。删除外键约束,手动删除索引

4.创建表时添加外键

先创建主表

create table dept1(
dept_id int primary key,
dept_name varchar(15)
);

再创建子表

create table emp1(
id int primary key,
name varchar(15),
dept_id int,
constraint fk_emp1_dept_id foreign key(dept_id) references dept1(dept_id)
);

5.已有表时添加外键

先创建父表

create table dept2(
dept_id int primary key,
dept_name varchar(15)
);

再创建子表

create table emp2(
id int primary key,
name varchar(15),
dept_id int
);

alter table emp2

add foreign key (dept_id) references dept2(dept_id)

6.错误演示

①主表的dept_id没有主键或唯一性约束

create table dept3(

dept_id int,

dept_name varchar(15)

);

create table emp3(

id int primary key,

name varchar(15),

dept_id int,

constraint fk_emp1_dept_id foreign key(dept_id) references dept1(dept_id)

);

7.演示外键增删改

①部门表

 ②增加员工表(部门号是部门表已经有的,不然a foreign key constraint fails失败)

insert into emp1(id,name,dept_id)

values

(1,'wang',101)

删除部门表的财务部

先把子表员工表引用的财务部的记录删除,才能删除父表部门表的记录。

delete from emp1

where dept_id =101;

delete from dept1

where dept_id =101;

9.删除外键约束

10.开发场景

问题1:如果两个表之间有关系(一对一、一对多),比如:员工表和部门表(一对多),它们之间是否 一定要建外键约束?

不一定

问题2:建和不建外键约束有什么区别?

建立外键:操作受到语法层面的限制

不建立外键:操作不受限制,保证数据引用的完整性,靠程序员自觉或java程序中进行限定

问题3:那么建和不建外键约束和查询有没有关系?

没有

11.阿里开发规范

不使用外键,外键概念在应用层解决。

说明:外键与级联更新适用于单机低并发,不适合分布式、高并发集群;级联更新是强阻塞,存在数据库更新风暴的风险;外键影响数据库的插入速度。

 

七、检查约束 check

1.作用:

检查某个字段的值的范围符合xx要求

2.关键字

check

3.MySQL5.7不支持,运行不报错,但不起作用。MySQL 8.0支持。Oracle支持

4.示例

create table test10(

id int,

last_name varchar(15),

salary decimal(10,2) check(salary > 2000)

);

①插入演示

insert into test10(id,last_name,salary)

values

(1,'wang',1000);错误

insert into test10(id,last_name,salary)

values

(2,'zhang',3000);正确

八、默认约束 default

1.作用

默认值约束,插入数据时,字段没有显式赋值,就赋值为默认值

2.创建表时增加默认约束

create table test11(

id int,

last_name varchar(15),

salary DECIMAL(10,2) default 2000

);

演示一:

insert into test11(id,last_name,salary)

values

(1,'wang',null), #成功

(1,'wang') #失败,字段和值的数目不匹配

演示二:

insert into test11(id,last_name)

values

(2,'zhang')

3.已有表时增加默认约束

创建默认约束时,检查此字段是否非空,如果非空记得添加 default 默认值 not null;

九、面试

1.为什么建表时,加not null default’’或default 0,为什么?

答:不想出现null值。

①不好比较。参与运算时返回的都是null

②效率不高,影响提高索引效果

面试2:带auto_increment的约束字段值都是从1开始吗?

答:①默认是从1开始,每新增一条记录字段自动加1。

②还可以自定义第一条插入记录的自增字段值,以后插入就会根据这个值自动加1

③添加主键约束时,往往设置字段自增属性

面试3:每个表都可以任意选择存储引擎吗?

外键约束不支持跨引擎使用。

MySQL支持每个表的引擎不同。但是外键约束不支持跨引擎使用,因为保证数据参照的完整性。

如果不同引擎的表之间需要关联外键,那么表之间不能创建外键约束。存储引擎的选择不是完全随意的。

十、练习

练习一

已经存在数据库test04_emp,两张表emp2和dept2

题目:

#1.向表emp2id列中添加PRIMARY KEY约束

alter table emp2

add primary key(id)

#2. 向表dept2id列中添加PRIMARY KEY约束

alter table dept2

add primary key(id)

#3. 向表emp2中添加列dept_id,并在其中定义FOREIGN KEY约束,与之相关联的列是dept2表中的id列。

alter table emp2

add column dept_id int

alter table emp2

add foreign key(dept_id) references dept2(id)

练习二

# 1、创建数据库test01_library

create database if not exists test01_library

# 2、创建表 books,表结构如下:

create table books(

id int,

name varchar(50),

authors varchar(100),

price float,

pubdate year,

note varchar(100),

num int

);

# 3、使用ALTER语句给books按如下要求增加相应的约束

 

Id

alter table books

add primary key(id);

alter table books

modify id int auto_increment;

name

alter table books

modify name varchar(50) not null;

authors

alter table books

modify authors varchar(100) not null;

price

alter table books

modify price float not null;

year

alter table books

modify pubdate year not null;

num

alter table books

modify num int not null;

练习三

#1. 创建数据库test04_company

create database if not exists test04_company

#2. 按照下表给出的表结构在test04_company数据库中创建两个数据表officesemployees

 

create table offices(

officeCode int(10) primary key,

city varchar(50) not null,

address varchar(50),

country varchar(50) not null,

postalCode varchar(15) unique

);

create table employees(

employeeNumber int(11) primary key auto_increment,

lastName varchar(50) not null,

firstName varchar(50) not null,

mobile varchar(25) unique,

officeCode int(10),

jobTitle varchar(50) not null,

birth datetime not null,

note varchar(255),

sex varchar(5),

foreign key(officeCode) references offices(officeCode)

);

#3. 将表employeesmobile字段修改到officeCode字段后面

ALTER TABLE employees MODIFY mobile VARCHAR(25) AFTER officeCode;

#4. 将表employeesbirth字段改名为employee_birth

alter table employees

change birth employee_birth datetime not null

#5. 修改sex字段,数据类型为CHAR(1),非空约束

alter table employees

modify sex char(1) not null

#6. 删除字段note

alter table employees

drop column note

#7. 增加字段名favoriate_activity,数据类型为VARCHAR(100)

alter table employees

add column favoriate_activity varchar(100)

#8. 将表employees名称修改为employees_info

rename table employees to employees_info

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值