一、约束
1、什么是约束
含义:一种限制,用于限制表中的数据,为了保证表中的数据的正确性、有效性和可靠性。
为了保证数据的一致性和完整性,SQL规定以约束的方式对表数据进行额外的条件限制。
约束是表级的强制规定。
可以在创建表时规定约束(通过create table语句),或者在表创建之后也可以(通过 alter table语句)。
2、约束分类
有以下六种约束:
NOT NULL:非空约束,规定某个字段不能为 null
UNIQUE:唯一约束,规定某个字段在整个表中是唯一的
PRIMARY KEY:主键(非空且唯一)
CHECK :检查约束(MySQL不支持)
DEFAULT:默认值,用于保证该字段有默认值
FOREIGN KEY:外键,用于限制两个表的关系,用于保证该字段的值必须来自于主表的关联列的值,在从表添加外键约束用于引用主表中某列的值
注意:MySQL 不支持 check 约束,但可以使用 check 约束,而没有任何效果。
根据约束数据列的限制,约束可分为:
① 单列约束:每个约束只约束一列
② 多列约束:每个约束可约束多列数据
根据约束的作用范围,约束可分为:
① 列级约束只能作用在一个列上,跟在列的定义后面;
② 表级约束可以作用在多个列上,不与列一起,而是单独定义;
3、
二、六大约束
1、NOT NULL约束
(1)NOT NULL 约束概述
非空约束用于确保当前列的值不为空值,非空约束只能出现在表对象的列上。
NULL 类型特征:
① 所有的类型的值都可以是 null,包括 int、float 等数据类型;
② 空字符串 "" 不等于 null,0 也不等于 null;
(2)设置NOT NULL 约束
① 创建 NOT NULL 约束
CREATE TABLE emp(
id INT(10) NOT NULL,
NAME VARCHAR(20) NOT NULL DEFAULT 'abc',
sex CHAR NULL
);
② 增加 NOT NULL 约束
ALTER TABLE emp
MODIFY sex VARCHAR(30) NOT NULL;
③ 取消 NOT NULL 约束
ALTER TABLE emp
MODIFY sex VARCHAR(30) NULL;
④ 取消 NOT NULL 约束,增加默认值
ALTER TABLE emp
MODIFY NAME VARCHAR(15) DEFAULT 'abc' NULL;
2、UNIQUE 约束
(1)UNIQUE 约束概述
唯一约束概念:表中的某一列不能出现重复的值,必须保证值的唯一性。
同一个表可以有多个唯一约束,多个列组合的约束。
在创建唯一约束的时候,如果不给唯一约束名称,就默认和列名相同。
MySQL 会给唯一约束的列上默认创建一个唯一索引。
(2)设置 UNIQUE 约束
① 创建 UNIQUE 约束
CREATE TABLE USER(
id INT NOT NULL,
NAME VARCHAR(25),
PASSWORD VARCHAR(16),
#使用表级约束语法
CONSTRAINT uk_name_pwd UNIQUE(NAME,PASSWORD)
);
表示用户名和密码组合不能重复。
CREATE TABLE student(
id INT,
phone_number VARCHAR(20) UNIQUE -- 添加了唯一约束
);
注意:在MySQL中,唯一约束限定的列的值可以有多个 null。(null表示不确定,即不相等)
② 添加唯一约束
#①列级约束
ALTER TABLE stuinfo MODIFY COLUMN seat INT UNIQUE;
#②表级约束
ALTER TABLE stuinfo ADD UNIQUE(seat);
③ 修改唯一约束
ALTER TABLE USER
ADD UNIQUE(NAME,PASSWORD);
④ 删除约束
alter table 表名 drop index 索引名;
ALTER TABLE USER
drop index UNIQUE(NAME,PASSWORD);
3、PRIMARY KEY 约束
(1)主键约束概述
主键约束相当于唯一约束+非空约束的组合,主键约束列不允许重复,也不允许出现空值;
如果是多列组合的主键约束,那么这些列都不允许为空值,并且组合的值不允许重复。;
每个表最多只允许一个主键,建立主键约束可以在列级别创建,也可以在表级别上创建。
MySQL的主键名总是PRIMARY,当创建主键约束时,系统默认会在所在的列和列组合上建立对应的唯一索引。
(2)设置主键约束
① 创建主键约束
三种模式:
② 添加主键约束
ALTER TABLE emp5
ADD PRIMARY KEY(NAME,pwd);
③ 修改主键约束
ALTER TABLE emp5
MODIFY id INT PRIMARY KEY;
④ 删除主键约束
ALTER TABLE emp5
DROP PRIMARY KEY;
注意:
① 主键非空且唯一;
② 一张表只能有一个字段(组)作为主键;
③ 主键就是表中记录的唯一标识;
4、FOREIGN KEY 约束
(1)FOREIGN KEY 概述
外键约束是保证一个或两个表之间的参照完整性,外键是构建于一个表的两个字段或是两个表的两个字段之间的参照关系;
从表的外键值必须在主表中能找到或者为空。当主表的记录被从表参照时,主表的记录将不允许删除,如果要删除数据,需要先删除从表中依赖该记录的数据,然后才可以删除主表的数据。
注意:外键约束的参照列,在主表中引用的只能是主键或唯一键约束的列。
同一个表可以有多个外键约束。
外键示意图:
主表:一方,用来约束别人的表;
从表:多方法,被别人约束的表;
(2)单表存储数据的缺点
单表存储数据可能会造成的缺点:
① 数据冗余;
② 后期还会出现增删改的问题;
所以使用外键约束来解决。
(3)设置 FOREIGN KEY
① 创建外键约束
② 设置多列外键
创建多列外键组合,必须使用表级约束:
③ 增加外键约束
ALTER TABLE 表名 ADD [CONSTRAINT] [外键名称] FOREIGN KEY (外键字段名称) REFERENCES 主表名称(主表列名称);
ALTER TABLE emp
ADD [CONSTRAINT emp_dept_id_fk] FOREIGN KEY(dept_id)
REFERENCES dept(dept_id);
④ 删除外键约束
ALTER TABLE emp
DROP FOREIGN KEY emp_dept_id_fk;
(4)FOREIGN KEY 约束的关键字
FOREIGN KEY:在表级指定子表中的列
REFERENCES:标示在父表中的列
(5)级联操作
当改变主表中的主键时,修改失败;在删除主表中的记录时,也出现删除失败。
级联操作:在修改和删除主表的主键时,同时更新或删除副表的外键值,称为级联操作。
ON DELETE CASCADE(级联删除):当父表中的列被删除时,子表中想对应的列也被删除;
ON DELETE SET NULL(级联置空):子表中相应的列置空
CREATE TABLE student(
id INT AUTO_INCREMENT PRIMARY KEY,
NAME VARCHAR(20),
classes_name VARCHAR(20),
classes_number INT,
/*表级别联合外键*/
FOREIGN KEY(classes_name, classes_number)
REFERENCES classes(NAME, number) ON DELETE CASCADE
);
5、CHECK 约束
(1)CHECK 约束概述
MySQL 可以使用 check 约束,但 check 约束对数据验证没有任何作用,添加数据时,没有任何错误或警告。
(2)设置 CHECK 约束
CREATE TABLE temp(
id INT AUTO_INCREMENT,
NAME VARCHAR(20),
age INT CHECK(age > 20),
PRIMARY KEY(id)
);
三、创建表时添加约束
1、添加列级约束
(1)语法
直接在字段和类型后面追加约束类型即可,
只支持:默认约束,非空约束,主键约束,唯一约束,其他约束不报错,没有效果;
(2)案例
CREATE TABLE major (
id INT PRIMARY KEY,
majorName VARCHAR(20)
);
CREATE TABLE stuinfo(
id INT PRIMARY KEY, #主键
stuName VARCHAR(20) NOT NULL, #非空
gender CHAR(1) CHECK(gender='男' OR gender='女'), #检查约束,不生效
seat INT UNIQUE, #唯一约束
age INT DEFAULT 20, #默认约束
majorId INT REFERENCES major(id) #外键,不生效
);
查看表中所有的索引,包括主键,外键,唯一
SHOW INDEX FROM stuinfo;
2、添加表级约束
(1)语法
在各个字段的最后面【constraint 约束名】 约束类型(字段名)。
不支持默认与非空约束。
(2)案例
CREATE TABLE stuinfo (
id INT,
stuName VARCHAR(20),
gender CHAR(1),
seat INT,
age INT,
majorid INT,
CONSTRAINT pk PRIMARY KEY(id), #为id添加主键
CONSTRAINT uq UNIQUE(seat), #唯一键
CONSTRAINT ck CHECK(gender = '男' OR gender = '女'), #检查
CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorid) REFERENCES major(id) #外键
);
通用写法:
CREATE TABLE IF NOT EXISTS stuinfo(
id INT PRIMARY KEY,
stuName VARCHAR(20) NOT NULL,
sex CHAR(1),
age DEFAULT 18,
seat INT UNIQUE,
majorid INT,
CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorid) REFERENCES major(id)
);
四、修改表时添加约束
1、语法
① 添加列级约束
alter table 表名 modify column 字段名 字段类型 新约束;
② 添加表级约束
alter table 表名 add 【constraint 约束名】 约束类型(字段名) 【外键的引用】;
2、案例
创建表:
DROP TABLE IF EXISTS stuinfo;
CREATE TABLE stuinfo (
id INT,
stuName VARCHAR(20),
gender CHAR(1),
seat INT,
age INT,
majorid INT
);
① 添加非空约束
ALTER TABLE stuinfo MODIFY COLUMN stuname VARCHAR(20) NOT NULL;
② 添加默认约束
ALTER TABLE stuinfo MODIFY COLUMN age INT DEFAULT 18;
③ 添加主键约束
a 列级约束
ALTER TABLE stuinfo MODIFY COLUMN id INT PRIMARY KEY;
b 表级约束
ALTER TABLE stuinfo ADD PRIMARY KEY(id);
④ 添加唯一约束
a 列级约束
ALTER TABLE stuinfo MODIFY COLUMN seat INT UNIQUE;
b 表级约束
ALTER TABLE stuinfo ADD UNIQUE(seat);
⑤ 添加外键约束
ALTER TABLE stuinfo ADD FOREIGN KEY(majorid) REFERENCES major(id);
五、修改表时删除约束
1、删除非空约束
ALTER TABLE stuinfo MODIFY COLUMN stuname VARCHAR(20) NULL;
2、删除默认约束
ALTER TABLE stuinfo MODIFY COLUMN age INT;
3、删除主键
ALTER TABLE stuinfo DROP PRIMARY KEY;
4、删除唯一
ALTER TABLE stuinfo DROP INDEX seat;
5、删除外键
ALTER TABLE stuinfo DROP FOREIGN KEY majorid;
六、约束的对比
1、主键和唯一的对比
保证唯一性 | 是否允许非空 | 一个表是否可以有多个 | 是否允许组合 | |
主键 | 可以 | 不允许 | 至多一个 | 允许,但不推荐 |
唯一 | 可以 | 允许 | 可以有多个 | 允许,但不推荐 |
2、外键
(1)要求在从表设置外键关系;
(2)从表的外键列的类型和主表的关联列的类型要求一致或兼容,名称无要求;
(3)主表中的关联列必须是一个 key(一般是主键或唯一);
(4)插入数据时,先插入主表,再插入从表;删除数据时,先删除从表再删除主表;
3、列级约束和表级约束
位置 | 支持的约束类型 | 是否可以起约束名 | |
列级约束 | 列的后面 | 语法都支持,但外键没有效果 | 不可以 |
表级约束 | 所有列的下面 | 默认和非空不支持,其他支持 | 可以(主键没有效果) |
七、标识列
1、标识列是什么
标识列又称自增长列。
含义:可以不用手动的插入值,系统提供默认的序列值;
特点:
(1)标识列必须和主键搭配吗?不一定,但要求是一个key
(2)一个表可以有几个标识列?至多一个!
(3)标识列的类型只能是数值型
(4)标识列可以通过 SET auto_increment_increment=3;设置步长,可以通过 手动插入值,设置起始值
2、查看设置标识列信息
使用命令查看信息
SHOW VARIABLES LIKE '%auto_increment%'
默认 auto_increment 的开始值是 1,如果希望修改起始值,使用下面语法。
设置步长值:
SET auto_increment_increment = 2; #步长
SET auto_increament_offset = '2'; #起始值(不生效,不支持更改)
除此之外,还可以有下面的操作:
① 创建时指定起始值
CREATE TABLE 表名(
列名 int primary key AUTO_INCREMENT
) AUTO_INCREMENT=起始值;
② 创建好以后修改起始值
ALTER TABLE 表名 AUTO_INCREMENT=起始值;
3、设置标识列
(1)创建表时设置标识列
CREATE TABLE tab_identity ( id INT PRIMARY KEY AUTO_INCREMENT, #设置主键,并为自增长列(必须是整数类型) NAME VARCHAR(20) );
(2)修改表时设置标识列
ALTER TABLE tab_identity MODIFY COLUMN PRIMARY KEY AUTO_INCREMENT;
(3)修改表时删除标识列
ALTER TABLE tab_identity MODIFY COLUMN PRIMARY KEY;
4、delete 和 truncate 对自增长的影响
① delete:删除所有记录之后,自增长没有影响;
② truncate:删除以后,自增长又重新开始;
八、数据约束总结
约束名 | 关键字 | 说明 |
主键 | primary key |
① 唯一 ② 非空 |
默认 | default | 如果一列没有值,使用默认值 |
非空 | not null | 这一列必须有值 |
唯一 | unique | 这一列不能有重复值 |
外键 | foreign key | 主表中主键列,在从表中外键列 |