【MySQL】约束

news2025/9/23 3:10:09

文章目录

  • 1. 约束
  • 2. 非空约束 NOT NULL
  • 3. 唯一性约束 UNIQUE
  • 4. 主键约束 PRIMARY KEY
  • 5. 自增约束 AUTO_INCREMENT
  • 6. 外键约束FOREIGN KEY
  • 7. 默认值约束 DEFAULT
  • 8. 小结

1. 约束

  1. 为了保证数据的完整性,SQL规范以约束的方式对表数据进行额外的条件限制。从以下四个方面考虑:
  • 实体完整性(Entity Integrity) :例如,同一个表中,不能存在两条完全相同无法区分的记录。
  • 域完整性(Domain Integrity) :例如:年龄范围0-120,性别范围“男/女”。
  • 引用完整性(Referential Integrity) :例如:员工所在部门,在部门表中要能找到这个部门。
  • 用户自定义完整性(User-defined Integrity) :例如:用户名唯一、密码不能为空等,本部门经理的工资不得高于本部门职工的平均工资的5倍。
  1. 根据约束起的作用,可分为:
  • NOT NULL 非空约束,规定某个字段不能为空
  • UNIQUE 唯一约束,规定某个字段在整个表中是唯一的
  • PRIMARY KEY 主键(非空且唯一)约束
  • FOREIGN KEY 外键约束
  • DEFAULT 默认值约束
  • 列级约束和表级约束区别:表级约束多了 CONSTRAINT constraint_name
  1. 基本语句:
  • 在创建表时规定约束:CREATE TABLE…
  • 在表创建后添加约束:ALTER TABLE …
  • 查看某个表已有的约束:
    SELECT * FROM information_schema.table_constraints WHERE table_name = ‘table name’;
  • 查看表索引:SHOW INDEX FROM tablename;

2. 非空约束 NOT NULL

  • 限定某个字段/某列的值不允许为空:NOT NULL。
  • 所有的类型的值都可以是NULL
  • 非空约束只能出现在表对象的列上,只能某个列单独限定非空,不能组合非空
  • 一个表可以有很多列都分别限定了非空
  • 空字符串’'不等于NULL,0也不等于NULL
  • 修改ALTER TABLE 字段约束时,如果要保留字段原有的非空约束,在加其他约束时,需要保留NOT NULL,否则非空约束就会被删除。
# 建表时非空约束
CREATE TABLE emp (
	id INT(10) NOT NULL,
	name VARCHAR(20) NOT NULL,
	sex CHAR NULL
);

在这里插入图片描述

# 建表后非空约束
ALTER TABLE emp 
MODIFY sex VARCHAR(20) NOT NULL;

ALTER TABLE emp 
MODIFY name VARCHAR(15) DEFAULT 'abc' NOT NULL;

# 删除非空约束
ALTER TABLE emp 
MODIFY sex VARCHAR(20) NULL;

3. 唯一性约束 UNIQUE

  • 用来限制某个字段/某列的值不能重复:UNIQUE。
  • UNIQUE KEY 等同于 UNIQUE.
  • 单列用法UNIQUE(),组合用法UNIQUE(item, item2, …)。
  • 同一个表可以有多个唯一约束。
  • 唯一约束可以是某一个列的值唯一,也可以多个列组合的值唯一。
  • 唯一性约束允许列值为空。
  • 如果创建唯一约束时未指定名称,如果是单列,就默认和列名相同;如果是组合列,那么默认和()中排在第一个的列名相同。也可以自定义唯一性约束名。
  • MySQL会给唯一约束的列上默认自动创建一个唯一索引。
  • 删除唯一约束只能通过删除唯一索引的方式删除。
  • 删除时需要指定唯一索引名,唯一索引名就和唯一约束名一样。
