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

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

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

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

相关推荐

SQL轻松入门(5):窗口函数(sql语录中加窗口函数的执行)

01前言标题中有2个字让我在初次接触窗口函数时,真真切切明白了何谓”高级”?说来也是一番辛酸史!话说,我见识了窗口函数的强大后,便磨拳擦掌的要试验一番,结果在查询中输入语句,返回的结果却是报错,Wh...

28个SQL常用的DeepSeek提示词指令,码住直接套用

自从DeepSeek出现后,极大地提升了大家平时的工作效率,特别是对于一些想从事数据行业的小白,只需要掌握DeepSeek的提问技巧,SQL相关的问题也不再是个门槛。...

从零开始学SQL进阶,数据分析师必备SQL取数技巧,建议收藏

上一节给大家讲到SQL取数的一些基本内容,包含SQL简单查询与高级查询,需要复习相关知识的同学可以跳转至上一节,本节给大家讲解SQL的进阶应用,在实际过程中用途比较多的子查询与窗口函数,下面一起学习。...

SQL_OVER语法(sql语句over什么含义)

OVER的定义OVER用于为行定义一个窗口,它对一组值进行操作,不需要使用GROUPBY子句对数据进行分组,能够在同一行中同时返回基础行的列和聚合列。...

SQL窗口函数知多少?(sql窗口怎么执行)

我们在日常工作中是否经常会遇到需要排名的情况,比如:每个部门按业绩来排名,每人按绩效排名,对部门销售业绩前N名的进行奖励等。面对这类需求,我们就需要使用sql的高级功能——窗口函数。...

如何学习并掌握 SQL 数据库基础:从零散查表到高效数据提取

无论是职场数据分析、产品运营,还是做副业项目,掌握SQL(StructuredQueryLanguage)意味着你能直接从数据库中提取、分析、整合数据,而不再依赖他人拉数,节省大量沟通成本,让你...

SQL窗口函数(sql窗口函数执行顺序)

背景在数据分析中,经常会遇到按某某条件来排名、并找出排名的前几名,用日常SQL的GROUPBY,ORDERBY来实现特别的麻烦,有时甚至实现不了,这个时候SQL窗口函数就能发挥巨大作用了,窗...

sqlserver删除重复数据只保留一条,使用ROW_NUMER()与Partition By

1.使用场景:公司的小程序需要实现一个功能:在原有小程序上,有一个优惠券活动表。存储着活动产品数据,但因为之前没有做约束,导致数据的不唯一,这会使打开产品详情页时,可能会出现随机显示任意活动问题。...

SQL面试经典问题(一)(sql经典面试题及答案)

以下是三个精心挑选的经典SQL面试问题及其详细解决方案,涵盖了数据分析、排序限制和数据清理等常见场景。这些问题旨在考察SQL的核心技能,适用于初学者到高级开发者的面试准备。每个问题均包含清晰的...

SQL:求连续N天的登陆人员之通用解答

前几天发了一个微头条:...

SQL四大排序函数神技(sql中的排序是什么语句)

在日常SQL开发中,排序操作无处不在。当大家需要排序时,是否只会想到ORDERBY?今天,我们就来揭秘SQL中四个强大却常被忽略的排序函数:ROW_NUMBER()、RANK()、DENSE_RAN...

四、mysql窗口函数之row_number()函数的使用

1、窗口函数之row_number()使用背景窗口函数中,排序函数rank(),dense_rank()虽说都是排序函数,但是各有用处,假如像上章节说的“同组同分”两条数据,我们不想“班级名次”出现“...

ROW_NUMBER()函数(rownumber函数与rank区别)

ROW_NUMBER()是SQL中的一个窗口函数(WindowFunction)...

Dify「模板转换」节点终极指南:动态文本生成进阶技巧(附代码)Jinja2引擎解析

这篇文章是关于Dify「模板转换」节点的终极指南,解析了基于Jinja2模板引擎的动态文本生成技巧,涵盖多源文本整合、知识检索结构化、动态API构建及个性化内容生成等六大应用场景,助力开发者高效利用模...

Python 最常用的语句、函数有哪些?

1.#coding=utf-8①代码中有中文字符,最好在代码前面加#coding=utf-8②pycharm不加可能不会报错,但是代码最终是会放到服务器上,放到服务器上的时候运行可能会报错。③...