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

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

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

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

相关推荐

吸顶大法 -- UWP中的工具栏吸顶的实现方式之一

如果一个页面中有很长的列表/内容,很多应用都会在用户向下滚动时隐藏页面的头,给用户留出更多的阅读空间,同时提供一个方便的吸顶工具栏,比如淘宝中的店铺页面。下面是一个比较简单的实现,如果有同学有更好的实...

C# ListView实现在日志中添加图片

ListView想在日志中添加图片,需要配合ImageList控件使用。1、在ListView控件中添加ImageList,视图选择Details2、添加列,有几张图片显示就添加几列ListViewI...

安卓里面优秀的第三方插件gitHub文件

pinned-section-listview这个列表是正确实施其他实现缺失很多功能。这些都是快速滚动页眉和页脚点击固定部分除此之外,它不产生任何不必要的视图、布局等很瘦。xUtils3...

android使用greendao来保存数据

有时我们的数据属于保存到数据库,对于Android应用和IOS应用,我们一般都会使用SQLite这个嵌入式的数据库作为我们保存数据的工具。由于我们直接操作数据库比较麻烦,而且管理起来也非常的麻烦,所以...

常见电脑桌面问题,你知多少

(一)桌面图标无法删除出现一些不认识的图标1.关闭正常运行且需要删除的程序;2.运行杀毒软件进行扫毒处理;3.系统欢迎或者重装系统;4.通过软件自带的卸载程序或者第三方软件(QQ管家、360)进行卸载...

独家|React Native 无限列表的优化与实践

导语本文介绍了在使用ReactNative开发过程中,如何对无限列表组件进行技术选型,如何使用RecyclerListView组件对无限列表进行性能优化,如何解决无限列表与标签页搭配使用时的内存...

深入浅出SlidingMenu

如果想直接查看源码的话可以从我的Github上下载查看:https://github.com/zhanghuijun0/demo-for-android/tree/master/SlidingMenu...

就问你酷不酷 定制自己的动态壁纸

虽然壁纸可以经常更换,但总是看着静态壁纸难免让人乏味。下面就教你如何设置动态壁纸,让你的桌面动起来炫起来。WindowsXP系统虽已退休多年,但在国内仍有大量的忠实用户,那我们就从它说起。其实Win...

安卓的ViewPager概述

一、ViewPager概述1、定义与用途:...

书评 | 9 年码龄工程师读 Android 经典

...

Flet 手机app界面设计,导航和路由,在多个界面之间自由跳转

前面的几篇文章,基本讲清楚了Flet界面设计,但都是“单个界面”。在实际项目中,肯定需要设计“多个界面”啊,多个界面直接怎么导航呢?也就是Flet的路由功能,这是Flet开发的必备技术。依然保...

Android指示器,轮播与循环轮播

AndroidUILibs之CircleIndicator1.说明CircleIndicator,顾名思义,圆形指示器,只一个可以用来做轮播的第三方库。2.配置在模块的build.gradle...

Shopee新手指南:Shopee卖家中心用户界面介绍

1.Shopee各站点前台网页链接:2.Shopee各站点后台网页链接3.ShopeeAPP下载:安卓版下载链接:https://pan.baidu.com/s/1eSp8M1k#list/path...

Django 官方推荐的姿势:类视图

作者:HelloGitHub-追梦人物在开发网站的过程中,有一些视图函数虽然处理的对象不同,但是其大致的代码逻辑是一样的。比如一个博客和一个论坛,通常其首页都是展示一系列的文章列表或者帖子列表。对处理...

ViewPager介绍和使用说明

ViewPager类提供了多界面切换的新效果。新效果有如下特征:...