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

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

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

在 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 <数据表名>;

相关推荐

MySQL进阶五之自动读写分离mysql-proxy

自动读写分离目前,大量现网用户的业务场景中存在读多写少、业务负载无法预测等情况,在有大量读请求的应用场景下,单个实例可能无法承受读取压力,甚至会对业务产生影响。为了实现读取能力的弹性扩展,分担数据库压...

Postgres vs MySQL_vs2022连接mysql数据库

...

3分钟短文 | Laravel SQL筛选两个日期之间的记录,怎么写?

引言今天说一个细分的需求,在模型中,或者使用laravel提供的EloquentORM功能,构造查询语句时,返回位于两个指定的日期之间的条目。应该怎么写?本文通过几个例子,为大家梳理一下。学习时...

一文由浅入深带你完全掌握MySQL的锁机制原理与应用

本文将跟大家聊聊InnoDB的锁。本文比较长,包括一条SQL是如何加锁的,一些加锁规则、如何分析和解决死锁问题等内容,建议耐心读完,肯定对大家有帮助的。为什么需要加锁呢?...

验证Mysql中联合索引的最左匹配原则

后端面试中一定是必问mysql的,在以往的面试中好几个面试官都反馈我Mysql基础不行,今天来着重复习一下自己的弱点知识。在Mysql调优中索引优化又是非常重要的方法,不管公司的大小只要后端项目中用到...

MySQL索引解析(联合索引/最左前缀/覆盖索引/索引下推)

目录1.索引基础...

你会看 MySQL 的执行计划(EXPLAIN)吗?

SQL执行太慢怎么办?我们通常会使用EXPLAIN命令来查看SQL的执行计划,然后根据执行计划找出问题所在并进行优化。用法简介...

MySQL 从入门到精通(四)之索引结构

索引概述索引(index),是帮助MySQL高效获取数据的数据结构(有序),在数据之外,数据库系统还维护者满足特定查询算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构...

mysql总结——面试中最常问到的知识点

mysql作为开源数据库中的榜一大哥,一直是面试官们考察的重中之重。今天,我们来总结一下mysql的知识点,供大家复习参照,看完这些知识点,再加上一些边角细节,基本上能够应付大多mysql相关面试了(...

mysql总结——面试中最常问到的知识点(2)

首先我们回顾一下上篇内容,主要复习了索引,事务,锁,以及SQL优化的工具。本篇文章接着写后面的内容。性能优化索引优化,SQL中索引的相关优化主要有以下几个方面:最好是全匹配。如果是联合索引的话,遵循最...

MySQL基础全知全解!超详细无废话!轻松上手~

本期内容提醒:全篇2300+字,篇幅较长,可搭配饭菜一同“食”用,全篇无废话(除了这句),干货满满,可收藏供后期反复观看。注:MySQL中语法不区分大小写,本篇中...

深入剖析 MySQL 中的锁机制原理_mysql 锁详解

在互联网软件开发领域,MySQL作为一款广泛应用的关系型数据库管理系统,其锁机制在保障数据一致性和实现并发控制方面扮演着举足轻重的角色。对于互联网软件开发人员而言,深入理解MySQL的锁机制原理...

Java 与 MySQL 性能优化:MySQL分区表设计与性能优化全解析

引言在数据库管理领域,随着数据量的不断增长,如何高效地管理和操作数据成为了一个关键问题。MySQL分区表作为一种有效的数据管理技术,能够将大型表划分为多个更小、更易管理的分区,从而提升数据库的性能和可...

MySQL基础篇:DQL数据查询操作_mysql 查

一、基础查询DQL基础查询语法SELECT字段列表FROM表名列表WHERE条件列表GROUPBY分组字段列表HAVING分组后条件列表ORDERBY排序字段列表LIMIT...

MySql:索引的基本使用_mysql索引的使用和原理

一、索引基础概念1.什么是索引?索引是数据库表的特殊数据结构(通常是B+树),用于...