约束实际上就是表中数据的限制条件
表在设计的时候加入约束的目的就是为了保证表中的记录完整和有效
下面将逐一介绍以上约束
用not null约束的字段不能为null值,必须给定具体的数据
创建表,给字段添加非空约束(创建用户表,用户名不能为空)
create table t_user(
id int(10),
name varchar(32) not null
);
如果没有插入name字段数据,则会报错
mysql> insert into t_user (id) values(1);
ERROR 1364 (HY000): Field 'name' doesn't have a default value
mysql> CREATE TABLE student(
id INT PRIMARY KEY,
name VARCHAR(50) NOT NULL UNIQUE,
gender VARCHAR(10) DEFAULT '女'
);
insert into student(id,name) values(1,'toc');
insert into student(id,name,gender) values(2,'jok','男');
insert into student(id,name,gender) values(3,'jerry',default);
Query OK, 0 rows affected (0.25 sec)
Query OK, 1 row affected (0.03 sec)
Query OK, 1 row affected (0.04 sec)
Query OK, 1 row affected (0.06 sec)
mysql> SELECT * FROM STUDENT;
+----+-------+--------+
| id | name | gender |
+----+-------+--------+
| 1 | toc | 女 |
| 2 | jok | 男 |
| 3 | jerry | 女 |
+----+-------+--------+
3 rows in set (0.06 sec)
可以看出如果不进行定义的话,gender会默认成为‘女’。
unique约束的字段,具有唯一性,不可重复,但可以为null
创建表,保证邮箱地址唯一(列级约束)
create table t_user(
id int(10),
name varchar(32) not null,
email varchar(128) unique
);
create table t_user(
id int(10),
name varchar(32) not null,
email varchar(128),
unique(email)
);
如果插入相同email会报错
mysql> insert into t_user(id,name,email) values(1,'xlj','[email protected]');
Query OK, 1 row affected (0.00 sec)
mysql> insert into t_user(id,name,email) values(2,'jay','[email protected]');
ERROR 1062 (23000): Duplicate entry '[email protected]' for key 'email'
联合约束,表示两个或以上的字段同时与另一条记录相等,则报错
create table t_user(
id int(10),
name varchar(32) not null,
email varchar(128),
unique(name,email)
);
插入第一条数据
mysql> insert into t_user(id,name,email) values(1,'xxx','qq.com');
Query OK, 1 row affected (0.05 sec)
插入第二条数据如果是与联合字段中的一条相同另一条相同,也是可以的
mysql> insert into t_user(id,name,email) values(2,'mmm','qq.com');
Query OK, 1 row affected (0.05 sec)
插入第三条数据,如果与联合字段都相同,则报错
mysql> insert into t_user(id,name,email) values(3,'mmm','qq.com');
ERROR 1062 (23000): Duplicate entry 'mmm-qq.com' for key 'name'
name varchar(32) not null unique
主键和唯一的区别
约束名称 | 保证唯一性 | 是否允许为空 | 一个表中可以有多少个 | 是否允许组合 |
主键 | √ | × | 最多有1个,可以没有 | √(不推荐) |
唯一 | √ | √ | 可以有多个 | √(不推荐) |
表设计时一定要有主键
表中的某个字段添加主键约束后,该字段为主键字段,主键字段中出现的每一个数据都称为主键值
给某个字段添加主键约束之后,该字段不能重复也不能为空,效果和"not null unique"约束相同,但是本质不同。
主键约束除了可以做到"not null unique"之外,还会默认添加"索引——index"
无论是单一主键还是复合主键,一张表主键约束只能有一个(约束只能有一个,但可以作用到好几个字段)
create table t_user(
id int(10) primary key,
name varchar(32)
);
create table t_user(
id int(10),
name varchar(32) not null,
constraint t_user_id_pk primary key(id)
);
create table t_user(
id int(10),
name varchar(32) not null,
email varchar(128) unique,
primary key(id,name)
);
create table t_user(
id int(10) primary key auto_increment,
name varchar(32) not null
);
插入两行记录,id主键值会自动增加
mysql> insert into t_user(name) values('jay');
Query OK, 1 row affected (0.04 sec)
mysql> insert into t_user(name) values('man');
Query OK, 1 row affected (0.00 sec)
mysql> select * from t_user;
+----+------+
| id | name |
+----+------+
| 1 | jay |
| 2 | man |
+----+------+
2 rows in set (0.00 sec)
只能是表级定义(如以下例子)
foreign key(classno) references t_class(cno)
若有两个表A、B,id是A的主键,而B中也有id字段,则id就是表B的外键,外键约束主要用来维护两个表之间数据的一致性。
A为基本表,B为信息表
某个字段添加外键约束之后,该字段称为外键字段,外键字段中每个数据都是外键值
设计数据库表,用来存储学生和班级信息
方案一:将学生信息和班级信息存储到一张表
sno sname classno cname
1 jay 100 浙江省第一中学高三1班
2 lucy 100 浙江省第一中学高三1班
3 king 200 浙江省第一中学高三2班
方案二:将学生信息和班级信息分开两张表存储
学生表(添加单一外键)
sno(pk) sname classno(fk)
1 jack 100
2 lucy 100
3 king 200
班级表
cno(pk) cname
100 浙江省第一中学高三1班
200 浙江省第一中学高三2班
结论:为了保证学生表中的classno字段中的数据必须来自于班级表中的cno字段中的数据,有必要给学生表中的classno字段添加外键约束
存储学生班级信息
mysql> drop table if exists t_student;
mysql> drop table if exists t_class;
mysql> create table t_class(
-> cno int(10) primary key,
-> cname varchar(128) not null unique
-> );
mysql> create table t_student(
-> sno int(10) primary key auto_increment,
-> sname varchar(32) not null,
-> classno int(3),
-> foreign key(classno) references t_class(cno)
-> );
mysql> insert into t_class(cno,cname) values(100,'aaaaaaxxxxxx');
mysql> insert into t_class(cno,cname) values(200,'oooooopppppp');
mysql> insert into t_student(sname,classno) values('jack',100);
mysql> insert into t_student(sname,classno) values('lucy',100);
mysql> insert into t_student(sname,classno) values('king',200);
班级表t_class
mysql> select * from t_class;
+-----+--------------+
| cno | cname |
+-----+--------------+
| 100 | aaaaaaxxxxxx |
| 200 | oooooopppppp |
+-----+--------------+
学生表t_student
mysql> select * from t_student;
+-----+-------+---------+
| sno | sname | classno |
+-----+-------+---------+
| 1 | jack | 100 |
| 2 | lucy | 100 |
| 3 | king | 200 |
+-----+-------+---------+
上表中找出每个学生的班级名称
mysql> select s.*,c.* from t_student s join t_class c on s.classno=c.cno;
+-----+-------+---------+-----+--------------+
| sno | sname | classno | cno | cname |
+-----+-------+---------+-----+--------------+
| 1 | jack | 100 | 100 | aaaaaaxxxxxx |
| 2 | lucy | 100 | 100 | aaaaaaxxxxxx |
| 3 | king | 200 | 200 | oooooopppppp |
+-----+-------+---------+-----+--------------+
以上是典型的一对多的设计:在多的地方加外键(子表加外键)