MySQL数据库基础 === 约束
目录
TOC
约束
在关系型数据库中,约束用于限制表中的数据,确保数据的完整性、一致性和准确性。通过使用各种约束条件,开发者可以确保数据符合特定规则,例如唯一性、非空、合理的值范围等。约束不仅能提高数据库的性能,还能在数据操作时自动进行验证,减少人为错误。
分类:
约束 | 描述 | 关键字 |
---|---|---|
非空约束 | 限制该字段的数据不能为null | NOT NULL |
唯一约束 | 保证该字段的所有数据都是唯一、不重复的 | UNIQUE |
主键约束 | 主键是一行数据的唯一标识,要求非空且唯一 | PRIMARY KEY |
默认约束 | 保存数据时,如果未指定该字段的值,则采用默认值 | DEFAULT |
检查约束(8.0.1版本后) | 保证字段值满足某一个条件 | CHECK |
外键约束 | 用来让两张图的数据之间建立连接,保证数据的一致性和完整性 | FOREIGN KEY |
约束是作用于表中字段上的,可以再创建表/修改表的时候添加约束。
常用约束
约束条件 | 关键字 |
---|---|
主键 | PRIMARY KEY |
自动增长 | AUTO_INCREMENT |
不为空 | NOT NULL |
唯一 | UNIQUE |
逻辑条件 | CHECK |
默认值 | DEFAULT |
sql
CREATE TABLE user(
id INT PRIMARY KEY AUTO_INCREMENT COMMENT "主键",
name VARCHAR ( 10 ) NOT NULL UNIQUE COMMENT "年龄",
age INT CHECK ( age > 0 AND age < 120 ) COMMENT "年龄",
status CHAR( 1 ) DEFAULT "1" COMMENT "状态",
gender CHAR( 1 ) COMMENT "性别"
) COMMENT "用户表"
-- 插入数据
INSERT INTO user(name,age,status,gender) VALUES ("tom1",19,"1","男"),("tom2",25,"0","男")
-- 不能为null
INSERT INTO user(name,age,status,gender) VALUES (NULL,19,"1","男")
-- 不能重复
INSERT INTO user(name,age,status,gender) VALUES ("tom1",19,"1","男")
-- 插入数据
INSERT INTO user(name,age,status,gender) VALUES ("tom3",19,"1","男")
-- 检查约束
INSERT INTO user(name,age,status,gender) VALUES ("tom3",121,"1","男")
-- 默认约束
INSERT INTO user(name,age,gender) VALUES ("tom4",88,"男")
外键约束
添加外键:
sql
CREATE TABLE 表名(
字段名 字段类型,
...
[CONSTRAINT] [外键名称] FOREIGN KEY(外键字段名) REFERENCES 主表(主表列名)
);
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名) REFERENCES 主表(主表列名);
删除外键:
ALTER TABLE 表名 DROP FOREIGN KEY 外键名;
cobol
CREATE TABLE dept(
id INT PRIMARY KEY AUTO_INCREMENT COMMENT "主键",
name VARCHAR ( 50 ) NOT NULL COMMENT "年龄"
) COMMENT "部门表"
-- 插入数据
INSERT INTO dept(name) VALUES ("研发部"),("市场部"),("财务部"),("销售部"),("总裁办")
CREATE TABLE emp (
id INT AUTO_INCREMENT COMMENT 'ID' PRIMARY KEY,
name VARCHAR ( 50 ) NOT NULL COMMENT '姓名',
age INT COMMENT '年龄',
job VARCHAR ( 20 ) COMMENT '职位',
salary INT COMMENT '薪资',
entrydate DATE COMMENT '入职时间',
managerid INT COMMENT '直属领导ID',
dept_id INT COMMENT '部门ID'
) COMMENT '员工表';
-- 添加数据
INSERT INTO emp (name, age, job, salary, entrydate, managerid, dept_id) VALUES
('金庸', 66, '总裁', 20000, '2000-01-01', NULL, 5),
('张无忌', 20, '项目经理', 12500, '2005-12-05', 1, 1),
('杨逍', 33, '开发', 8400, '2000-11-03', 2, 1),
('韦一笑', 48, '开发', 11000, '2002-02-05', 2, 1),
('常遇春', 43, '开发', 10500, '2004-09-07', 3, 1),
('小昭', 19, '程序员鼓励师', 6600, '2004-10-12', 2, 1);
-- 添加外健
ALTER TABLE emp ADD CONSTRAINT fk_emp_dept_id FOREIGN KEY (dept_id) REFERENCES dept(id)
-- 删除外健
ALTER TABLE emp DROP FOREIGN key fk_emp_dept_id
删除/更新行为
行为 | 说明 |
---|---|
NO ACTION | 当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新(与RESTRICT一致) |
RESTRICT | 当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新(与NO ACTION一致) |
CASCADE | 当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则也删除/更新外键在子表中的记录 |
SET NULL | 当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则设置子表中该外键值为null(要求该外键允许为null) |
SET DEFAULT | 父表有变更时,子表将外键设为一个默认值(Innodb不支持) |
更改删除/更新行为:
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段) REFERENCES 主表名(主表字段名) ON UPDATE 行为 ON DELETE 行为;
sql
-- 更新行为
ALTER TABLE emp ADD CONSTRAINT fk_emp_dept_id FOREIGN KEY (dept_id) REFERENCES dept(id) ON UPDATE CASCADE ON DELETE CASCADE
ALTER TABLE emp ADD CONSTRAINT fk_emp_dept_id FOREIGN KEY (dept_id) REFERENCES dept(id) ON UPDATE SET NULL ON DELETE SET NULL
总结
1. 约束类型总结
- 非空约束(NOT NULL) :保证该字段不能为
NULL
,对一些必须存在的字段非常重要,比如用户名
、ID
等。 - 唯一约束(UNIQUE) :保证字段的值在表中唯一,避免重复。通常用于保证邮箱、电话号码等数据的唯一性。
- 主键约束(PRIMARY KEY) :主键是表中唯一标识每一行记录的字段或字段组合。它不仅要求字段值唯一,而且不能为空。
- 外键约束(FOREIGN KEY) :用于创建表与表之间的关系,确保数据的关联性和一致性。外键约束确保主表的更新或删除操作不会导致子表数据失效。
- 默认值约束(DEFAULT) :当插入数据时,如果某字段没有明确指定值,则使用默认值。适用于需要预设值的字段。
- 检查约束(CHECK) :限制字段的值范围或条件,例如限制年龄字段的取值范围。
2. 外键约束的进阶应用
外键约束不仅用于数据表之间的关系,还能通过设置删除或更新行为(如 CASCADE
、 SET NULL
等)来进一步控制数据的一致性。通过设定外键约束的删除和更新行为,可以控制父表数据变更时,子表如何响应。常见的行为包括:
- CASCADE :当父表数据被删除或更新时,子表中相关的外键数据也会自动删除或更新。
- SET NULL :当父表数据被删除或更新时,子表中相关的外键数据会设置为
NULL
。 - SET DEFAULT :当父表数据变更时,子表中的外键字段会被设置为默认值
NO ACTION
表示如果父表中的记录被删除或更新,数据库将检查子表中的外键是否依赖于这些记录。如果有依赖,则不执行父表的删除或更新操作,RESTRICT
的行为也是类似的,当父表记录被删除或更新时,如果有子表记录依赖于该父表记录,操作会被拒绝。
3.NO ACTION 与 RESTRICT 的区别
NO ACTION
和 RESTRICT
是外键约束中用于指定删除或更新父表记录时子表如何响应的两种行为。尽管它们看起来类似,但它们的行为在数据库引擎中有一些细微的差别。
-
NO ACTION :
NO ACTION
表示如果父表中的记录被删除或更新,数据库将检查子表中的外键是否依赖于这些记录。如果有依赖,则不执行父表的删除或更新操作,具体执行行为取决于数据库的实现。 一般来说,NO ACTION
的行为与RESTRICT
相同 ,即会阻止父表记录的删除或更新。如果子表存在依赖外键的数据,父表的记录不会被删除或更新。 -
RESTRICT :
RESTRICT
的行为也是类似的,当父表记录被删除或更新时,如果有子表记录依赖于该父表记录,操作会被拒绝。RESTRICT
和NO ACTION
都会在父表记录存在外键引用时阻止删除或更新 ,但RESTRICT
是在删除或更新操作开始之前立即进行检查的,而NO ACTION
则是在操作被提交之前才进行检查,因此它们在某些数据库实现中可能有所不同。具体行为取决于数据库系统的实现。
总结: 在多数数据库系统中, NO ACTION
和 RESTRICT
的行为是相同的,都是阻止删除或更新父表记录,如果子表中存在相关外键数据。
4. SET DEFAULT 约束的使用与支持
关于 SET DEFAULT
行为,这确实有些误导,感谢你的提醒。让我们澄清一下:
- SET DEFAULT :
当父表记录被删除或更新时,子表中的外键字段会被设置为某个预设的 默认值 。然而,值得注意的是, 并不是所有的数据库引擎都支持SET DEFAULT
。在一些数据库(例如 MySQL 的 InnoDB 存储引擎)中,SET DEFAULT
并不被支持。实际上, InnoDB 不支持SET DEFAULT
行为 ,这也是常见的数据库实现中的一个限制。其他如 PostgreSQL 和 SQL Server 则通常支持这个行为。
因此, SET DEFAULT
并不是普遍可用的功能 ,如果你在MySQL等数据库中使用它,可能会遇到错误。