当前位置:   article > 正文

MySQL 约束详解_mysql的约束

mysql的约束

一、什么是约束

约束实际上就是表中数据的限制条件


二、约束作用

表在设计的时候加入约束的目的就是为了保证表中的记录完整和有效

  • 比如name字段中要让其用户名不重复,这就需要添加约束。或者必须注册的时候需要添加邮箱等

三、约束种类

  • 非空约束(not null)
  • 默认约束(default),保证字段总会有值,即使没有插入值,都会有默认值!
  • 唯一性约束(unique)
  • 主键约束(primary key) PK
  • 外键约束(foreign key) FK
  • 检查约束(目前MySQL不支持、Oracle支持)

下面将逐一介绍以上约束


非空约束

用not null约束的字段不能为null值,必须给定具体的数据

创建表,给字段添加非空约束(创建用户表,用户名不能为空)

  1. create table t_user(
  2. id int(10),
  3. name varchar(32) not null
  4. );

如果没有插入name字段数据,则会报错

  1. mysql> insert into t_user (id) values(1);
  2. ERROR 1364 (HY000): Field 'name' doesn't have a default value

默认约束

  1. mysql> CREATE TABLE student(
  2. id INT PRIMARY KEY,
  3. name VARCHAR(50) NOT NULL UNIQUE,
  4. gender VARCHAR(10) DEFAULT '女'
  5. );
  6. insert into student(id,name) values(1,'toc');
  7. insert into student(id,name,gender) values(2,'jok','男');
  8. insert into student(id,name,gender) values(3,'jerry',default);
  9. Query OK, 0 rows affected (0.25 sec)
  10. Query OK, 1 row affected (0.03 sec)
  11. Query OK, 1 row affected (0.04 sec)
  12. Query OK, 1 row affected (0.06 sec)
  13. mysql> SELECT * FROM STUDENT;
  14. +----+-------+--------+
  15. | id | name | gender |
  16. +----+-------+--------+
  17. | 1 | toc ||
  18. | 2 | jok ||
  19. | 3 | jerry ||
  20. +----+-------+--------+
  21. 3 rows in set (0.06 sec)

可以看出如果不进行定义的话,gender会默认成为‘女’。 


 唯一性约束

unique约束的字段,具有唯一性,不可重复,但可以为null

创建表,保证邮箱地址唯一(列级约束)

  1. create table t_user(
  2. id int(10),
  3. name varchar(32) not null,
  4. email varchar(128) unique
  5. );

 1、表级约束

  1. create table t_user(
  2. id int(10),
  3. name varchar(32) not null,
  4. email varchar(128),
  5. unique(email)
  6. );

如果插入相同email会报错

  1. mysql> insert into t_user(id,name,email) values(1,'xlj','932834897@qq.com');
  2. Query OK, 1 row affected (0.00 sec)
  3. mysql> insert into t_user(id,name,email) values(2,'jay','932834897@qq.com');
  4. ERROR 1062 (23000): Duplicate entry '932834897@qq.com' for key 'email'

2、使用表级约束,给多个字段联合约束

联合约束,表示两个或以上的字段同时与另一条记录相等,则报错

  1. create table t_user(
  2. id int(10),
  3. name varchar(32) not null,
  4. email varchar(128),
  5. unique(name,email)
  6. );

 插入第一条数据

  1. mysql> insert into t_user(id,name,email) values(1,'xxx','qq.com');
  2. Query OK, 1 row affected (0.05 sec)

插入第二条数据如果是与联合字段中的一条相同另一条相同,也是可以的

  1. mysql> insert into t_user(id,name,email) values(2,'mmm','qq.com');
  2. Query OK, 1 row affected (0.05 sec)

插入第三条数据,如果与联合字段都相同,则报错

  1. mysql> insert into t_user(id,name,email) values(3,'mmm','qq.com');
  2. ERROR 1062 (23000): Duplicate entry 'mmm-qq.com' for key 'name'

3、复合约束

name varchar(32) not null unique

主键和唯一的区别

约束名称保证唯一性是否允许为空一个表中可以有多少个是否允许组合
主键×最多有1个,可以没有√(不推荐)
唯一可以有多个√(不推荐)

主键约束(primary key)PK

表设计时一定要有主键

1、主键涉及术语

  • 主键约束
  • 主键字段
  • 主键值

 2、以上三种术语关系

表中的某个字段添加主键约束后,该字段为主键字段,主键字段中出现的每一个数据都称为主键值

3、主键约束与“not null unique”区别

给某个字段添加主键约束之后,该字段不能重复也不能为空,效果和"not null unique"约束相同,但是本质不同。

主键约束除了可以做到"not null unique"之外,还会默认添加"索引——index"

 4、一张表应该有主键字段,如果没有,表示该表无效

  • 主键值:是当前行数据的唯一标识、是当前行数据的身份证号
  • 即使表中两行记录相关数据相同,但由于主键值不同,所以也认为是两行不同的记录

5、按主键约束的字段数量分类

无论是单一主键还是复合主键,一张表主键约束只能有一个(约束只能有一个,但可以作用到好几个字段)

  • 单一主键:给一个字段添加主键约束
  • 复合主键:给多个字段联合添加一个主键约束(只能用表级定义)

