目录
1. 约束(constraint)概述
1.1 为什么需要约束
1.2 什么是约束
1.3 约束的分类
2. 非空约束
2.1 作用
2.2 关键字
2.3 特点
2.4 添加非空约束
2.5 删除非空约束
3. 唯一性约束
3.1作用
3.2 关键字
3.3 特点
3.5 关于复合唯一约束
4. 主键(PRIMARY KEY)约束
4.1 作用
4.2 关键字
4.3 特点
4.4 添加主键约束
4.5 关于复合主键
4.6 删除主键约束
5. 自增列:AUTO_INCREMENT
5.1 作用
5.2 关键字
5.3 特点和要求
5.4 如何指定自增约束
5.5 如何删除自增约束
5.6 MySQL 8.0新特性—自增变量的持久化
6. FOREIGN KEY 约束
6.1 作用
6.2 关键字
6.3 主表和从表/父表和子表
6.5 添加外键约束
6.6 约束等级
6.8 开发场景
6.9 阿里开发规范
7. CHECK 约束
7.1 作用
7.2 关键字
7.3 说明:MySQL 5.7 不支持
8. DEFAULT约束
8.1 作用
8.2 关键字
8.3 如何给字段加默认值
位置 支持的约束类型 是否可以起约束名 列级约束: 列的后面 语法都支持,但外键没有效果 不可以 表级约束: 所有列的下面 默认和非空不支持,其他支持 可以(主键没有效果)
#information_schema数据库名(系统库)
#table_constraints表名称(专门存储各个表的约束)
SELECT * FROM information_schema.table_constraints
WHERE table_name = '表名称';
SELECT * FROM information_schema.table_constraints
WHERE table_name = 'employees';
CREATE TABLE 表名称(
字段名 数据类型,
字段名 数据类型 NOT NULL,
字段名 数据类型 NOT NULL
);
(2)建表后 alter table 表名称 modify 字段名 数据类型 not null;
alter table 表名称 modify 字段名 数据类型 NULL;#去掉not null,相当于修改某个非注解字段,
该字段允许为空
或
alter table 表名称 modify 字段名 数据类型;#去掉not null,相当于修改某个非注解字段,
该字段允许为空
用来限制某个字段/某列的值不能重复。
create table 表名称(
字段名 数据类型,
字段名 数据类型 unique,
字段名 数据类型 unique key,
字段名 数据类型
);
create table 表名称(
字段名 数据类型,
字段名 数据类型,
字段名 数据类型,
[constraint 约束名] unique key(字段名)
);
举例:
CREATE TABLE USER(
id INT NOT NULL,
NAME VARCHAR(25),
PASSWORD VARCHAR(16),
-- 使用表级约束语法
CONSTRAINT uk_name_pwd UNIQUE(NAME,PASSWORD)
);
表示用户名和密码组合不能重复(2)建表后指定唯一键约束
#字段列表中如果是一个字段,表示该列的值唯一。如果是两个或更多个字段,那么复合唯一,
#即多个字段的组合是唯一的
#方式1:
alter table 表名称 add unique key(字段列表);#方式2:
alter table 表名称 modify 字段名 字段类型 unique;
create table 表名称(
字段名 数据类型,
字段名 数据类型,
字段名 数据类型,
unique key(字段列表) #字段列表中写的是多个字段名,多个字段名用逗号分隔,表示那么是复合唯一,即多
个字段的组合是唯一的
);
SELECT * FROM information_schema.table_constraints WHERE table_name = '表名';
#查看都有哪些约束ALTER TABLE 表名
DROP INDEX 唯一约束名;
create table 表名称(
字段名 数据类型 primary key, #列级模式
字段名 数据类型,
字段名 数据类型
);
create table 表名称(
字段名 数据类型,
字段名 数据类型,
字段名 数据类型,
[constraint 约束名] primary key(字段名) #表级模式
);
(2)建表后增加主键约束 ALTER TABLE 表名称 ADD PRIMARY KEY(字段列表);
#字段列表可以是一个字段,也可以是多个字段,
#如果是多个字段的话,是复合主键
create table 表名称(
字段名 数据类型,
字段名 数据类型,
字段名 数据类型,
primary key(字段名1,字段名2) #表示字段1和字段2的组合是唯一的,也可以有更多个字段
);
alter table 表名称 drop primary key;
说明:删除主键约束,不需要指定主键名,因为一个表只有一个主键,删除主键约束后,非空还存在。
create table 表名称(
字段名 数据类型 primary key auto_increment,
字段名 数据类型 unique key not null,
字段名 数据类型 unique key,
字段名 数据类型 not null default 默认值,
);
create table 表名称(
字段名 数据类型 default 默认值 ,
字段名 数据类型 unique key auto_increment,
字段名 数据类型 not null default 默认值,
primary key(字段名)
);
(2)建表后 alter table 表名称 modify 字段名 数据类型 auto_increment;
alter table 表名称 modify 字段名 数据类型 auto_increment;#给这个字段增加自增约束
alter table 表名称 modify 字段名 数据类型; #去掉auto_increment相当于删除
CREATE TABLE test1(
id INT PRIMARY KEY AUTO_INCREMENT
);
插入4个空值,执行如下:
INSERT INTO test1
VALUES(0),(0),(0),(0);
查询数据表test1中的数据,结果如下: 删除id为4的记录,语句如下:
DELETE FROM test1 WHERE id = 4;
再次插入一个空值,语句如下: INSERT INTO test1 VALUES(0);
查询此时数据表test1中的数据,结果如下: 从结果可以看出,虽然删除了id为4的记录,但是再次插入空值时,并没有重用被删除的4,而是分配了 5。 删除id为5的记录,结果如下:
DELETE FROM test1 where id=5;
重启数据库,重新插入一个空值。 INSERT INTO test1 values(0);
再次查询数据表test1中的数据,结果如下:
从结果可以看出,自增变量已经持久化了。
MySQL 8.0将自增主键的计数器持久化到 重做日志中。每次计数器发生改变,都会将其写入重做日志中。如果数据库重启,InnoDB会根据重做日志中的信息来初始化计数器的内存值。
create table 主表名称(
字段1 数据类型 primary key,
字段2 数据类型
);
create table 从表名称(
字段1 数据类型 primary key,
字段2 数据类型,
[CONSTRAINT <外键约束名称>] FOREIGN KEY(从表的某个字段) references 主表名(被参考字段)
);#(从表的某个字段)的数据类型必须与主表名(被参考字段)的数据类型一致,逻辑意义也一样
#(从表的某个字段)的字段名可以与主表名(被参考字段)的字段名一样,也可以不一样
-- FOREIGN KEY: 在表级指定子表中的列
-- REFERENCES: 标示在父表中的列
create table dept( #主表
did int primary key, #部门编号
dname varchar(50) #部门名称
);
create table emp(#从表
eid int primary key, #员工编号
ename varchar(5), #员工姓名
deptid int, #员工所在的部门
foreign key (deptid) references dept(did)
#在从表中指定外键约束
#emp表的deptid和和dept表的did的数据类型一致,意义都是表示部门的编号
);
说明: (1)主表dept必须先创建成功,然后才能创建emp表,指定外键成功。 (2)删除表时,先删除从表emp,再删除主表dept (2)建表后 一般情况下,表与表的关联都是提前设计好了的,因此,会在创建表的时候就把外键约束定义好。不过,如果需要修改表的设计(比如添加新的字段,增加新的关联关系),但没有预先定义外键约束,那么,就要用修改表的方式来补充定义。 格式: ALTER TABLE 从表名 ADD [CONSTRAINT 约束名] FOREIGN KEY (从表的字段) REFERENCES
主表名(被引用字段) [on update xx][on delete xx];
举例: ALTER TABLE emp1
ADD CONSTRAINT emp_dept_id_fk FOREIGN KEY(dept_id) REFERENCES dept(dept_id);
总结:约束关系是针对双方的 添加了外键约束后,主表的修改和删除数据受约束 添加了外键约束后,从表的添加和修改数据受约束 在从表上建立外键,要求主表必须存在 删除主表时,要求从表先删除,或将从表中外键引用该主表的关系先删除
如果没有指定等级,就相当于Restrict方式。 对于外键约束,最好是采用: ON UPDATE CASCADE ON DELETE RESTRICT 的方式。(1)演示1:on update cascade on delete set null
create table dept(
did int primary key, #部门编号
dname varchar(50) #部门名称
);
create table emp(
eid int primary key, #员工编号
ename varchar(5), #员工姓名
deptid int, #员工所在的部门
foreign key (deptid) references dept(did) on update cascade on delete set null
#把修改操作设置为级联修改等级,把删除操作设置为set null等级
);insert into dept values(1001,'教学部');
insert into dept values(1002, '财务部');
insert into dept values(1003, '咨询部');insert into emp values(1,'张三',1001); #在添加这条记录时,要求部门表有1001部门
insert into emp values(2,'李四',1001);
insert into emp values(3,'王五',1002);select * from dept;
select * from emp;#修改主表成功,从表也跟着修改,修改了主表被引用的字段1002为1004,
#从表的引用字段就跟着修改为1004了
update dept set did = 1004 where did = 1002;
#删除主表的记录成功,从表对应的字段的值被修改为null
mysql> delete from dept where did = 1001;
在 MySQL 里,外键约束是有成本的,需要消耗系统资源。对于大并发的 SQL 操作,有可能会不适合。比如大型网站的中央数据库,可能会 因为外键约束的系统开销而变得非常慢 。所以, MySQL 允许你不使用系统自带的外键约束,在 应用层面 完成检查数据一致性的逻辑。也就是说,即使你不用外键约束,也要想办法通过应用层面的附加逻辑,来实现外键约束的功能,确保数据的一致性。
【 强制 】不得使用外键与级联,一切外键概念必须在应用层解决。 说明:(概念解释)学生表中的 student_id 是主键,那么成绩表中的 student_id 则为外键。如果更新学生表中的 student_id,同时触发成绩表中的 student_id 更新,即为级联更新。外键与级联更新适用于 单机低并发 ,不适合 分布式 、 高并发集群 ;级联更新是强阻塞,存在数据库 更新风暴 的风险;外键影响数据库的 插入速度 。
create table employee(
eid int primary key,
ename varchar(5),
gender char check ('男' or '女')
);
create table 表名称(
字段名 数据类型 primary key,
字段名 数据类型 unique key not null,
字段名 数据类型 unique key,
字段名 数据类型 not null default 默认值,
);
(2)建表后
alter table 表名称 modify 字段名 数据类型 default 默认值;
#如果这个字段原来有非空约束,你还保留非空约束,那么在加默认值约束时,
#还得保留非空约束,否则非空约束就被删除了
#同理,在给某个字段加非空约束也一样,如果这个字段原来有默认值约束,
#你想保留,也要在modify语句中保留默认值约束,否则就删除了
alter table 表名称 modify 字段名 数据类型 default 默认值 not null;
alter table 表名称 modify 字段名 数据类型 ;#删除默认值约束,也不保留非空约束
alter table 表名称 modify 字段名 数据类型 not null; #删除默认值约束,保留非空约束
上一篇:Maven依赖的基本概念
下一篇:jQuery 常用API