简单了解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约束,不能重复。