# 建表时唯一性约束
CREATE TABLE stu3 (
	sid INT NOT NULL UNIQUE KEY,
	cardid VARCHAR(20) UNIQUE,
	phone INT UNIQUE KEY,
	name VARCHAR(25),
	password VARCHAR(16),
	address VARCHAR(18),
	age INT,
	childs INT,
	UNIQUE KEY(name, password),
	UNIQUE(address, age),
	CONSTRAINT stu3_constraint UNIQUE(sid, cardid)
);
-- UNIQUE KEY 等同于 UNIQUE
-- NOT NULL && UNIQUE 等同于 PRIMARY KEY
-- CONSTRAINT ... UNIQUE() 表级约束

CREATE TABLE stu2 (
	sid INT NOT NULL,
	name VARCHAR(25) DEFAULT 'abc',
	password VARCHAR(16),
	cardid VARCHAR(20) UNIQUE,
	phone INT UNIQUE KEY,
	address VARCHAR(18),
	age INT,
	childs INT,
	CONSTRAINT stu2_name_pwd UNIQUE(name, password) 
);

DESC stu2;
DROP TABLE stu2;

在这里插入图片描述

# 建表后唯一性约束
ALTER TABLE 表名称 ADD UNIQUE KEY (字段列表);

# sid 既非NULL又唯一时会变为主键PrimaryKey
ALTER TABLE stu2 ADD UNIQUE KEY(sid); 
-- sid key : PRI

ALTER TABLE stu2 ADD UNIQUE KEY(address, age, childs);
ALTER TABLE stu2 ADD CONSTRAINT stu2_age_childs UNIQUE(address, age, childs);

# 也可以直接改变字段属性
ALTER TABLE stu2 MODIFY sid INT NOT NULL UNIQUE;
-- sid key: PRI 
ALTER TABLE stu2 MODIFY sid INT UNIQUE;
-- sid key: UNI

SELECT * FROM information_schema.TABLE_CONSTRAINTS
WHERE table_name = 'stu2';

# 删除唯一性约束
ALTER TABLE stu2 DROP INDEX stu2_age_childs;

4. 主键约束 PRIMARY KEY

  • 用来唯一标识表中的一行记录:PRIMARY 。
  • 主键约束相当于唯一约束+非空约束的组合,主键约束列不允许重复,也不允许出现空值。
  • 一个表最多只能有一个主键约束,建立主键约束可以在列级别创建,也可以在表级别上创建。
  • 主键约束对应着表中的一列或者多列(复合主键)
  • 如果是多列组合的复合主键约束,那么这些列都不允许为空值,并且组合的值不允许重复。
  • MySQL的主键名总是PRIMARY,就算自己命名了主键约束名也没用。
  • 当创建主键约束时,系统默认会在所在的列或列组合上建立对应的主键索引(能够根据主键查询的,就根据主键查询,效率更高)。
  • 如果删除主键约束了,主键约束对应的索引就自动删除了。
  • 不要修改主键字段的值。因为主键是数据记录的唯一标识,如果修改了主键的值,就有可能会破坏数据的完整性。
  • 删除主键约束,不需要指定主键名,因为一个表只有一个主键,删除主键约束后,非空还存在。
# 列级约束PRIMARY KEY
CREATE TABLE temp1(
	id INT PRIMARY KEY,
	name VARCHAR(20)
);
# 列级约束组合
CREATE TABLE temp2 (
	id INT NOT NULL AUTO_INCREMENT,
	name VARCHAR(20),
	PRIMARY KEY(id, name)
);
# 表级约束
CREATE TABLE temp2 (
	id INT NOT NULL AUTO_INCREMENT,
	name VARCHAR(20),
	CONSTRAINT temp2_id_pk PRIMARY KEY(id)
);
# 表级约束组合
CREATE TABLE temp3 (
	id INT NOT NULL AUTO_INCREMENT,
	name VARCHAR(20),
	CONSTRAINT temp3_id_pk PRIMARY KEY(id, name)
);
-- id 和 name 均为非NULL且PRI

