一、MySQL约束
参考【MySQL】约束_mysql约束-CSDN博客
- not null:非空约束
- unique:唯一性约束
- primary key:主键约束
- foreign key:外键约束
- check:检查约束
- default:默认值约束
如何添加约束
- 在CREATE TABLE时添加约束
- 使用ALTER TABLE添加约束,也可以使用这个删除约束
约束类型介绍
1. NOT NULL 非空约束:限制某个字段/某列的值不允许为空
注意:
空字符串不等于null,0也不等于null
如果没有使用not null约束,那么默认情况下所有的类型都是可以为null的
非空约束只能设置成列级约束
1)如何在建表时创建非空约束
CREATE TABLE t_decade_test_not_null(
id INT NOT NULL,
last_name VARVHAR(20) NOT NULL,
email VARCHAR(25),
salary DECIMAL(10,2)
);
2)创建完这个表后,如下几种情况会报错
- 使用insert插入数据,id或者last_name的值为null
- 使用insert插入数据,没有给id或者last_name字段赋值,且没有指定它的默认值
- 只用update更新数据,给id或者last_name字段传递的值为null
3)如何使用ALTER TABLE添加约束,我们还是以之前的t_decade_test_not_null为例
对email字段添加一个非空约束,但是如果email字段已经存在null值,那么下方的语句是无法执行的
ALTER TABLE t_decade_test_not_null
MODIFY email VARCHAR(25) NOT NULL;
4)如何使用ALTER TABLE删除约束呢?其实只要把NOT NULL改成NULL即可
ALTER TABLE t_decade_test_not_null
MODIFY email VARCHAR(25) NULL;
2. UNIQUE 唯一性约束:确保某一列/某一个字段的值不会重复
注意点:
MySQL会给唯一约束的列上默认建一个唯一索引
一个表中可以设置多个唯一性约束
唯一性约束可以针对某一个字段,也可以针对某几个字段组合起来的值
唯一性约束允许字段为空。如果两条数据,该字段都赋值null,不会受到唯一性约束的限制
创建唯一性约束的时候,如果不给约束命名,那就默认唯一性约束的名字和字段名相同
1)如何在建表时,给字段添加唯一性约束
CREATE TABLE t_decade_test_unique(
id INT UNIQUE #这就是列级约束,
last_name VARVHAR(20),
email VARCHAR(25),
salary DECIMAL(10,2),
# 添加表级约束,一般约束的命名格式为:作用_表名_字段
CONSTRAINT uk_t_decade_test_unique_email UNIQUE(email)
);
2)如何使用ALTER TABLE来添加约束
方式一:
alter table 表名 add UNIQUE(字段名称)
alter table t_decade_test_unique add UNIQUE(lastname);
# 如果要给约束取名,还是使用constraint
alter table t_decade_test_unique add constraint uk_t_decade_test_unique_lastname UNIQUE(lastname,email);
方式二:
alter table 表名 modify 字段名 字段类型 UNIQUE
alter table t_decade_test_unique MODIFY last_name VARVHAR(20) UNIQUE;
3)什么是复合的唯一性约束
可以理解为,我们对多个字段进行组合
要求两条数据中,这几个字段的值不能完全相同,必须有一个或者几个字段的值不一样
CREATE TABLE t_unique_user(
id INT,
user_name VARCHAR(20),
user_pwd VARCHAR(15),
constraint uk_t_unique_user_nameAndPwd UNIQUE(user_name,user_pwd);
);
这样一来,这个表中的任意两条数据,name和pwd字段就不能完全相同
4)删除唯一性约束
创建唯一性约束的字段会自动创建一个唯一索引,所以我们只能通过删除唯一索引的方式来删除该约束
而唯一索引的名和唯一性约束的名称是一样的
如果是单列约束,那默认就和字段名称相同,如果是复合约束,那默认就和()中排在第一位的字段名相同。当然我们也可以使用constraint来自定义约束名
alter table t_unique_user
DROP index 索引名;
我们也可以通过show index from 表名;查看表的索引
3. PRIMARY KEY 主键约束:用来标识表中的一行记录,也就是说,可以通过这个来确定某条数据是独一无二的
特点:主键约束相当于唯一性约束+非空约束
注意点:
- 一个表中只能有一个主键约束,它可以在列级别创建,也可以在表级别创建
- 主键约束对应着表中的一列或者多列(复合主键)
- 如果是多列组合的复合主键约束,那么任何一列都不允许为空,而且组合的值不允许重复
- 主键约束的名总是PRIMARY,它不能像前面的唯一性约束一样自定义名称
- 创建主键约束后,系统会自动在对应的列或者组合字段上创建主键索引(根据主键进行查询的效率更高),如果删除了主键约束,对应的主键索引也会被删除
- 不要修改主键字段的值,因为他是数据记录的唯一标识,如果修改了主键的值,就有可能破坏数据的完整性
4. AUTO_INCREMENT 自增列:让某个字段的值自增
特点:
- 一个表只能有一个自增字段
- 当需要产生唯一标识符或者顺序值的时候,可以设置自增长
- 自增长约束的列必须是键列(必须要有主键约束或者唯一性约束),而且自增长约束的列必须是整数类型,在没有给第一条数据的该字段显式赋值情况下,默认从1开始
- 如果我们在插入某条数据时,自增列对应的value填的是0或者null,实际上入表的值会是该字段当前最大值加1,并不会展示为0或者null
5. FOREIGN KEY 外键约束:用来让两张表的数据建立连接,保持数据的一致性和完整性
了解什么是主表/从表或者说什么是父表/子表:
主表(父表):被引用的表,比如上面的部门表
从表(子表):引用别人的表,比如上面的员工表
特点:
- 从表的外键引用/参考的必须是主表的主键列或者是唯一约束的那个字段,这是因为被依赖/被参考的值必须是唯一的
- 创建外键约束时,如果没有自定义名称,那么会自动生成一个外键名,不会像之前介绍的约束一样和列名保持一致了
- 如果在创建表的时候就指定外键约束,那么必须先创建主表,再创建从表
- 删表时,先删从表(或者先删外键约束),再删主表
- 当主表的数据被从表参照时,主表的数据将不被允许删除,如果要删除数据,需要先去从表中删除依赖该记录的数据,然后再删除主表数据
- 在从表中指定外键约束,一个表可以建立多个外键约束
- 从表的外键列和主表中被引用的列不一定要名称相同,但是数据类型必须保持一致
- 创建外键约束时,系统会默认在所在的列上建立普通索引,索引名=列名(列名≠外键约束名)
- 删除外键约束后,必须手动删除对应的索引
创建方式:
1)在create table时指定外键约束
CREATE TABLE t_dept(
dept_id INT PRIMARY KEY AUTO_INCREMENT,
dept_name VARCHAR(20)
);
CREATE TABLE t_emp(
emp_id INT PRIMARY KEY AUTO_INCREMENT,
emp_name VARCHAR(20),
department_id INT,
# 使用表级约束的方式指定外键约束
CONSTRAINT fk_emp_department_id FOREIGN KEY (department_id) REFERENCES t_dept (dept_id)
);
2)演示外键效果
在创建了t_dept和t_emp表之后
如果两张表都是空表,当我们直接执行insert into t_emp values(1,"decade",10);
SQL执行会报错,因为我们从表t_emp依赖的主表t_dept中并没有id为10的记录
所以我们要先执行
insert into t_dept values(10,"技术部");
再执行insert into t_emp values(1,"decade",10);
执行上述插入语句之后
假设我们执行delete from t_dept where id = 10;,语句还是会报错,因为这条数据被从表依赖
同样的,当我们执行update t_dept set id = 20 where dept_name = '技术部';时,语句也会报错
3)建表后如何使用alter table添加外键约束
CREATE TABLE t_dept2(
dept_id INT PRIMARY KEY AUTO_INCREMENT,
dept_name VARCHAR(20)
);
CREATE TABLE t_emp2(
emp_id INT PRIMARY KEY AUTO_INCREMENT,
emp_name VARCHAR(20),
department_id INT
);
ALTER TABLE t_emp2
ADD CONSTRAINT fk_emp2_department_id FOREIGN KEY (department_id) REFERENCES t_dept2 (dept_id);
4)删除外键约束
# 第一步:先查看表中的约束名,删除约束
SELECT * FROM information_schema.TABLE_CONSTRAINTS
WHERE table_name = '表名称';
ALTER TABLE 从表名
DROP FOREIGN KEY 外键约束名称;
# 第二步:查看索引名和删除索引
SHOW INDEX FROM 表名称;
ALTER TABLE 从表名 DROP INDEX 索引名;
6. CHECK 检查约束:检查某个字段的值是否复合要求
建表时添加
CREATE TABLE t_emp(
id iNT PRIMARY KEY AUTO_INCREMENT
last_name VARCHAR(20),
salary DECIMAL(10,2) CHECK(salary>5000)
);
如果你执行insert into t_emp values(1, "彭于晏", 1500);
,语句就会报错
7. DEFAULT默认值约束:给某个字段设置默认值,如果在插入数据时没有给该字段显式赋值,那么就赋值为默认值
1)在创建表时添加约束
CREATE TABLE t_emp(
id iNT PRIMARY KEY AUTO_INCREMENT
last_name VARCHAR(20),
salary DECIMAL(10,2) DEFAULT 3000
);
如果你执行insert into t_emp values(1, "彭于晏");,那么此条数据对应salary那一列的值就是3000
2)使用ALTER TABLE添加约束
CREATE TABLE t_emp(
id iNT PRIMARY KEY AUTO_INCREMENT
last_name VARCHAR(20),
salary DECIMAL(10,2)
);
ALTER TABLE t_emp
MODIFY salary DECIMAL(10,2) DEFAULT 3000;
3)删除约束
ALTER TABLE t_emp
MODIFY salary DECIMAL(10,2);