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

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

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

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

相关推荐

redis的八种使用场景

前言:redis是我们工作开发中,经常要打交道的,下面对redis的使用场景做总结介绍也是对redis举报的功能做梳理。缓存Redis最常见的用途是作为缓存,用于加速应用程序的响应速度。...

基于Redis的3种分布式ID生成策略

在分布式系统设计中,全局唯一ID是一个基础而关键的组件。随着业务规模扩大和系统架构向微服务演进,传统的单机自增ID已无法满足需求。高并发、高可用的分布式ID生成方案成为构建可靠分布式系统的必要条件。R...

基于OpenWrt系统路由器的模式切换与网页设计

摘要:目前商用WiFi路由器已应用到多个领域,商家通过给用户提供一个稳定免费WiFi热点达到吸引客户、提升服务的目标。传统路由器自带的Luci界面提供了工厂模式的Web界面,用户可通过该界面配置路...

这篇文章教你看明白 nginx-ingress 控制器

主机nginx一般nginx做主机反向代理(网关)有以下配置...

如何用redis实现注册中心

一句话总结使用Redis实现注册中心:服务注册...

爱可可老师24小时热门分享(2020.5.10)

No1.看自己以前写的代码是种什么体验?No2.DooM-chip!国外网友SylvainLefebvre自制的无CPU、无操作码、无指令计数器...No3.我认为CS学位可以更好,如...

Apportable:拯救程序员,IOS一秒变安卓

摘要:还在为了跨平台使用cocos2d-x吗,拯救objc程序员的奇葩来了,ApportableSDK:FreeAndroidsupportforcocos2d-iPhone。App...

JAVA实现超买超卖方案汇总,那个最适合你,一篇文章彻底讲透

以下是几种Java实现超买超卖问题的核心解决方案及代码示例,针对高并发场景下的库存扣减问题:方案一:Redis原子操作+Lua脚本(推荐)//使用Redis+Lua保证原子性publicbo...

3月26日更新 快速施法自动施法可独立设置

2016年3月26日DOTA2有一个79.6MB的更新主要是针对自动施法和快速施法的调整本来内容不多不少朋友都有自动施法和快速施法的困扰英文更新日志一些视觉BUG修复就不翻译了主要翻译自动施...

Redis 是如何提供服务的

在刚刚接触Redis的时候,最想要知道的是一个’setnameJhon’命令到达Redis服务器的时候,它是如何返回’OK’的?里面命令处理的流程如何,具体细节怎么样?你一定有问过自己...

lua _G、_VERSION使用

到这里我们已经把lua基础库中的函数介绍完了,除了函数外基础库中还有两个常量,一个是_G,另一个是_VERSION。_G是基础库本身,指向自己,这个变量很有意思,可以无限引用自己,最后得到的还是自己,...

China&#39;s top diplomat to chair third China-Pacific Island countries foreign ministers&#39; meeting

BEIJING,May21(Xinhua)--ChineseForeignMinisterWangYi,alsoamemberofthePoliticalBureau...

移动工作交流工具Lua推出Insights数据分析产品

Lua是一个适用于各种职业人士的移动交流平台,它在今天推出了一项叫做Insights的全新功能。Insights是一个数据平台,客户可以在上面实时看到员工之间的交流情况,并分析这些情况对公司发展的影响...

Redis 7新武器:用Redis Stack实现向量搜索的极限压测

当传统关系型数据库还在为向量相似度搜索的性能挣扎时,Redis7的RedisStack...

Nginx/OpenResty详解,Nginx Lua编程,重定向与内部子请求

重定向与内部子请求Nginx的rewrite指令不仅可以在Nginx内部的server、location之间进行跳转,还可以进行外部链接的重定向。通过ngx_lua模块的Lua函数除了能实现Nginx...