# 建表后 PRIMARY KEY
ALTER TABLE temp ADD PRIMARY KEY(id);
ALTER TABLE temp ADD PRIMARY KEY(id, name);

# 删除主键约束,不需要指定主键名
ALTER TABLE temp DROP PRIMARY KEY;

5. 自增约束 AUTO_INCREMENT

  • 某个字段的值自增:AUTO_INCREMENT。
  • 一个表最多只能有一个自增长列
  • 当需要产生唯一标识符或顺序值时,可设置自增长
  • 自增长列约束的列必须是键列(主键列PRIMARY KEY 或 唯一键列UNIQUE KEY)
  • 自增约束的列的数据类型必须是整数类型
  • 如果自增列指定了 0 和 null,会在当前最大值的基础上自增;如果自增列手动指定了具体值,直接赋值为具体值。
  • 自增显示在Extra项
create table 表名称(
	字段名 数据类型 primary key auto_increment,
	字段名 数据类型 unique key not null,
	字段名 数据类型 unique key,
	字段名 数据类型 not null default 默认值,
);
create table 表名称(
	字段名 数据类型 default 默认值,
	字段名 数据类型 unique key auto_increment,
	字段名 数据类型 not null default 默认值,,
	primary key(字段名)
);

-- 不建议只写KEY,虽然默认key = primary key
CREATE TABLE auto(
	id INT KEY AUTO_INCREMENT,
	name VARCHAR(20)
);

CREATE TABLE auto2(
	id INT PRIMARY KEY AUTO_INCREMENT,
	name VARCHAR(20)
);

CREATE TABLE auto3(
	id INT UNIQUE KEY AUTO_INCREMENT,
	name VARCHAR(20) PRIMARY KEY
);

# 建表后增加自增
ALTER TABLE auto3 
MODIFY id INT AUTO_INCREMENT;

# 去掉auto_increment相当于删除
ALTER TABLE auto3 
MODIFY id INT;

6. 外键约束FOREIGN KEY

  • 限定某个表的某个字段的引用完整性:FOREIGN KEY。 比如:员工表的员工所在部门的选择,必须在部门表能找到对应的部分。
  • 主表(父表):被引用的表,被参考的表。从表(子表):引用别人的表,参考别人的表。例如:学生表、课程表、选课表:选课表的学生和课程要分别参考学生表和课程表,学生表和课程表是主表,选课表是从表。
  • 从表的外键列,必须参考主表的主键或唯一约束的列。因为被依赖/被参考的值必须是唯一的。
  • 在创建外键约束时,可以指定外键约束名。如果不给外键约束命名,默认名不是列名,而是自动产生一个外键名(例如student_ibfk_1)。
  • 创建表时就指定外键约束的话,先创建主表,再创建从表
  • 删表时,先删从表(或先删除外键约束),再删除主表
  • 当主表的记录被从表参照时,主表的记录将不允许删除,如果要删除数据,需要先删除从表中依赖该记录的数据,然后才可以删除主表的数据
  • 在从表中指定外键约束,并且一个表可以建立多个外键约束
  • 从表的外键列与主表被参照的列名字可以不相同,但是数据类型必须一样,逻辑意义一致。如果类型不一样,创建子表时,就会出现错误“ERROR 1005 (HY000): Can’t createtable’database.tablename’(errno: 150)”。
  • 当创建外键约束时,系统默认会在所在的列上建立对应的普通索引。但是索引名是外键的约束名。(根据外键查询效率很高)
  • 删除外键约束后,必须手动删除对应的索引。
  • 两个表之间有关系,但不一定必须要外键约束。
  • 外键约束需要消耗系统资源,对于大并发的 SQL 操作,可能会因为外键约束的系统开销而变得非常慢。建议通过应用层面完成检查数据一致性的逻辑。
  • 阿里开发规范:不得使用外键与级联,一切外键概念必须在应用层解决。外键与级联更新适用于单机低并发,不适合分布式、高并发集群;级联更新是强阻塞,存在数据库更新风暴的风险;外键影响数据库的插入速度。