单一主键(列级定义)

  1. create table t_user(
  2. id int(10) primary key,
  3. name varchar(32)
  4. );

单一主键(表级定义)

  1. create table t_user(
  2. id int(10),
  3. name varchar(32) not null,
  4. constraint t_user_id_pk primary key(id)
  5. );

复合主键(表级定义)

  1. create table t_user(
  2. id int(10),
  3. name varchar(32) not null,
  4. email varchar(128) unique,
  5. primary key(id,name)
  6. );

6、在MySQL数据库提供了一个自增的数字,专门用来自动生成主键值,主键值不用用户维护,自动生成,自增数从1开始,以1递增(auto_increment)

  1. create table t_user(
  2. id int(10) primary key auto_increment,
  3. name varchar(32) not null
  4. );

插入两行记录,id主键值会自动增加

  1. mysql> insert into t_user(name) values('jay');
  2. Query OK, 1 row affected (0.04 sec)
  3. mysql> insert into t_user(name) values('man');
  4. Query OK, 1 row affected (0.00 sec)
  5. mysql> select * from t_user;
  6. +----+------+
  7. | id | name |
  8. +----+------+
  9. | 1 | jay |
  10. | 2 | man |
  11. +----+------+
  12. 2 rows in set (0.00 sec)

外键约束(foreign key)FK

只能是表级定义(如以下例子)

foreign key(classno) references t_class(cno)

什么是外键

若有两个表A、B,id是A的主键,而B中也有id字段,则id就是表B的外键,外键约束主要用来维护两个表之间数据的一致性。

A为基本表,B为信息表

1、外键涉及到的术语

  • 外键约束
  • 外键字段
  • 外键值

2、外键约束、外键字段、外键值之间的关系

某个字段添加外键约束之后,该字段称为外键字段,外键字段中每个数据都是外键值

3、按外键约束的字段数量分类

  • 单一外键:给一个字段添加外键约束
  • 复合外键:给多个字段联合添加一个外键约束


4、一张表可以有多个外键字段(与主键不同)


5、分析场景

设计数据库表,用来存储学生和班级信息

方案一:将学生信息和班级信息存储到一张表

  1. sno sname classno cname
  2. 1 jay 100 浙江省第一中学高三1
  3. 2 lucy 100 浙江省第一中学高三1
  4. 3 king 200 浙江省第一中学高三2

方案二:将学生信息和班级信息分开两张表存储

学生表(添加单一外键)

  1. sno(pk) sname classno(fk)
  2. 1 jack 100
  3. 2 lucy 100
  4. 3 king 200

班级表

  1. cno(pk) cname
  2. 100 浙江省第一中学高三1
  3. 200 浙江省第一中学高三2

结论:为了保证学生表中的classno字段中的数据必须来自于班级表中的cno字段中的数据,有必要给学生表中的classno字段添加外键约束

注意点

  • 外键值可以为null
  • 外键字段去引用一张表的某个字段的时候,被引用的字段必须具有unique约束
  • 有了外键引用之后,表分为父表和子表
    • 班级表:父表
    • 学生表:子表
  • 创建先创建父表
  • 删除先删除子表数据
  • 插入先插入父表数据

 存储学生班级信息

  1. mysql> drop table if exists t_student;
  2. mysql> drop table if exists t_class;
  3. mysql> create table t_class(
  4. -> cno int(10) primary key,
  5. -> cname varchar(128) not null unique
  6. -> );
  7. mysql> create table t_student(
  8. -> sno int(10) primary key auto_increment,
  9. -> sname varchar(32) not null,
  10. -> classno int(3),
  11. -> foreign key(classno) references t_class(cno)
  12. -> );
  13. mysql> insert into t_class(cno,cname) values(100,'aaaaaaxxxxxx');
  14. mysql> insert into t_class(cno,cname) values(200,'oooooopppppp');
  15. mysql> insert into t_student(sname,classno) values('jack',100);
  16. mysql> insert into t_student(sname,classno) values('lucy',100);
  17. mysql> insert into t_student(sname,classno) values('king',200);

班级表t_class

  1. mysql> select * from t_class;
  2. +-----+--------------+
  3. | cno | cname |
  4. +-----+--------------+
  5. | 100 | aaaaaaxxxxxx |
  6. | 200 | oooooopppppp |
  7. +-----+--------------+

学生表t_student

  1. mysql> select * from t_student;
  2. +-----+-------+---------+
  3. | sno | sname | classno |
  4. +-----+-------+---------+
  5. | 1 | jack | 100 |
  6. | 2 | lucy | 100 |
  7. | 3 | king | 200 |
  8. +-----+-------+---------+

上表中找出每个学生的班级名称

  1. mysql> select s.*,c.* from t_student s join t_class c on s.classno=c.cno;
  2. +-----+-------+---------+-----+--------------+
  3. | sno | sname | classno | cno | cname |
  4. +-----+-------+---------+-----+--------------+
  5. | 1 | jack | 100 | 100 | aaaaaaxxxxxx |
  6. | 2 | lucy | 100 | 100 | aaaaaaxxxxxx |
  7. | 3 | king | 200 | 200 | oooooopppppp |
  8. +-----+-------+---------+-----+--------------+

结论

以上是典型的一对多的设计:在多的地方加外键(子表加外键)

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号