百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT技术 > 正文

【MySQL】七种约束超详解(mysql常用的约束有哪些)

wptr33 2025-03-24 21:22 25 浏览

在 MySQL 中,约束是指对表中数据的一种约束,能够帮助数据库管理员更好地管理数据库,并且能够确保数据库中数据的正确性和有效性。 例如,在数据表中存放年龄的值时,如果存入 200、300 这些无效的值就毫无意义了。因此,使用约束来限定表中的数据范围是很有必要的。

1.主键

主键(PRIMARY KEY)的完整称呼是“主键约束”,是 MySQL 中使用最为频繁的约束。一般情况下,为了便于 DBMS 更快的查找到表中的记录,都会在表中设置一个主键。

主键分为单字段主键和多字段联合主键,本节将分别讲解这两种主键约束的创建、修改和删除。

  • 使用主键应注意以下几点:
  1. 每个表只能定义一个主键。
  2. 主键值必须唯一标识表中的每一行,且不能为 NULL,即表中不可能存在有相同主键值的两行数据。这是唯一性原则。
  3. 一个字段名只能在联合主键字段表中出现一次。
  4. 联合主键不能包含不必要的多余字段。当把联合主键的某一字段删除后,如果剩下的字段构成的主键仍然满足唯一性原则,那么这个联合主键是不正确的。这是最小化原则。

1.1在建表的时候创建主键

在 CREATE TABLE 语句中,通过 PRIMARY KEY关键字来指定主键。

语法如下:

<字段名> <数据类型> PRIMARY KEY [默认值]
CREATE TABLE tb_emp1(
id INT(11) PRIMARY KEY,
name VARCHAR(25),
deptId INT(11),
salary FLOAT
);

1.2在定义一句之后创建主键

语法如下:

[CONSTRAINT <约束名>] PRIMARY KEY [字段名]
CREATE TABLE tb_emp2(
id INT(11),
name VARCHAR(25),
deptId INT(11),
salary FLOAT,
PRIMARY KEY(id)
);

1.3在创建表时设置联合主键

所谓的联合主键,就是这个主键是由一张表中多个字段组成的。 比如,设置学生选课数据表时,使用学生编号做主键还是用课程编号做主键呢?如果用学生编号做主键,那么一个学生就只能选择一门课程。如果用课程编号做主键,那么一门课程只能有一个学生来选。显然,这两种情况都是不符合实际情况的。 实际上设计学生选课表,要限定的是一个学生只能选择同一课程一次。因此,学生编号和课程编号可以放在一起共同作为主键,这也就是联合主键了。

联合主键语法:

PRIMARY KEY [字段1,字段2,…,字段n]
注意:当主键是由多个字段组成时,不能直接在字段名后面声明主键约束。
创建数据表 tb_emp3,假设表中没有主键 id,为了唯一确定一个员工,可以把 name、deptId 联合起来作为主键,
CREATE TABLE tb_emp3(
name VARCHAR(25),
deptId INT(11),
salary FLOAT,
PRIMARY KEY(name,deptId)
);

1.4在修改表时添加主键约束

主键约束不仅可以在创建表的同时创建,也可以在修改表时添加。但是需要注意的是,设置成主键约束的字段中不允许有空值。

语法如下:

ALTER TABLE <数据表名> ADD PRIMARY KEY(<字段名>);
CREATE TABLE tb_emp4(
name VARCHAR(25),
deptId INT(11),
salary FLOAT
);
DESC tb_emp4;
ALTER TABLE tb_emp4 ADD PRIMARY KEY(id);

1.5删除主键

当一个表中不需要主键约束时,就需要从表中将其删除。删除主键约束的方法要比创建主键约束容易的多。

语法如下:

ALTER TABLE <表名> DROP PRIMARY KEY;
ALTER TABLE tb_emp1 DROP PRIMARY KEY;

由于主键约束在一个表中只能有一个,因此不需要指定主键名就可以删除一个表中的主键约束。

1.6主键自增长