create table 主表名称(
	字段1 数据类型 primary key,
	字段2 数据类型
);
create table 从表名称(
	字段1 数据类型 primary key,
	字段2 数据类型,
	[CONSTRAINT <外键约束名称>] FOREIGN KEY(从表的某个字段) references 主表名(被参考字段)
);


CREATE TABLE depx(
	did INT PRIMARY KEY,
	dname VARCHAR(20)
);
CREATE TABLE empx(
	eid INT PRIMARY KEY,
	ename VARCHAR(20),
	depxid INT,
	FOREIGN KEY (depxid) REFERENCES depx(did)
);
-- depxid KEY: MUL 

DESC depx;
DESC empx;
  • 建表后添加外键约束
ALTER TABLE 从表名 
ADD [CONSTRAINT 约束名] FOREIGN KEY (从表的字段) REFERENCES 主表名(被引用字段) [on update xx][on delete xx];

ALTER TABLE empx 
ADD FOREIGN KEY (depxid) REFERENCES depx(did); 
  • 删除外键约束
# (1)先查看从表约束名,删除外键约束
SELECT * FROM information_schema.TABLE_CONSTRAINTS
WHERE table_name = 'empx';
# 删除外键
ALTER TABLE empx 
DROP FOREIGN KEY empx_ibfk_1;

#(2)查看索引名和删除索引
SHOW INDEX FROM empx;
# 删除索引
ALTER TABLE empx 
DROP INDEX depxid;

7. 默认值约束 DEFAULT

  • 给某个字段/某列指定默认值,一旦设置默认值,在插入数据时,如果此字段没有显式赋值,则赋值为默认值:DEFAULT。
  • 默认值约束一般不在唯一键和主键列上加。
create table 表名称(
	字段名 数据类型 default 默认值 ,
	字段名 数据类型 not null default 默认值,
	字段名 数据类型 not null default 默认值,
	primary key(字段名),
	unique key(字段名)
);

create table employee(
	eid INT primary key,
	salary DOUBLE(10,2) DEFAULT 2000
	ename varchar(20) not null,
	gender char default '男',
	tel char(11) not null DEFAULT '' #默认是空字符串
);

alter table 表名称 modify 字段名 数据类型 default 默认值;
alter table 表名称 modify 字段名 数据类型 default 默认值 not null;

ALTER TABLE empx 
MODIFY eid INT DEFAULT 0;

ALTER TABLE empx 
MODIFY ename VARCHAR(20) DEFAULT 'van' NOT NULL;

ALTER TABLE empx 
MODIFY eid INT;

#删除默认值约束,也不保留非空约束
alter table 表名称 modify 字段名 数据类型 ;
#删除默认值约束,保留非空约束
alter table 表名称 modify 字段名 数据类型 not null;

8. 小结

面试1、为什么建表时,加 not null default ‘’ 或 default 0
答:不想让表中出现null值。

面试2、为什么不想要 null 的值
答:(1)不好比较。null是一种特殊值,比较时只能用专门的is null 和 is not null来比较。碰到运算符,通常返回null。
(2)效率不高。影响提高索引效果。因此,我们往往在建表时 not null default ‘’ 或 default 0

面试3、带AUTO_INCREMENT约束的字段值是从1开始的吗? 在MySQL中,默认AUTO_INCREMENT的初始值是1,每新增一条记录,字段值自动加1。设置自增属性(AUTO_INCREMENT)的时候,还可以指定第一条插入记录的自增字段的值,这样新插入的记录的自增字段值从初始值开始递增,如在表中插入第一条记录,同时指定id值为5,则以后插入的记录的id值就会从6开始往上增加。添加主键约束时,往往需要设置字段自动增加属性。

