MySql数据库——约束

本文介绍了MySQL数据库中的约束,包括主键约束的唯一性和非空性,自增类型的主键,以及外键约束对于参照完整性的维护。讨论了外键的级联删除和置空操作,以及在高并发和大数据量场景下外键的优缺点。遵循阿里巴巴开发手册,不建议在数据库中设置外键,但也要根据场景权衡正确性和性能。

一、主键约束

    主键的作用是唯一标识一条记录。所以它不能重复,也不能为空,我们可以认为它是唯一性约束和非空约束的组合。一张数据表的主键最多只能有一个 (推荐每张表都设置一个主键)。主键可以是一个字段,也可以由多个字段符合组成。

-- 设置主键的两种方式
 create table t_student (
 	id int primary key,
 	name varchar(20)
 );

 create table t_student (
	 id int,
	 name varchar(20),
	 primary key(id)
 );

# 不推荐以下写法
 create table t_score(
 	 sid int,
 	 cid int,
	 score int
 );
 alter table t_score add primary key(sid, cid);
-- 联合主键 在一条数据可能有重复的情况下,用另一条数据去保持其唯一性
 create table t_score(
 	 sid int,
 	 cid int,
	 score int,
	 primary key(sid, cid)
 );
 

自增类型

-- auto_increment
 auto_increment 关键字往往是和 primary key 一起使用的。它的作用是:被修饰的字段会自动增长。
 1. auto_increment 只能作用于被 primary key 或者是 unique 修饰的字段。
 2. auto_increment 作用字段的类型必须是数值类型。
 3. 一张数据表只能有一个自增长字段。

 create table t_student (
 	 id int primary key auto_increment,
 	 name varchar(20)
 );
 create table t_student (
  	 id int unique auto_increment,
	 name varchar(20)
 );

二、外键约束

    外键约束的作用是确保表与表之间参照完整性。一张表的外键往往对应另一张表的主键。外键可以是重复的,也可以为空。

create table t_class (
	 id int primary key auto_increment,
     name varchar(20) not null,
     teacher varchar(20) not null
 );
 create table t_student (
 	 id int primary key auto_increment,
     name varchar(20) not null,
     cid int,
     foreign key(cid) references t_class(id)
 );

 # 我们还可以给外键添加一个名字
create table t_student (
id int primary key auto_increment,
name varchar(20) not null,
cid int,
constraint fk_cid foreign key(cid) references t_class(id)
);
# 当然我们还可以在创建表之后,再添加外键 (不推荐)
 create table t_student (
 	id int primary key auto_increment,
	name varchar(20) not null,
	cid int
 );
 alter table t_student add constraint fk_cid foreign key(cid) references t_class(id);

添加外键之后,对两张表都会有一些约束。具体体现在:
1. t_student 表不能随意的添加和修改。
2. t_class 表不能随意的删除和修改。

1、级联删除

-- 删除 t_class 表中的记录,那么 t_student 中引用相应记录的行也会一起被删除。
 create table t_student (
	id int primary key auto_increment,
	name varchar(20) not null,
	cid int,
	constraint fk_cid foreign key(cid) references t_class(id) on delete    cascade
 );
 

2、级联置空

-- 删除 t_class 表中的记录,那么 t_student 中引用相应记录的行的外键会被置为 null 。
 create table t_student (
	 id int primary key auto_increment,
	 name varchar(20) not null,
	 cid int,
	 constraint fk_cid foreign key(cid) references t_class(id) on delete set null
 );
 

外键虽然可以保证表与表之间的参照完整性,但是它的缺点也很明显。

  1. 影响数据库的性能
  2. 在高并发场景中容易引起死锁
  3. 当数据量很大的时候,为了保证查询的性能,我们需要进行分库分表。一旦分库分表,我们就不能
    保证参照的完整性了。
    正是因为这些原因,所以《阿里巴巴开发手册》中规定:不要在数据库中设置外键,一切的参照完整都
    应该在业务层中完成。
    当然,这并不是说,外键就一无是处。如果参照完整性都在业务层中完成,也会导致一些问题。
  4. 业务层与数据耦合了。
  5. 增加了业务层的逻辑。
  6. 不能够在数据库的层面保证表之间的参照完整性。
    所以,我们应该正确地看待外键。在以下场景中,我们是可以使用外键的。
  7. 并发度不高
  8. 数据量不大,不需要分库分表。
  9. 正确性 > 性能

三、其他约束

-- unique 唯一性约束保证了字段的值是唯一的。即使我们有了主键,我们还是可以对其它字段设置唯一性约束。
# 注意事项: null 与 null 是不相同的,所以唯一性约束的字段,可以有多个 null 值。
 create table t_unique(
	 a int unique
 );

-- NOT NULL非空性约束保证了字段的值不为null ,必须有个具体的值。
 create table t_student (
	 id int primary key auto_increment,
 name varchar(20) not null,
 );

-- DEFAULT 表示字段的默认值。如果插入数据的时候,没有给该字段取值,就会设置为默认值。
 create table t_student (
	 id int primary key auto_increment,
	 name varchar(20) not null,
	 cid int,
	 constraint fk_cid foreign key(cid) references t_class(id) on delete set null
 );



-- CHECK 表示自定义约束。MySQL 没有实现这个功能,但是其它商用型数据库,比如 Oracle 是有这个功能的。
 create table t_check(
	 height float(3, 2) check(height between 0.00 and 3.00)
 );
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值