在 MySQL 中,当主键定义为自增长后,这个主键的值就不再需要用户输入数据了,而由数据库系统根据定义自动赋值。每增加一条记录,主键会自动以相同的步长进行增长。

通过给字段添加 AUTO_INCREMENT 属性来实现主键自增长。

语法如下:

字段名 数据类型 AUTO_INCREMENT
  • 默认情况下:
  1. AUTO_INCREMENT 的初始值是 1,每新增一条记录,字段值自动加 1。
  2. 一个表中只能有一个字段使用 AUTO_INCREMENT 约束,且该字段必须有唯一索引,以避免序号重复(即为主键或主键的一部分)。
  3. AUTO_INCREMENT 约束的字段必须具备 NOT NULL 属性。
  4. AUTO_INCREMENT 约束的字段只能是整数类型(TINYINT、SMALLINT、INT、BIGINT 等)。
  5. AUTO_INCREMENT 约束字段的最大值受该字段的数据类型约束,如果达到上限,AUTO_INCREMENT 就会失效。
CREATE TABLE tb_student(
id INT(4) PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(25) NOT NULL
);

1.7指定自增字段初始值

如果第一条记录设置了该字段的初始值,那么新增加的记录就从这个初始值开始自增。例如,如果表中插入的第一条记录的 id 值设置为 5,那么再插入记录时,id 值就会从 5 开始往上增加。

CREATE TABLE tb_student2 (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(20) NOT NULL,
PRIMARY KEY(ID)
)AUTO_INCREMENT=100;

1.8MySQL 设置自增长值和步长

SET @@auto_increment_increment=3; #将自增长步长设置为3
SET @@auto_increment_offset=4; #将自增长开始值设置为4
-- 我们先看下设置的自增步长和初始值是否改变了:
SHOW VARIABLES LIKE 'auto_inc%';

2.外检约束

MySQL 外键约束(FOREIGN KEY)是表的一个特殊字段,经常与主键约束一起使用。对于两个具有关联关系的表而言,相关联字段中主键所在的表就是主表(父表),外键所在的表就是从表(子表)。外键用来建立主表与从表的关联关系,为两个表的数据建立连接,约束两个表中数据的一致性和完整性。

  • 定义外键时,需要遵守下列规则:
  1. 主表必须已经存在于数据库中,或者是当前正在创建的表。如果是后一种情况,则主表与从表是同一个表,这样的表称为自参照表,这种结构称为自参照完整性。
  2. 主表必须要有主键。
  3. 主键不能包含空值,但允许在外键中出现空值。也就是说,只要外键的每个非空值出现在指定的主键中,这个外键的内容就是正确的。
  4. 在主表的表名后面指定列名或列名的组合。这个列或列的组合必须是主表的主键或候选键。
  5. 外键中列的数目必须和主表的主键中列的数目相同。
  6. 外键中列的数据类型必须和主表主键中对应列的数据类型相同。

2.1在创建表时设置外键约束

在 CREATE TABLE 语句中,通过 FOREIGN KEY关键字来指定外键。

具体的语法格式如下:

[CONSTRAINT <外键名>] FOREIGN KEY 字段名 [,字段名2,…]
REFERENCES <主表名> 主键列1 [,主键列2,…]

先创建tb_dept表

CREATE TABLE tb_dept(
id INT(11) PRIMARY KEY,
name VARCHAR(22) NOT NULL,
location VARCHAR(50)
);

创建 tb_emp表,并在 tb_emp表上创建外键,tb_emp表的deptId关联tb_dept表的主键

CREATE TABLE tb_emp(
id INT(11) PRIMARY KEY,
name VARCHAR(25),
deptId INT(11),
salary FLOAT,
CONSTRAINT fk_emp_dept FOREIGN KEY(deptId) REFERENCES tb_dept(id)
);

注意:从表的外键关联的必须是主表的主键,且主键和外键的数据类型必须一致。例如,两者都是 INT 类型,或者都是 CHAR 类型。如果不满足这样的要求,在创建从表时,就会出现“ERROR 1005(HY000): Can’t create table”错误。

2.2在修改表时添加外键约束