面试4、并不是每个表都可以任意选择存储引擎? 外键约束(FOREIGN KEY)不能跨引擎使用。
MySQL支持多种存储引擎,每一个表都可以指定一个不同的存储引擎,需要注意的是:外键约束是用来保证数据的参照完整性的,如果表之间需要关联外键,却指定了不同的存储引擎,那么这些表之间是不能创建外键约束的。所以说,存储引擎的选择也不完全是随意的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/394434.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

达人合作加持品牌布局,3.8女神玩转流量策略!

随着迅猛发展的“她经济”&#xff0c;使社区本就作为内容种草的平台&#xff0c;自带“营销基因”。在3.8女神节即将到来之际&#xff0c;如何充分利用平台女性资源优势&#xff0c;借助达人合作等手段&#xff0c;实现迅速引流&#xff0c;来为大家详细解读下。一、小红书节日…

数据的标准化处理

假设各个指标之间的水平相差很大&#xff0c;此时直接使用原始指标进行分析时&#xff0c;数值较大的指标&#xff0c;在评价模型中的绝对作用就会显得较为突出和重要&#xff0c;而数值较小的指标&#xff0c;其作用则可能就会显得微不足道。 因此&#xff0c;为了统一比较的标…

60% 程序员大呼:我要远程办公!

近几年数字化的普及&#xff0c;白领们从挤地铁、打卡、开会、写日报转变成“早上9点视频会议”&#xff0c;企业的办公场所也从写字楼、会议室、工位变成了手机、电脑中的线上会议室&#xff0c;远程办公已经成为一种流行的办公形式。《财富》杂志发现&#xff0c;75%的员工表…

全网火爆,软件测试面试题大全,接口测试题+回答 (18k+的offer)

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 面试测试工程师的时…

UML全解

目录UML结构性图表类图类图中具体类、抽象、接口和包的表示法在UML类图中表示具体类在UML类图中表示抽象类在UML类图中表示接口在UML类图中表示包关系泛化&#xff08;Generalization&#xff09;实现&#xff08;Realization&#xff09;关联&#xff08;Association&#xff…

Pyspark基础入门7_RDD的内核调度

Pyspark 注&#xff1a;大家觉得博客好的话&#xff0c;别忘了点赞收藏呀&#xff0c;本人每周都会更新关于人工智能和大数据相关的内容&#xff0c;内容多为原创&#xff0c;Python Java Scala SQL 代码&#xff0c;CV NLP 推荐系统等&#xff0c;Spark Flink Kafka Hbase Hi…

20230307 LS-DYNA易拉罐变形学习笔记

一、定义材料 定义铝合金材料 在左侧把density拖至alumium处 即可在下方输入密度值 同样的道理,将各向同性弹性拉到材料处,即可定义杨氏模量、泊松比等参数

TDengine | 04 | TDengine3.0.2.6二进制包部署

1 前期准备 1.1 版本 TDengine :3.0.2.6 Linux&#xff1a;centos 7 1.2 机器规划 机器IPhostname192.168.3.21master.bafang.com192.168.3.22node1.bafang.com192.168.3.23node2.bafang.com 1.3 修改这三个节点上的hostname hostnamectl set-hostname master.bafang.com…

HBase常用Shell命令

HBase提供了一个非常方便的命令行交互工具HBase Shell。通过HBase Shell&#xff0c;HBase可以与MySQL命令行一样创建表、索引&#xff0c;也可以增加、删除和修改数据&#xff0c;同时集群的管理、状态查看等也可以通过HBase Shell实现。 一、数据定义语言 数据定义语言&…

Acwing: 一道关于线段树的好题(有助于全面理解线段树)

题目链接&#x1f517;&#xff1a;2643. 序列操作 - AcWing题库 前驱知识&#xff1a;需要理解线段树的结构和程序基本框架、以及懒标记的操作。 题目描述 题目分析 对区间在线进行修改和查询&#xff0c;一般就是用线段树来解决&#xff0c;观察到题目一共有五个操作&…

查看python第三方库的依赖pkgs

