完整性约束
非空约束 not null
非空约束not null 约束的字段不能为null
create table vip(
id int,
name varchar(255) not null // not null只有列级约束,没有表级约束
);
insert into vip(id,name) values(1,'zhangsan');
insert into vip(id,name) values(2,'lisi');
insert into vip(id) values(3);
ERROR 1364 (HY000): Field 'name' doesn't have a default value
唯一性约束 unique
- 唯一性约束unique约束的字段不能重复,但是可以为NULL
drop table if exists vip;
create table vip(
id int,
name varchar(255) unique,
email varchar(255));
insert into vip(id,name,email) values(1,'zhangsan','zhangsan@qq.com');
insert into vip(id,name,email) values(2,'lisi','lisi@qq.com');
insert into vip(id,name,email) values(2,'zhangsan','lisi@qq.com');
ERROR 1062 (23000): Duplicate entry 'zhangsan' for key 'name'
insert into vip(id,name,email) values(2,null,'lisi@qq.com');
+------+----------+-----------------+
| id | name | email |
+------+----------+-----------------+
| 1 | zhangsan | zhangsan@qq.com |
| 2 | lisi | lisi@qq.com |
| 2 | NULL | lisi@qq.com |
+------+----------+-----------------+
-
需求:name 和 email两个字段联合起来具有唯一性
方法一:
drop table if exists vip; create table vip( id int, name varchar(255) unique,//这是列级约束 email varchar(255) unique); insert into vip(id,name,email) values(1,'zhangsan','zhangsan@qq.com'); insert into vip(id,name,email) values(1,'zhangsan','zhangsan@123.com'); ERROR 1062 (23000): Duplicate entry 'zhangsan' for key 'name' 显然不满足需求; 这种写法表示的意思是,name 和 email 各种唯一,而不是联合唯一
方法二:
drop table if exists vip; create table vip( id int, name varchar(255), email varchar(255), unique(name,email));//这里是表级约束 insert into vip(id,name,email) values(1,'zhangsan','zhangsan@qq.com'); insert into vip(id,name,email) values(1,'zhangsan','zhangsan@123.com'); 运行成功 +------+----------+------------------+ | id | name | email | +------+----------+------------------+ | 1 | zhangsan | zhangsan@qq.com | | 1 | zhangsan | zhangsan@123.com | +------+----------+------------------+
-
unique 和not null可以联合
drop table if exists vip; create table vip( id int unique not null, name varchar(255), email varchar(255)); insert into vip(id,name,email) values(1,'zhangsan','zhangsan@qq.com'); insert into vip(id,name,email) values(null,'zhangsan','zhangsan@123.com'); ERROR 1048 (23000): Column 'id' cannot be null insert into vip(id,name,email) values(1,'zhangsan','zhangsan@qq.com'); ERROR 1062 (23000): Duplicate entry '1' for key 'id'
注意:在mysql当中,如果一个字段同时被not null和unique约束的话,该字段自动变成主键字段。
+-------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+--------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | name | varchar(255) | YES | | NULL | | | email | varchar(255) | YES | | NULL | | +-------+--------------+------+-----+---------+-------+
主键约束 primary key
-
什么是主键
- 主键是每一行记录的唯一标识。
- 主键具有唯一性
- 主键不能为空值
- 任何一张表都应该有主键,没有主键,表无效
-
如何添加主键
drop table if exists vip; create table vip( id int primary key, name varchar(255)); insert into vip(id,name) values(1,'zhangsan'); insert into vip(id,name) values(2,'lisi'); //id不能重复 insert into vip(id,name) values(2,'wangwu'); ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY' //id不能为null insert into vip(id,name) values(null,'wangwu'); ERROR 1048 (23000): Column 'id' cannot be null
-
如何给多个字段联合起来添加主键约束
drop table if exists vip; create table vip( id int primary key, name varchar(255)primary key); ERROR 1068 (42000): Multiple primary key defined
不能直接在列级直接加上两个主键约束
drop table if exists vip; create table vip( id int , name varchar(255), primary key(id,name)); //创建成功 insert into vip(id,name) values(1,'zhangsan'); insert into vip(id,name) values(2,'lisi'); //id和name都不能为null,只要其中一个为null,就不能插入 insert into vip(id,name) values(null,'wangwu'); ERROR 1048 (23000): Column 'id' cannot be null //插入成功 //id和name不能联合起来相同 insert into vip(id,name) values(2,'wangwu');
-
主键可以按功能分为:
自然主键:主键值是一个自然数,和业务没关系。
业务主键:主键值和业务紧密关联,例如拿银行卡账号做主键值。这就是业务主键!在实际开发中使用业务主键多,还是使用自然主键多一些? 自然主键使用比较多,因为主键只要做到不重复就行,不需要有意义。 业务主键不好,因为主键一旦和业务挂钩,那么当业务发生变动的时候, 可能会影响到主键值,所以业务主键不建议使用。尽量使用自然主键。
在mysql当中,有一种机制,可以帮助我们自动维护一个主键值?
drop table if exists vip;
create table vip(
id int primary key auto_increment,
name varchar(255)
);
insert into vip(name) values('zhangsan');
insert into vip(name) values('zhangsan');
insert into vip(name) values('zhangsan');
insert into vip(name) values('zhangsan');
insert into vip(name) values('zhangsan');
insert into vip(name) values('zhangsan');
insert into vip(name) values('zhangsan');
insert into vip(name) values('zhangsan');
+----+----------+
| id | name |
+----+----------+
| 1 | zhangsan |
| 2 | zhangsan |
| 3 | zhangsan |
| 4 | zhangsan |
| 5 | zhangsan |
| 6 | zhangsan |
| 7 | zhangsan |
| 8 | zhangsan |
+----+----------+
外键约束 foreign key
-
背景:
请设计数据库表,来描述“班级和学生”的信息?
第一种方案:班级和学生存储在一张表中???
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 第二中学高三2班 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字段中的每一个值都是外键值。
-
如何加外键约束
create table t_class( calssno int primary key, classname varchar(255)); insert into t_class(calssno,classname) values(1,'class1,senior3,no.2middle school'); insert into t_class(calssno,classname) values(2,'class2,senior3,no.2middle school'); mysql> select * from t_class; +---------+----------------------------------+ | calssno | classname | +---------+----------------------------------+ | 1 | class1,senior3,no.2middle school | | 2 | class2,senior3,no.2middle school | +---------+----------------------------------+ create table t_student( no int primary key, name varchar(255), cno int, foreign key(cno) references t_class(calssno) ); insert into t_student(no,name,cno) values(1,'jack', 1); insert into t_student(no,name,cno) values(2,'lucy', 1); insert into t_student(no,name,cno) values(3,'lilei', 1); insert into t_student(no,name,cno) values(4,'hanmeimei', 1); insert into t_student(no,name,cno) values(5,'zhangsan', 2); insert into t_student(no,name,cno) values(6,'lisi', 2); insert into t_student(no,name,cno) values(7,'wangwu', 2); insert into t_student(no,name,cno) values(8,'zhaoliu', 2); insert into t_student(no,name,cno) values(9,'zhaoliu',null); +----+-----------+------+ | no | name | cno | +----+-----------+------+ | 1 | jack | 1 | | 2 | lucy | 1 | | 3 | lilei | 1 | | 4 | hanmeimei | 1 | | 5 | zhangsan | 2 | | 6 | lisi | 2 | | 7 | wangwu | 2 | | 8 | zhaoliu | 2 | | 9 | zhaoliu | NULL | +----+-----------+------+
子表中的外键引用的父表中的某个字段,被引用的这个字段必须父表的主键吗?
不一定是主键,但至少具有unique约束。外键可以为NULL吗?
外键值可以为NULL。
检查约束 check
sql脚本文件
xxxx.sql这种文件被称为sql脚本文件。
sql脚本文件中编写了大量的sql语句。
我们执行sql脚本文件的时候,该文件中所有的sql语句会全部执行!
批量的执行SQL语句,可以使用sql脚本文件。
在mysql当中怎么执行sql脚本呢?
mysql> source D:\course\03-MySQL\document\vip.sql(脚本文件路径)