语法如下:
ALTER TABLE <数据表名> ADD CONSTRAINT <外键名>
FOREIGN KEY(<列名>) REFERENCES <主表名> (<列名>);
ALTER TABLE tb_emp ADD CONSTRAINT fk_tb_dept FOREIGN KEY(deptId) REFERENCES tb_dept(id);

注意:在为已经创建好的数据表添加外键约束时,要确保添加外键约束的列的值全部来源于主键列,并且外键列不能为空。

2.3删除外键约束

语法如下:

ALTER TABLE <表名> DROP FOREIGN KEY <外键约束名>;
ALTER TABLE tb_emp DROP FOREIGN KEY fk_tb_dept;

3.唯一约束

3.1 在创建表时设置唯一约束

MySQL 唯一约束(Unique Key)是指所有记录中字段的值不能重复出现。

语法如下:

<字段名> <数据类型> UNIQUE
CREATE TABLE tb_dept (
id INT(11) PRIMARY KEY,
name VARCHAR(22) UNIQUE,
location VARCHAR(50)
);
3.2 在修改表时创建唯一约束

语法如下:

ALTER TABLE <数据表名> ADD CONSTRAINT <唯一约束名> UNIQUE(<列名>);
ALTER TABLE tb_dept ADD CONSTRAINT unique_name UNIQUE(name);

3.3 删除唯一约束

语法如下:

ALTER TABLE <表名> DROP INDEX <唯一约束名>;
ALTER TABLE tb_dept DROP INDEX unique_name;

4.检查约束

4.1 在创建表时设置检查约束

检查约束使用 CHECK 关键字

语法格式如下:

CHECK <表达式>

“表达式”指的就是 SQL 表达式,用于指定需要检查的限定条件。

CREATE TABLE tb_emp (
id INT(11) PRIMARY KEY,
name VARCHAR(25),
deptId INT(11),
salary FLOAT,
CHECK(salary>0 AND salary<1000)
);

4.2 在修改表时添加检查约束

ALTER TABLE 表名 ADD CONSTRAINT <检查约束名> CHECK(<检查约束>)
ALTER TABLE tb_emp ADD CONSTRAINT check_id CHECK(id>0);

4.3 删除检查约束

ALTER TABLE <数据表名> DROP CONSTRAINT <检查约束名>;
ALTER TABLE tb_emp DROP CONSTRAINT check_id;

5.默认值

5.1 在建表的时候设置默认值

<字段名> <数据类型> DEFAULT <默认值>;
CREATE TABLE tb_dept (
id INT(11) PRIMARY KEY,
name VARCHAR(22),
location VARCHAR(50) DEFAULT 'Beijing'
);

5.2在修改表时添加设置默认值

ALTER TABLE <数据表名>
CHANGE COLUMN <旧字段名> <新字段名> <数据类型> DEFAULT <默认值>;
ALTER TABLE tb_dept CHANGE COLUMN location location VARCHAR(50) DEFAULT 'Shanghai';

5.3 删除默认值约束

ALTER TABLE <数据表名>
CHANGE COLUMN <旧字段名> <新字段名> <数据类型> DEFAULT NULL;
ALTER TABLE tb_dept3 CHANGE COLUMN location location VARCHAR(50) DEFAULT NULL;

6.非空约束

6.1在创建表时设置非空约束

<字段名> <数据类型> NOT NULL;
CREATE TABLE tb_dept (
id INT(11) PRIMARY KEY,
name VARCHAR(22) NOT NULL,
location VARCHAR(50)
);

6.2 在修改表的时候设置非空约束

ALTER TABLE <数据表名> CHANGE COLUMN <旧字段名> <新字段名> <数据类型> NOT NULL;
ALTER TABLE tb_dept CHANGE COLUMN location location VARCHAR(50) NOT NULL;

6.3 删除非空约束

ALTER TABLE <数据表名> CHANGE COLUMN <旧字段名> <新字段名> <数据类型> NULL;
ALTER TABLE tb_dept CHANGE COLUMN location location VARCHAR(50) NULL;

