@@ -0,0 +1,266 @@
## 约束和常见约束
在创建表时可以添加约束,可以给表的字段增加约束,添加约束的目的是为了表中数据的完整性、合法性、唯一性
常见约束:
非空约束;【not null】不能为NULL
唯一约束;【unique】不能重复
主键约束;【primary key】不能是null且不能重复(PK)
外键约束;【foreign key】(FK)
检查约束;【check】注意:Oracle数据库中有check约束,但是MySQL没有,目前MySQL不支持
### 非空约束
在创建表格时添加约束;



一个完整的表中应该有主键
主键的分类:
1. 根据主键字段划分:
1. 单一主键【推荐,常用】
2. 复合主键【多个字段联合来添加一个主键约束】(不建议使用,因为违背三范式)
2. 根据主键性质:
1. 自然主键【主键值最好就是和业务没有任何关系的自然数】**{推荐}**
2. 业务主键【主键值和系统的业务挂钩】(拿着银行卡号做主键)(不推荐)
因为以后的业务进行改变时,主键值可能也需要随着变化,但有时候没办法改变,因为变化会导致主键值的重复。
> 主键约束只能有一个!!!
#### 主键自增
使用表级约束方式定义主键:

) ;
```
 | 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表叫做父表。
顺序要求:
>删除数据的时候,先删除子表,再删除父表。
>
>添加数据的时候,先添加父表,在添加子表。
>
>创建表的时候,先创建父表,再创建子表。
>
>删除表的时候,先删除子表,在删除父表。
语法:
 ,
- > primary key ( cno ) 【 主 键 】
- > ) ;
Query OK , 0 rows affected ( 0 . 05 sec )
```
创建父表
 ,
- > classno int ,
- > foreign key ( classno ) references t_class ( cno ) 【 外 键 】
- > ) ;
Query OK , 0 rows affected ( 0 . 07 sec )
```
创建子表
外键值可以是NULL?
> 外键可以是NULL。
外键字段引用其他表中某个字段时,被引用的字段必须是主键吗?
> 被引用的字段不一定是主键,但至少有unique约束