5天手把手教你,MySql从入门到精通:05.MySql约束-聚侠网漫画
约束:constraint验证表的输入数据的有效性的。
约束的类型:
主键约束:primary key,唯一且不能为NULL
外键约束:foreign key,表与表之间引用关系,一个表的某个字段去引用另外一个表的字段值
唯一性约束:unique,唯一,但允许为NULL
非空约束:NOT NULL,给字段赋值时,不能为NULL值
缺省值(约束)属性:default,当不给某个字段赋值时,就取默认值/缺省值
检查约束(MySql不支持检查约束):check
1、主键约束
要求任何创建一个表必须带一个主键,主键就表示确定数据行或者记录是唯一的。
主键的特征:
1)、各行主键列的值不能重复
2)、不能为空
3)、一个表只有一个主键,主键列可以是一个字段列、也可以是多个字段列。
如果是多个字段构成的主键,就称为联合主键或者组合主键。
组成主键的多个字段值各行不重复即可。
create table exam
(
id int primary key,
sid int,
cid int,
result float(5,2)
);
或:
create table exam
(
id int,
sid int,
cid int,
result float(5,2),
primary key(id)
);
insert into exam values(1,1001,1,98);
insert into exam values(1,1002,2,37.5);
insert into exam values(null,1003,3,90);
insert into exam values(2,1002,2,37.5);
联合主键:
create table exam2
(
sid int,
cid int,
result float(5,2),
primary key(sid,cid)
);
insert into exam2 values(1001,1,98);
insert into exam2 values(1001,2,37.5);
insert into exam2 values(1001,1,90);
insert into exam2 values(1002,2,37.5);
insert into exam2 values(null,null,37.5);
create table employees2
(
id int primary key, -- 员工编号
name varchar(50), -- 员工姓名
sex char(1), -- 员工性别
hiredate datetime, -- 入职日期
salary float(10,2) -- 工资
);
2、非空约束:not null
字段默认是允许为null的,如果不允许为null,须添加not null
create table employees3
(
id int primary key, -- 员工编号
name varchar(50) not null, -- 员工姓名
sex varchar(2), -- 员工性别
birthday date, -- 生日
salary float -- 工资
);
或者
create table employees3
(
id int, -- 员工编号
name varchar(50) not null, -- 员工姓名
sex varchar(2), -- 员工性别
birthday date, -- 生日
salary float, -- 工资
primary key(id)
);
insert into employees3 values(1001,'刘备','男','2000-1-1',1000);
insert into employees3 values(1001,'关羽','女','2002-11-18',2000);
insert into employees3 values(null,'关羽','女','2002-11-18',2000);
insert into employees3 values(1002,null,'女','2002-11-18',2000);
insert into employees3(id,sex,birthday,salary) values(1002,'女','2002-11-18',2000);
insert into employees3 values(1002,'关羽','女','2002-11-18',2000);
联合主键示例:创建成绩表,有4列,学号、科目号、考试日期和成绩
要求学号、科目编号和考试日期做为联合主键。成绩不能为空。
create table result
(
studentno int,
subjectno int,
examdate date,
result float(5,2) not null,
primary key(studentno,subjectno,examdate)
);
insert into result values(1,1,'2022-2-15',100);
insert into result values(1,1,'2022-2-15',100);
insert into result values(1,2,'2022-2-15',100);
insert into result values(2,1,'2022-2-15',100);
insert into result values(2,2,'2022-2-15',100);
3、检查约束
create table employees4
(
id int primary key, -- 员工编号
name varchar(50) not null, -- 员工姓名
sex varchar(2), -- 员工性别
birthday date, -- 生日
salary float, -- 工资
check(sex='男' or sex='女')
);
insert into employees4 values(1003,'张飞','女性','2004-8-31',3000);
经过测试,发现CHECK检查约束无效。
使用ENUM枚举类型实现
drop table employees4;
create table employees4
(
id int primary key, -- 员工编号
name varchar(50) not null, -- 员工姓名
sex enum('男','女'), -- 员工性别
birthday date, -- 生日
salary float-- 工资
);
insert into employees4 values(1003,'张飞','女性','2004-8-31',3000);
insert into employees4 values(1003,'张飞','女','2004-8-31',3000);
insert into employees4 values(1001,'刘备','男','2000-1-1',1000);
insert into employees4 values(1002,'关羽',null,'2002-12-15',2000);
4、缺省值/默认值DEFAULT default
缺省值在mysql中不是一种约束,而是一种属性
drop table employees4;
create table employees4
(
id int primary key, -- 员工编号
name varchar(50) not null, -- 员工姓名
sex enum('男','女'), -- 员工性别
birthday date, -- 生日
salary float(10,2) default 1000 -- 工资
);
insert into employees4(id,name,sex,birthday) values(1001,'刘备','男','2000-1-1');
insert into employees4 values(1002,'关羽',null,'2002-12-15',default);
insert into employees4 values(1003,'张飞','女','2004-8-31',3000);
insert into employees4 values(1004,'赵云','女','2004-8-31',null);
5、唯一性约束UNIQUE
唯一性约束:
1)各行字段值不能重复
2)但允许为null
3)而且允许多个为null
create table employees5
(
id int primary key, -- 员工编号,主键
name varchar(50) not null, -- 员工姓名,不能为空
sex enum('男','女'), -- 员工性别,枚举值
birthday date, -- 生日
salary float default 1000, -- 工资,缺省值是1000
pid varchar(18) unique-- 身份证号码,唯一性
);
insert into employees5 values(1001,'刘备','男','2000-1-1',1500,'123');
insert into employees5 values(1002,'关羽',null,'2002-12-15',2000,'123');
insert into employees5 values(1002,'关羽',null,'2002-12-15',2000,'456');
insert into employees5 values(1003,'张飞','女','2004-8-31',3000,null);
insert into employees5 values(1004,'赵子龙','男','2008-8-31',5000,null);
insert into employees5 values(1005,'孔明','男','2008-8-31',default,null);
insert into employees5(id,name,sex,birthday,pid) values(1006,'李白','男','2008-8-31','1111');
6、外键约束 FOREIGN KEY
数据表之间的关联/引用关系是依靠具体的主键(primary key)和外键(foreign key)建立起来的。
被引用的表:主表/父表
外键所在的表或者引用表:从表/子表/明细表
主键:帮助MySQL以最快的速度把一条特点的数据记录的位置确定下来。
主键必须是唯一的
主键应该是紧凑的,因此整数类型比较适合
外键:引用另外一个数据表的某条记录。
外键列类型尽可能与主键列类型保持一致
外键列应该加上NOT NULL
创建外键的条件:
0、主表被引用的字段必须是主键
1、从表的外键字段必须与主表的主键字段在数据类型和长度/精度上要相同,
否则无法创建外键约束。
2、字段名可以不同。
3、必须先建主表,再建从表。
--创建部门表:主表/父表
create table departments
(
id int primary key,-- 部门编号
name varchar(50) not null-- 部门名称
);
-- 创建员工表:从表/子表/明细表
create table employees6
(
id int primary key, -- 员工编号,自动编号
name varchar(50) not null, -- 员工姓名
sex enum('男','女'), -- 员工性别
hiredate date, -- 入职日期
salary float default 1000, -- 工资
pid varchar(18) unique,-- 身份证号码
departmentid int,-- 部门编号
foreign key(departmentid) references departments(id) -- 定义部门编号为外键
);
-- 查看创建表的明细信息
show create table employees6;
-- 添加记录
insert into departments values(10,'研发部');
insert into departments values(20,'人事部');
insert into departments values(30,'销售部');
insert into departments values(40,'总裁部');
insert into employees6 values(1001,'刘备','男','2000-1-1',1500,'123',40);
insert into employees6 values(1002,'关羽',null,'2002-12-15',2000,'456',10);
insert into employees6 values(1003,'张飞','女','2004-8-31',3000,null,50);
insert into employees6 values(1004,'赵子龙','男','2008-8-31',5000,null,null);
insert into employees6 values(1003,'张飞','女','2004-8-31',3000,null,20);
注意事项:
1、当主表中没有对应的记录时,不能将记录添加到子表
——员工表中不能出现在部门信息表中不存在的部门编号;
insert into employees6 values(1003,'张飞','女','2004-8-31',3000,null,50);
2、不能更改主表中的值而导致子表中的记录孤立
意即主表中的字段被从表中引用了,是无法修改主表的主键值的,相反是可以的。
——把部门信息表中的部门编号改变了,员工表中的部门编号也应当随之改变;
update departments set id=100 where id=10;
update departments set id=300 where id=30;
3、子表存在与主表对应的记录,不能从主表中删除该行
——不能把有员工的部门编号删除了
delete from departments where id=10;
delete from departments where id=300;
4、删除主表前,先删子表:删除的顺序与创建的顺序正好相反。
——先删员工表、后删除部门表
drop table departments;
drop table employees6;
自动编号auto_increment属性
1、创建表的时候指定自动编号
如果不给自动编号字段赋值,则由系统自动产生做为值给字段;
MySql也允许人为赋值给自动编号的字段,以后产生的自动编号将从人为赋值的值开始自动产生编号;
如果后面再人为赋值给自动编号的字段,后面再产生的自动编号将从最大的人为赋值开始产生自动编号。
注意:
1.自动编号的字段要求必须是主键整型,否则不能创建表。
2.不能删除带自动编号的主键,除非去除自动编号属性。
create table employees7
(
id int primary key auto_increment,
name varchar(50)
);
insert into employees7(name) values('刘备');
insert into employees7(name) values('关羽');
insert into employees7 values(10,'张飞');
insert into employees7(name) values('赵云');
insert into employees7(name) values('孔明');
select * from employees7;
2、指定初始值为其他值,默认为1
create table employees8
(
id int primary key auto_increment,
name varchar(50)
)auto_increment=1000; -- 自动编号的初始值为100
insert into employees8(name) values('刘备');
insert into employees8(name) values('关羽');
3、设置步长为其他步长,默认步长为1
set session auto_increment_increment=5; -- 会话
insert into employees8(name) values('张飞');
insert into employees8(name) values('赵云');
设置的步长是针对当前整个运行环境会话有效的,这样会影响其他表的自动编号的步长值,需要时时地修改该参数。
会话:表示一个客户端与服务器建立连接通信的整个过程。
练习:
1.建立一个学生信息表(student)
定义列sno学号,类型为5位定长字符串,非空,主键
定义列sname姓名,类型为8位定长字符串,非空
定义列ssex性别,取值1或0
定义列sage年龄,类型为短整型
定义列sdept系名,数据类型为20位变长字符串
2.建立一个课程信息表(course)
定义列courseid课程号,类型为整型,非空,自动增长,主键
定义列cname课程名,类型为16位变长字符串,非空
3.建立一个学生考试成绩信息表(sc)
sno学号,外键
cid课程编号,外键
定义列grade成绩,类型为整型
-- 创建学生表
create table student
(
snochar(5) primary key,
snamechar(8) not null,
ssexenum('1','0'),
sagesmallint,
sdepvarchar(20)
);
-- 创建课程表
create table course
(
courseid int primary key auto_increment,
cname varchar(16) not null
);
-- 创建成绩表
create table sc
(
snochar(5),
cidint,
gradeint,
foreign key(sno) references student(sno), -- 学号外键
foreign key(cid) references course(courseid),-- 课程编号外键
primary key(sno,cid)-- 联合主键
);
-- 练习
-- 创建数据库myschool
create database myschool;
-- 打开数据库myschool
use myschool;
-- 创建学生表student
create table student
(
studentNoint primary key comment '学号',
loginPwdvarchar(20) not null,
studentNamevarchar(50) not null,
sexchar(2) not null default '男',
gradeIDint unsigned,
phonevarchar(50),
addressvarchar(255) default '地址不详',
borndatedatetime,
emailvarchar(50),
identityCardvarchar(18) unique
);
insert into student values(1001,'123456','刘备','男',1,'13823121234',default,'2012-1-1','liubei@qq.com','123');
-- 创建科目表
create table subject
(
subjectNoint primary key auto_increment,
subjectNamevarchar(50),
classHourint,
gradeIDint
);
-- 创建成绩表
create table result
(
studentNoint,
subjectNoint,
examDatedatetime,
studentResultint,
foreign key(studentNo) references student(studentNo),
foreign key(subjectNo) references subject(subjectNo),
primary key(studentNo,subjectNo,examDate)
);
总结:
1、PRIMARY KEY 主码约束(主键)
2、UNIQUE唯一性约束
3、NOT NULL非空值约束
4、AUTO_INCREMENT 用于整数列默认自增1
5、UNSIGNED 无符号整数
6、DEFAULT default_value 默认值约束
7、DEFAULT cur_timestamp创建新记录时默认保存当前时间
(仅适用timestamp数据列)
8、ON UPDATE cur_timestamp 修改记录时默认保存当前时间
(仅适用timestamp数据列)
9、CHARACTER SET name 指定字符集(仅适用字符串)