vlambda博客
学习文章列表

简单了解mysql中的约束

约束(constraint)

在创建表的时候,我们可以给字段加上一些约束,保证表中的数据完整,有效。

约束包括

1.非空约束(not null ):字段的值不能为null,可以使用以下语法使用。

create table stu(stu_no varchar(10) not null default '给定默认值,传入空的时候,就不会报错了',name varchar(10) not null);

2.唯一性约束(unique):表示字段的值不能够重复,null不算是重复

create table stu(stu_no varchar(10) unique,name varchar(10) not null);

多个字段可以实现共同唯一性

create table stu(stu_no varchar(10) unique,name varchar(10) unique);

insert into stu values('123','456'); insert into stu values('123','789');

以上是不可以插入的,这种是两个字段各自唯一性

create table stu(stu_no varchar(10),name varchar(10),unique(stu_no,name));

这种是两个字段联合起来唯一性,约束没有添加在列的后面,这种约束称为表级约束

insert into stu values('123','456'); insert into stu values('123','789');

这种的时候,以上是可以插入的

not null与unique是可以联合使用的

create table stu(stu_no varchar(10) unique not null);

这个时候查看表结构,发现这个字段变成了主键字段

+--------+-------------+------+-----+---------+-------+| Field  | Type        | Null | Key | Default | Extra |+--------+-------------+------+-----+---------+-------+| stu_no | varchar(10) | NO   | PRI | NULL    |       |+--------+-------------+------+-----+---------+-------+

3.主键约束(primary key,简称PK)

相关术语1.主键约束(一种约束)2.主键字段(字段上添加了主键约束)3.主键值(主键字段的每一个值)

主键值是每一行记录的唯一标识,类似于身份证号码

表中的数据直接可能完全一样,这个时候就需要使用到主键值区分,每一张表都应该有主键,没有主键的表是非法的,一个字段如果被设置成为not null 并且unique的话,会被默认当成主键,主键的特征就是not null 并且unique,具有唯一性。

设置主键约束:create table stu(stu_no varchar(10) primary key);

一个表中只能有一个主键,不能有两个主键,以下SQL不可以

create table stu(stu_no varchar(10) primary key ,name varchar(10) primary key);

但可以两个字段联合起来作为主键,称为复合主键(不建议使用)。一个字段主键称为单一主键

create table stu(stu_no varchar(10) ,name varchar(10) ,primary key(stu_no,name));

主键类型建议使用int,bigint,char,不建议使用varchar,主键一般都是定长的。

4.外键约束(foreign key,简称FK)

5.检查约束(check)(mysql不支持,oracle支持)

自然主键:主键值是一个自然数,和业务没关系(使用的比较多)

可以使用自增实现,从1开始create table stu(stu_no int primary key auto_increment);

业务主键:主键与业务紧密关联,例如手机号码

外键约束

相关术语1.外键约束(一种约束)2.外键字段(添加外键约束的字段)3.外键值(外键字段中的每一个值)

业务背景: 请设计数据库表,来描述“班级和学生”的信息?

第一种方案:班级和学生存储在一张表中???
t_student
no(pk) name classno classname
----------------------------------------------------------------------------------
1 jack 100 北京市大兴区亦庄镇第二中学高三1班
2 lucy 100 北京市大兴区亦庄镇第二中学高三1班
3 lilei 100 北京市大兴区亦庄镇第二中学高三1班
4 hanmeimei 100 北京市大兴区亦庄镇第二中学高三1班
5 zhangsan 101 北京市大兴区亦庄镇第二中学高三2班
6 lisi 101 北京市大兴区亦庄镇第二中学高三2班
7 wangwu 101 北京市大兴区亦庄镇第二中学高三2班
8 zhaoliu 101 北京市大兴区亦庄镇第二中学高三2班
分析以上方案的缺点:
数据冗余,空间浪费!!!!
这个设计是比较失败的!

第二种方案:班级一张表、学生一张表??

t_class 班级表
classno(pk) classname
------------------------------------------------------
100 北京市大兴区亦庄镇第二中学高三1班
101 北京市大兴区亦庄镇第二中学高三1班

t_student 学生表
no(pk) name cno(FK引用t_class这张表的classno)
----------------------------------------------------------------
1 jack 100
2 lucy 100
3 lilei 100
4 hanmeimei 100
5 zhangsan 101
6 lisi 101
7 wangwu 101
8 zhaoliu 101

当cno字段没有任何约束的时候,可能会导致数据无效。可能出现一个102,但是102班级不存在。
所以为了保证cno字段中的值都是100和101,需要给cno字段添加外键约束。
那么:cno字段就是外键字段。cno字段中的每一个值都是外键值。

注意:
t_class是父表
t_student是子表

删除表的顺序?
先删子,再删父。

创建表的顺序?
先创建父,再创建子。

删除数据的顺序?
先删子,再删父。

插入数据的顺序?
先插入父,再插入子。

可以这样定义外键约束

create table t_student(no int primary key,name varchar(255),classno int,foreign key(classno) references t_class(classno));

这样子表t_student中的classno字段中的值插入的时候就在t_class中的classno字段值中选择,不能填入不在t_class中的classno字段值。被引用的父表的字段值可以为null,不必须是主键,但至少有unique约束,不能重复。