课题组的服务器不给连外网&#xff0c;安装python第三方库就只能手动离线安装。但是python第三方库可能会迭代依赖&#xff0c;单纯的pip show [pkg]是看不出来的…… 参考链接&#xff1a;查看python第三方库的依赖 https://blog.csdn.net/qq_38316655/article/details/127943…

【多层交叉transformer:高光谱和多光谱图像融合】

MCT-Net: Multi-hierarchical cross transformer for hyperspectral and multispectral image fusion &#xff08;MCT-Net&#xff1a;用于高光谱和多光谱图像融合的多层交叉transformer&#xff09; 考虑到光学成像的局限性&#xff0c;图像采集设备通常在空间信息和光谱信…

04-SQL基础(表管理,约束,多表连接,子查询)

本文章主要内容 1、表的管理&#xff1a;创建表&#xff0c;修改表结构&#xff0c;删除字段&#xff0c;修改字段&#xff0c;添加字段&#xff0c;删除表&#xff0c;添加表约束&#xff1b; 2、数据管理&#xff1a;新增记录&#xff0c;修改记录&#xff0c;删除记录&…

分享10个不错的C语言开源项目

今天跟大家分享10个重量级的C语言开源项目&#xff0c;C语言确实经得住考验&#xff1a; Redis&#xff1a;Redis是一个开源的高性能的键值对数据库。它以C语言编写&#xff0c;具有极高的性能和可靠性。 Nginx&#xff1a;Nginx是一个高性能的HTTP和反向代理服务器&#xff0…

KPN对任意形状文本检测

文章目录一、研究背景二、方法流程1. 特征提取2. 核建议3. 实例无关特征图4. 轮廓生成5. 其余部分内容三、不足一、研究背景 相比起基于 FCN 网络的文本边缘检测网络&#xff0c;KPN网络可以更好地处理文本之间的间隔。 二、方法流程 1. 特征提取 FCN 和 FPN FCN(全卷积神经…

第十四届蓝桥杯第三期模拟赛原题与详解

​​​​​​​ 文章目录 一、填空题 1、1 找最小全字母十六进制数 1、1、1 题目描述 1、1、2 题解关键思路与解答 1、2 给列命名 1、2、1 题目描述 1、2、2 题解关键思路与解答 1、3 日期相等 1、3、1 题目描述 1、3、2 题解关键思路与解答 1、4 乘积方案数 1、4、1 题目描…

在IC行业,什么样的人才能拿到高薪资offer?

最近几年国家大战略发展半导体产业&#xff0c;薪资也水涨船高&#xff0c;IC设计类岗位应届生薪水甚至已经到30W的级别&#xff0c;越来越多的人想要从事IC行业。 在IC行业&#xff0c;什么样的人才能拿到高薪资offer&#xff1f;来听听资深工程师怎么说&#xff1f; 我参加…

【网络篇】----- 传输层协议 之 UDP(协议格式,协议特性和编程影响三方面详细分析)

文章目录 前言1、UDP协议2、协议格式 2.1、协议格式模型2.2、字段分析3.协议特性4.编程影响总结前言 1、UDP协议 UDP协议&#xff0c;又名数据报传输协议&#xff0c;是传输层协议之一&#xff01;&#xff01;&#xff01; 在TCP/IP五层模型中&#xff0c;在传输层中&#xff…

MATLAB | 如何绘制github同款日历热力图

应粉丝要求&#xff0c;出一个类似于github热图的日历热力图&#xff0c;大概长这样&#xff1a; 依旧工具函数放在文末&#xff0c;如有bug请反馈并去gitee下载更新版。 使用教程 使用方式有以下几种会慢慢讲到&#xff1a; heatmapDT(Year,T,V)heatmapDT(Year,T,V,MonLim)h…

数据结构|链表

概念&#xff1a;链表是一种物理存储结构上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。单链表的形式就像一条铁链环环相扣它与顺序表最大的不同是&#xff0c;单链表的数据存储是在不连续的空间&#xff0c;存储的数据里面含有…