约束和常见约束
在创建表时可以添加约束,可以给表的字段增加约束,添加约束的目的是为了表中数据的完整性、合法性、唯一性
常见约束:
非空约束;【not null】不能为NULL
唯一约束;【unique】不能重复
主键约束;【primary key】不能是null且不能重复(PK)
外键约束;【foreign key】(FK)
检查约束;【check】注意:Oracle数据库中有check约束,但是MySQL没有,目前MySQL不支持
非空约束
在创建表格时添加约束;
Not null只有列级约束,没有表级约束
唯一性约束
unique:唯一性约束修饰的字段具有唯一性,不能重复,但是可以是NUll
设置后可以是NULL但是不能重复:(单行设置不能重复)
两行或多行拼接联合不能重复:
当两行内容需要联合保证不重复时需要使用 unique(字段名1,字段名2,,,)
只有当两个数据进行拼接对比后相同才会被认定为相同,反之属于。
在表的每一列添加是列级约束;在字段声明后单独添加是表级约束。
TIP
如果一个字段同时被not null 和 unique 同时修饰,这个字段自动变成主键字段
主键约束
添加主键约束:
TIP
添加主键后,不能为NULL,不能重复,具有唯一性
主键约束 :primary key
主键字段:添加primary key的字段
主键值:添加primary key的值
主键的作用:
主键的值是每条记录的唯一标识(就像身份证号)
一个完整的表中应该有主键
主键的分类:
根据主键字段划分:
- 单一主键【推荐,常用】
- 复合主键【多个字段联合来添加一个主键约束】(不建议使用,因为违背三范式)
根据主键性质:
- 自然主键【主键值最好就是和业务没有任何关系的自然数】{推荐}
- 业务主键【主键值和系统的业务挂钩】(拿着银行卡号做主键)(不推荐)
因为以后的业务进行改变时,主键值可能也需要随着变化,但有时候没办法改变,因为变化会导致主键值的重复。
主键约束只能有一个!!!
主键自增
使用表级约束方式定义主键:
提供主键值自增:
drop table if exists t1;【t1存在的话进行删除】
create table t1 (
id int primary key auto_increment ,【设置自动主键,MySQL提供,可以从1自增】
name varchar(255)
);
外键约束
外键约束:foreign key
外键字段:添加有外键约束的字段
外键值:添加有外键约束的值
案例:统计学校所有学生和班级
业务背景:
请设计数据库表,用来维护学生和班级的信息?
第一种方案:一张表存储所有数据
no(pk) | name | classno | classname |
---|---|---|---|
1 | zs1 | 101 | 北京大兴区经济技术开发区亦庄二中高三1班 |
2 | zs2 | 101 | 北京大兴区经济技术开发区亦庄二中高三1班 |
3 | zs3 | 102 | 北京大兴区经济技术开发区亦庄二中高三2班 |
4 | zs4 | 102 | 北京大兴区经济技术开发区亦庄二中高三2班 |
5 | zs5 | 102 | 北京大兴区经济技术开发区亦庄二中高三2班 |
缺点:冗余。【不推荐】
第二种方案:两张表(班级表和学生表)
t_class 班级表
cno(pk) | cname |
---|---|
101 | 北京大兴区经济技术开发区亦庄二中高三1班 |
102 | 北京大兴区经济技术开发区亦庄二中高三2班 |
t_student 学生表
sno(pk) | sname | classno(该字段添加外键约束fk) |
---|---|---|
1 | zs1 | 101 |
2 | zs2 | 101 |
3 | zs3 | 102 |
4 | zs4 | 102 |
5 | zs5 | 102 |
将所有信息都放一个表中,会有大量的重复数据(如班级等) ,所以需要多张表进行连接来创建。
但是当不同的表需要有一些数据进行连接,并且保证数据的准确性,这时候可以使用外键
如:在班级栏使用外键,这样学生选择的班级就只是在指定的一些数据中进行选择,而保证数据的稳定性
t_student中的classno字段引用t_class表中的cno字段,此时t_student表叫做子表。t_class表叫做父表。
顺序要求:
删除数据的时候,先删除子表,再删除父表。
添加数据的时候,先添加父表,在添加子表。
创建表的时候,先创建父表,再创建子表。
删除表的时候,先删除子表,在删除父表。
语法:
mysql> create table t_class(
-> cno int,
-> cname varchar(255),
-> primary key(cno)【主键】
-> );
Query OK, 0 rows affected (0.05 sec)
创建父表
mysql> create table t_student(
-> cno int,
-> cname varchar(255),
-> classno int,
-> foreign key(classno) references t_class (cno)【外键】
-> );
Query OK, 0 rows affected (0.07 sec)
创建子表
外键值可以是NULL?
外键可以是NULL。
外键字段引用其他表中某个字段时,被引用的字段必须是主键吗?
被引用的字段不一定是主键,但至少有unique约束