7.查看表的约束

SHOW CREATE TABLE <数据表名>;

相关推荐

oracle数据导入导出_oracle数据导入导出工具

关于oracle的数据导入导出,这个功能的使用场景,一般是换服务环境,把原先的oracle数据导入到另外一台oracle数据库,或者导出备份使用。只不过oracle的导入导出命令不好记忆,稍稍有点复杂...

继续学习Python中的while true/break语句

上次讲到if语句的用法,大家在微信公众号问了小编很多问题,那么小编在这几种解决一下,1.else和elif是子模块,不能单独使用2.一个if语句中可以包括很多个elif语句,但结尾只能有一个else解...

python continue和break的区别_python中break语句和continue语句的区别

python中循环语句经常会使用continue和break,那么这2者的区别是?continue是跳出本次循环,进行下一次循环;break是跳出整个循环;例如:...

简单学Python——关键字6——break和continue

Python退出循环,有break语句和continue语句两种实现方式。break语句和continue语句的区别:break语句作用是终止循环。continue语句作用是跳出本轮循环,继续下一次循...

2-1,0基础学Python之 break退出循环、 continue继续循环 多重循

用for循环或者while循环时,如果要在循环体内直接退出循环,可以使用break语句。比如计算1至100的整数和,我们用while来实现:sum=0x=1whileTrue...

Python 中 break 和 continue 傻傻分不清

大家好啊,我是大田。今天分享一下break和continue在代码中的执行效果是什么,进一步区分出二者的区别。一、continue例1:当小明3岁时不打印年龄,其余年龄正常循环打印。可以看...

python中的流程控制语句:continue、break 和 return使用方法

Python中,continue、break和return是控制流程的关键语句,用于在循环或函数中提前退出或跳过某些操作。它们的用途和区别如下:1.continue(跳过当前循环的剩余部分,进...

L017:continue和break - 教程文案

continue和break在Python中,continue和break是用于控制循环(如for和while)执行流程的关键字,它们的作用如下:1.continue:跳过当前迭代,...

作为前端开发者,你都经历过怎样的面试?

已经裸辞1个月了,最近开始投简历找工作,遇到各种各样的面试,今天分享一下。其实在职的时候也做过面试官,面试官时,感觉自己问的问题很难区分候选人的能力,最好的办法就是看看候选人的github上的代码仓库...

面试被问 const 是否不可变?这样回答才显功底

作为前端开发者,我在学习ES6特性时,总被const的"善变"搞得一头雾水——为什么用const声明的数组还能push元素?为什么基本类型赋值就会报错?直到翻遍MDN文档、对着内存图反...

2023金九银十必看前端面试题!2w字精品!

导文2023金九银十必看前端面试题!金九银十黄金期来了想要跳槽的小伙伴快来看啊CSS1.请解释CSS的盒模型是什么,并描述其组成部分。答案:CSS的盒模型是用于布局和定位元素的概念。它由内容区域...

前端面试总结_前端面试题整理

记得当时大二的时候,看到实验室的学长学姐忙于各种春招,有些收获了大厂offer,有些还在苦苦面试,其实那时候的心里还蛮忐忑的,不知道自己大三的时候会是什么样的一个水平,所以从19年的寒假放完,大二下学...

由浅入深,66条JavaScript面试知识点(七)

作者:JakeZhang转发链接:https://juejin.im/post/5ef8377f6fb9a07e693a6061目录由浅入深,66条JavaScript面试知识点(一)由浅入深,66...

2024前端面试真题之—VUE篇_前端面试题vue2020及答案

添加图片注释,不超过140字(可选)1.vue的生命周期有哪些及每个生命周期做了什么?beforeCreate是newVue()之后触发的第一个钩子,在当前阶段data、methods、com...

今年最常见的前端面试题,你会做几道?

在面试或招聘前端开发人员时,期望、现实和需求之间总是存在着巨大差距。面试其实是一个交流想法的地方,挑战人们的思考方式,并客观地分析给定的问题。可以通过面试了解人们如何做出决策,了解一个人对技术和解决问...