资讯动态

MySQL基础 约束详解 表与表之间的关系

发布时间:2026/8/22 16:39:52 来源:尧图企业网站定制
目标掌握数据库五大约束的使用理解表与表之间的三种关系及建立方式 一、什么是约束在数据库设计中约束Constraint是对表中数据施加的限制规则用于确保数据的完整性准确性、正确性。使用约束的好处✅ 防止错误数据写入数据库✅ 减少冗余数据脏数据✅ 保证数据的一致性和可靠性MySQL 中常用的约束共有五大类约束类型关键字作用主键约束PRIMARY KEY唯一标识一条记录不允许为空且不能重复唯一约束UNIQUE保证列中数据不重复但允许为空非空约束NOT NULL该列不允许为空值默认约束DEFAULT插入时若不提供值则使用默认值填充外键约束FOREIGN KEY维护两张表之间数据的一致性与完整性 二、主键约束PRIMARY KEY2.1 基本概念理论上每张表都必须有一个主键作为数据的唯一标识主键列的值不允许为 NULL且不允许重复主键通常用id命名是额外增加的列而非业务数据列2.2 建表时指定主键CREATETABLEstudent(idINTPRIMARYKEY,nameVARCHAR(50),ageINT,emailVARCHAR(100));2.3 主键重复时会报错-- 第一条成功INSERTINTOstudent(id,name,age,email)VALUES(1,张三,18,1443005893qq.com);-- 第二条失败id1 已存在主键重复报错INSERTINTOstudent(id,name,age,email)VALUES(1,李四,20,1443005893qq.com);❌Duplicate entry 1 for key PRIMARY2.4 自动递增 AUTO_INCREMENT手动维护主键十分麻烦MySQL 提供了自动递增策略——每次取当前表中最大 ID 值 1由数据库自动维护。CREATETABLEstudent(idINTPRIMARYKEYAUTO_INCREMENT,nameVARCHAR(50),ageINT,emailVARCHAR(100));-- 插入时无需手动指定 idINSERTINTOstudent(name,age,email)VALUES(张三,18,1443005893qq.com);INSERTINTOstudent(name,age,email)VALUES(李四,20,1443005893qq.com);AUTO_INCREMENT 的重要特点只有整型列才能设置为自动递增只有主键才能设置为自增列新增数据时可以不赋值系统自动填充初始值默认为1步长默认为1自增值一旦被使用即便该行被删除也不会回退复用 三、唯一约束UNIQUE3.1 基本概念保证某列数据不允许重复与主键类似但级别低于主键一张表可以创建多个唯一约束唯一约束的列允许为 NULLNULL 不参与唯一性比较⚠️ 注意VARCHAR(255)长度时无法设置唯一约束3.2 常见应用场景唯一约束常用于约束手机号、账号、邮箱等不允许重复的字段。CREATETABLEstudent(idINTPRIMARYKEYAUTO_INCREMENT,nameVARCHAR(50),ageINT,emailVARCHAR(100)UNIQUE-- 邮箱不允许重复);3.3 违反唯一约束时报错INSERTINTOstudent(name,age,email)VALUES(张三,18,1443005893qq.com);-- 同一邮箱再次插入触发唯一约束INSERTINTOstudent(name,age,email)VALUES(lisi,20,1443005893qq.com);❌Duplicate entry 1443005893qq.com for key email 四、非空约束NOT NULL4.1 基本概念通过NOT NULL将某列设置为必填字段插入数据时该列不允许为空值。4.2 使用示例CREATETABLEstudent(idINTPRIMARYKEYAUTO_INCREMENT,nameVARCHAR(50)NOTNULL,-- 姓名不能为空ageINT,emailVARCHAR(100)UNIQUE);-- 尝试插入空姓名会报错INSERTINTOstudent(name,age,email)VALUES(NULL,18,testqq.com);❌Column name cannot be null️ 五、默认约束DEFAULT5.1 基本概念通过DEFAULT为某列设置默认值插入时若不提供该列的值则自动使用默认值填充。5.2 使用示例CREATETABLEstudent(idINTPRIMARYKEYAUTO_INCREMENT,nameVARCHAR(50)NOTNULL,ageINTDEFAULT18,-- 年龄默认为18genderVARCHAR(10)DEFAULT男-- 性别默认为男);-- 不提供 age 和 gender将使用默认值INSERTINTOstudent(name)VALUES(张三);-- 查询结果age18, gender男SELECT*FROMstudent; 六、外键约束FOREIGN KEY6.1 基本概念外键用来让两个表的数据之间建立连接保证数据的一致性和完整性。拥有外键的表称为从表子表被引用的表称为主表父表从表外键列的值必须在主表对应列中存在6.2 添加外键示例假设有部门表dept和员工表emp-- 主表部门表CREATETABLEdept(idINTPRIMARYKEYAUTO_INCREMENT,nameVARCHAR(50)NOTNULL);-- 从表员工表dept_id 引用 dept 的主键CREATETABLEemp(idINTPRIMARYKEYAUTO_INCREMENT,nameVARCHAR(50)NOTNULL,dept_idINT,CONSTRAINTfk_emp_deptFOREIGNKEY(dept_id)REFERENCESdept(id));6.3 删除 / 更新时的行为策略当主表数据发生变化时从表如何联动可通过以下策略控制策略说明CASCADE父表 update/delete 时子表匹配记录同步update/deleteSET NULL父表 update/delete 时子表外键列设为 NULL该列不能是 NOT NULLNO ACTION子表有匹配记录时不允许父表进行 update/deleteRESTRICT同 NO ACTION立即检查外键约束-- 使用 CASCADE父表删除时子表联动删除CONSTRAINTfk_emp_deptFOREIGNKEY(dept_id)REFERENCESdept(id)ONDELETECASCADEONUPDATECASCADE6.4 使用外键的注意事项数据库引擎必须为InnoDBMyISAM 不支持外键从表中的外键值必须在主表中存在或者为 NULL6.5 ⚠️ 为什么实际开发中常常不使用外键尽管外键能提高数据质量但在实际工程中许多团队选择不在数据库层面使用外键而是在应用层做数据一致性校验。原因如下在表上存在活动外键时每次插入、更新、删除操作前数据库都需要检查是否违反约束对性能影响较大。数据仓库、OLAP 场景中批量处理数据时性能开销尤为明显。常见做法数据库不加外键 业务代码保证数据一致性 定期数据巡检。️ 七、表与表之间的关系数据库中表和表之间存在三种基本关系一对一、一对多、多对多。正确理解并设计表关系是数据库建模的核心能力。7.1 一对多最常见概念一张表中的一条记录对应另一张表中的多条记录。典型例子一个部门拥有多个员工一个用户有多条订单一个班级有多个学生如何建立联系在**多的一方**子表添加外键引用**一的一方**父表的主键。-- 父表部门一CREATETABLEdept(idINTPRIMARYKEYAUTO_INCREMENT,nameVARCHAR(50)NOTNULL);-- 子表员工多CREATETABLEemp(idINTPRIMARYKEYAUTO_INCREMENT,nameVARCHAR(50)NOTNULL,dept_idINT,-- 外键指向 dept 表FOREIGNKEY(dept_id)REFERENCESdept(id));关系示意图7.2 一对一概念一张表中的一条记录对应另一张表中的恰好一条记录反之亦然。典型例子用户表与用户详情表基础信息 扩展信息拆分存储公民与身份证员工与工牌为什么需要一对一通常是为了垂直分表将频繁访问的核心字段和不常访问的扩展字段分开提升查询性能字段过多时拆分成两张表管理更清晰如何建立联系在任意一方添加外键并在外键列上加UNIQUE约束保证一对一而非一对多。-- 用户基础表CREATETABLEuser(idINTPRIMARYKEYAUTO_INCREMENT,usernameVARCHAR(50)NOTNULL,passwordVARCHAR(100)NOTNULL);-- 用户详情表CREATETABLEuser_detail(idINTPRIMARYKEYAUTO_INCREMENT,user_idINTUNIQUE,-- UNIQUE 保证一对一phoneVARCHAR(20),addressVARCHAR(200),FOREIGNKEY(user_id)REFERENCESuser(id));关系示意图7.3 多对多概念一张表中的一条记录对应另一张表中的多条记录反过来也一样。典型例子学生和课程一个学生选多门课一门课有多个学生用户和角色一个用户有多个角色一个角色对应多个用户订单和商品一个订单包含多个商品一个商品出现在多个订单中如何建立联系中间关系表多对多不能直接在两张表上加外键来解决必须引入第三张关联表中间表。中间表至少包含两个外键分别指向两张主表的主键。-- 学生表CREATETABLEstudent(idINTPRIMARYKEYAUTO_INCREMENT,nameVARCHAR(50)NOTNULL);-- 课程表CREATETABLEcourse(idINTPRIMARYKEYAUTO_INCREMENT,nameVARCHAR(100)NOTNULL);-- 中间关联表学生选课CREATETABLEstudent_course(idINTPRIMARYKEYAUTO_INCREMENT,student_idINTNOTNULL,course_idINTNOTNULL,scoreDECIMAL(5,2),-- 还可以存储关系相关的额外属性FOREIGNKEY(student_id)REFERENCESstudent(id),FOREIGNKEY(course_id)REFERENCEScourse(id),UNIQUEKEYuk_stu_course(student_id,course_id)-- 防止重复选课);数据示例可以看出张三选了 MySQL 和 Java李四选了 MySQL王五选了 Python。7.4 三种关系总结对比关系类型典型场景实现方式一对多部门-员工、用户-订单在多的一方加外键一对一用户-详情、公民-身份证在任意一方加外键 UNIQUE约束多对多学生-课程、用户-角色创建中间关联表各加一个外键 八、综合建表案例以一个简单的选课系统为例综合运用约束与表关系-- 1. 班级表CREATETABLEclass(idINTPRIMARYKEYAUTO_INCREMENT,nameVARCHAR(50)NOTNULLUNIQUE-- 班级名唯一);-- 2. 学生表多对一 班级CREATETABLEstudent(idINTPRIMARYKEYAUTO_INCREMENT,nameVARCHAR(50)NOTNULL,ageINTDEFAULT18,emailVARCHAR(100)UNIQUE,class_idINT,FOREIGNKEY(class_id)REFERENCESclass(id)ONDELETESETNULL);-- 3. 课程表CREATETABLEcourse(idINTPRIMARYKEYAUTO_INCREMENT,nameVARCHAR(100)NOTNULL,descriptionVARCHAR(500));-- 4. 选课中间表多对多CREATETABLEstudent_course(idINTPRIMARYKEYAUTO_INCREMENT,student_idINTNOTNULL,course_idINTNOTNULL,scoreDECIMAL(5,2),FOREIGNKEY(student_id)REFERENCESstudent(id)ONDELETECASCADE,FOREIGNKEY(course_id)REFERENCEScourse(id)ONDELETECASCADE,UNIQUEKEYuk_stu_course(student_id,course_id)); 总结知识点核心要点主键约束唯一 非空配合AUTO_INCREMENT自动维护唯一约束不重复但可为空一表可有多个非空约束该列必须有值默认约束不传值时自动填默认值外键约束维护表间引用完整性实际开发中常用应用层替代一对多在多方加外键一对一外键 UNIQUE多对多建立中间关联表学习建议约束是数据库设计的基础表关系是业务建模的核心。建议多练习 ER 图设计先画图再建表养成良好的数据库设计习惯。如有问题欢迎在评论区留言交流

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价