MySQL表约束详解:非空、唯一、主键与外键实操指南
在数据库设计中,约束是保障数据完整性与有效性的关键机制。本文深入解析MySQL中的非空、唯一、主键和外键四种常用约束,提供具体的Create Table与Insert测试用例,帮助开发者建立规范的数据结构。
认识MySQL数据约束
约束的英文单词为 constraint。在创建数据库表时,通过对特定字段附加约束条件,可以强制限制输入数据的有效范围,从而确保存储在表中的数据符合业务逻辑与实际需求。常见的数据类型约束包括:NOT NULL(非空)、UNIQUE(唯一性)、PRIMARY KEY(主键)、FOREIGN KEY(外键)以及 CHECK(检查约束)。这些约束共同构成了关系型数据库数据质量的防线。
1. 非空约束 (NOT NULL)
非空约束用于确保指定字段的值不能为空。若尝试插入空值且未设置默认值,系统将拒绝该操作并抛出错误。
第1步:定义含非空约束的表结构
目的:创建一个包含非空字段的表。
mysql> create table t_vip( id int, name varchar(255) not null );
第2步:验证非空约束的效果
入口:向表中插入数据。
首先插入一个符合规范的数据行,系统正常接受:
mysql> insert into t_vip(id, name) values(1, 'zhangsan'); mysql> insert into t_vip(id, name) values(2, 'lisi');
接着,尝试仅插入 id 字段而忽略 name 字段,观察报错信息:
mysql> insert into t_vip(id) values(3); ERROR 1364 (HY000): Field 'name' doesn't have a default value
上述报错表明,由于 name 字段被定义为 NOT NULL 且未设定默认值,MySQL 拒绝了隐式或显式的空值插入。
2. 唯一性约束 (UNIQUE)
唯一性约束要求字段内的所有值必须互不相同,但允许存在 NULL 值。这一约束常用于防止重复记录,例如限制用户名或邮箱的唯一性。
1. 单字段唯一性约束
目的:确保某一列的所有数据均不重复。
mysql> create table t_vip( id int, name varchar(255) unique, email varchar(255) );
操作与结果:当尝试插入已存在的值时,系统会触发唯一性冲突错误:
mysql> insert into t_vip(id, name, email) values(3, 'lisi', 'lisi@123.com'); ERROR 1062 (23000): Duplicate entry 'lisi' for key 't_vip.name'
插入成功后,可通过查询确认表内数据状态:
mysql> select * from t_vip;
2. 多字段联合唯一性约束
需求场景:需要实现“姓名+邮箱”组合的唯一性,而非单个字段的全局唯一。
如果简单地分别给两列添加 unique(即每个字段独立唯一),无法满足业务要求。正确的做法是在 CREATE TABLE 语句末尾定义联合索引:
mysql> create table t_vip( id int, name varchar(255), email varchar(255), unique(name, email) );
在此基础上,以下两条数据均合法,因为它们组成的组合值不同:
mysql> insert into t_vip(id, name, email) values(1, 'zhangsan', 'zhangsan@123.com'); mysql> insert into t_vip(id, name, email) values(1, 'zhangsan', 'zhangsan@sina.com');
但若再次插入完全相同的 (name, email) 组合,则会被拦截。
3. 主键约束 (PRIMARY KEY)
主键是表中每一行记录的物理或逻辑标识符,相当于记录的“身份证号”。主键具有两个核心特征:非空(NOT NULL)与唯一(UNIQUE)。
主键的相关术语
- 主键约束:一种强制数据唯一性和非空的约束类型。
- 主键字段:应用了主键约束的列。
- 主键值:主键字段当前存储的具体数值。
单一主键 vs 复合主键
单一主键:仅由一列构成。例如:
mysql> create table t_vip( id int primary key, name varchar(255) );
测试发现,无论是试图插入重复 ID 还是缺失 ID(null),均会引发相应错误:
-- 插入重复主键报错 ERROR 1062 (23000): Duplicate entry '2' for key 't_vip.PRIMARY' -- 插入空主键报错 ERROR 1364 (HY000): Field 'id' doesn't have a default value
复合主键:由多列联合组成主键。此时,只有组合起来才具备唯一性。例如:
mysql> create table t_vip( id int, name varchar(255), email varchar(255), primary key(id, name) );
在此结构中,相同 ID 搭配不同 Name 是允许的:
mysql> insert into t_vip(id, name, email) values(1, 'zhangsan', 'zhansgan@123.com'); mysql> insert into t_vip(id, name, email) values(1, 'lisi', 'lisi@123.com');
自然主键与业务主键的选择
- 自然主键:主键值为无意义的自然数(如自增整数),不与业务逻辑挂钩。实际开发中最为推荐,易于维护。
- 业务主键:使用具有业务含义的字段(如银行卡号、手机号)作为主键。一旦业务属性发生变化(如用户换绑手机号),会导致主键变更及关联数据修改的巨大成本,故较少直接使用。
4. 外键约束 (FOREIGN KEY)
外键用于在不同表之间建立引用关系,确保参照完整性。涉及的概念包括:FOREIGN KEY 本身、引用该约束的列(外键字段)及其中的具体值。
为何需要外键?——从范式论说起
假设我们要设计“班级”和“学生”的信息模型。若将所有数据存储于单张表中,会出现大量班级信息的冗余(重复保存班级名称等),浪费存储空间且不利于更新。第二种方案将班级与学生分拆为两张表:
拆分后,学生表中的班级编号(cno)如果不加限制,可能会出现指向不存在的班级(如班级表中没有 102 班,但学生表里有 102)。为此,需引入外键约束,强制 cno 的值必须在父表(班级表)中存在。
外键操作的顺序规则
在使用外键时,必须严格遵守操作顺序,以避免破坏数据一致性:
- 建表顺序:先创建父表(被引用表),再创建子表(引用表)。
- 删除顺序:必须先删除子表数据,再删除子表;随后处理父表。
- 插入顺序:必须先有父表数据,才能向子表插入对应外键值的记录。
创建并测试外键表
第1步:构建父子表结构
目的:建立一个具备参照引用的数据库环境。
-- 创建父表:班级表 mysql> create table t_class( classno int primary key, classname varchar(255) ); -- 创建子表:学生表 mysql> create table t_student( no int primary key auto_increment, name varchar(255), cno int, foreign key(cno) references t_class(classno) );
第2步:录入初始数据
入口:首先在父表中写入有效的班级列表。
mysql> insert into t_class(classno, classname) values(100, '高三1班'); mysql> insert into t_class(classno, classname) values(101, '高三2班');
随后在子表录入多名学生归属 100 班的记录:
mysql> insert into t_student(name, cno) values('jack', 100);
mysql> insert into t_student(name, cno) values('lucy', 100);
mysql> insert into t_student(name, cno) values('lilei', 100);
mysql> insert into t_student(name, cno) values('hanmeimei', 100);
mysql> insert into t_student(name, cno) values('zhangsan', 100);
mysql> insert into t_student(name, cno) values('lisi', 100);
mysql> insert into t_student(name, cno) values('wangwu', 100);
mysql> insert into t_student(name, cno) values('zhaoliu', 100);
关于父表字段是否必须是主键的说明:被外键引用的字段并不绝对必须是主键(Primary Key),但它至少必须具备 UNIQUE(唯一)约束,以保证关系的准确映射。
以上就是MySQL中常见数据约束(非空、唯一、主键、外键)的详细内容与操作实践,更多关于数据库设计与优化的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









