mysql数据库表之间如何建立关系_mysql表关联设计

发布时间 - 2026-02-01 00:00:00    点击率:
外键约束仅InnoDB生效,MyISAM不校验;建表需父表被引用列有索引、列类型严格一致、外键名唯一;一对多在“多”方加外键并建索引;多对多必须用带双外键的中间表;LEFT JOIN出NULL常因孤儿记录。

外键约束怎么加才生效

MySQL 中表关联的核心是外键(FOREIGN KEY),但不是所有存储引擎都支持。只有 InnoDB 支持完整外键约束,MyISAM 虽能解析 FOREIGN KEY 语法,但完全不校验、不生效。

建表时加外键必须满足几个硬性条件:

  • 父表 的被引用列(通常是主键或唯一索引列)必须有明确的索引,否则报错 ERROR 1005 (HY000): Can't create table ... errno: 150
  • 子表和父表的对应列类型要严格一致:整型宽度、是否 UNSIGNED、字符集和排序规则(COLLATE)都不能差一点
  • 外键名在同一个数据库内不能重复;若用 ALTER TABLE 添加,需先确保子表数据全部符合父表现有值(否则会因“孤儿记录”失败)

一对多关系怎么写最稳妥

这是最常见也最容易出错的场景。比如 orders 表和 users 表,一个用户可下多个订单,但一个订单只属于一个用户。

关键设计点:

  • 在「多」的一方(orders)加外键字段,例如 user_id INT NOT NULL,再用 FOREIGN KEY (user_id) REFERENCES users(id)
  • 务必给 user_id 加普通索引(INDEX),否则 JOINDELETE CASCADE 时性能极差
  • 如果业务允许用户注销后订单仍保留,外键可设为 ON DELETE SET NULL;但此时 user_id 字段必须允许 NULL,且注意后续 WHERE user_id = ? 查询无法走索引(NULL 值不参与 B+ 树索引)

多对多关系为什么必须用中间表

比如 stude

ntscourses,一个学生选多门课,一门课被多个学生选。直接在任一表加字段会爆炸式冗余——你没法在一个字段里存多个 ID,也不该用逗号分隔字符串(违反第一范式,无法索引、无法约束、无法原子更新)。

正确做法是建第三张表(如 student_courses):

  • 它只有两个字段:student_idcourse_id,联合设为主键(PRIMARY KEY (student_id, course_id)
  • 两边都加外键:FOREIGN KEY (student_id) REFERENCES students(id) ON DELETE CASCADE,同理处理 course_id
  • 如果需要记录选课时间等额外信息,就把这些字段加到中间表里,而不是硬塞进任一主表

LEFT JOIN 时 NULL 值从哪来

很多人执行 SELECT * FROM orders LEFT JOIN users ON orders.user_id = users.id 后发现 users 字段全是 NULL,第一反应是“关联没写对”,其实更可能是外键字段里存了父表不存在的值(比如 user_id = 999,但 users 表最大 id 是 100)。

这种数据叫“孤儿记录”,根源在于:

  • 建表时没加外键约束(或用了 MyISAM
  • 应用层绕过数据库逻辑,直接 INSERT 了非法 user_id
  • 手动删了 users 记录,但没配 ON DELETE CASCADE,也没在代码里同步清理 orders

查孤儿记录可以用:SELECT * FROM orders WHERE user_id NOT IN (SELECT id FROM users WHERE id IS NOT NULL),但注意 NOT IN 遇到 NULL 会整个失效,生产环境建议改用 NOT EXISTSLEFT JOIN ... WHERE users.id IS NULL


# mysql  # cad  # 为什么  # NULL  # select  # Error  # 整型  # 字符串  # errno  # int  # delete  # table  # 数据库  # 多个  # 设为  # 主键  # 这是  # 几个  # 也不  # 键名  # 也没  # 很多人  # 可以用 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: JavaScript中的标签模板是什么_它如何扩展字符串功能  Laravel如何处理JSON字段的查询和更新_Laravel JSON列操作与查询技巧  桂林网站制作公司有哪些,桂林马拉松怎么报名?  米侠浏览器网页图片不显示怎么办 米侠图片加载修复  如何批量查询域名的建站时间记录?  使用spring连接及操作mongodb3.0实例  合肥制作网站的公司有哪些,合肥聚美网络科技有限公司介绍?  如何彻底卸载建站之星软件?  深圳网站制作的公司有哪些,dido官方网站?  Laravel中的Facade(门面)到底是什么原理  宙斯浏览器视频悬浮窗怎么开启 边看视频边操作其他应用教程  Laravel Session怎么存储_Laravel Session驱动配置详解  北京专业网站制作设计师招聘,北京白云观官方网站?  小视频制作网站有哪些,有什么看国内小视频的网站,求推荐?  Laravel怎么实现软删除SoftDeletes_Laravel模型回收站功能与数据恢复【步骤】  免费网站制作appp,免费制作app哪个平台好?  Laravel如何构建RESTful API_Laravel标准化API接口开发指南  Laravel Pest测试框架怎么用_从PHPUnit转向Pest的Laravel测试教程  深圳网站制作平台,深圳市做网站好的公司有哪些?  HTML 中如何正确使用模板变量为元素的 name 属性赋值  如何在万网主机上快速搭建网站?  千库网官网入口推荐 千库网设计创意平台入口  Laravel Eloquent:优雅地将关联模型字段扁平化到主模型中  Laravel怎么实现微信登录_Laravel Socialite第三方登录集成  音响网站制作视频教程,隆霸音响官方网站?  Laravel队列由Redis驱动怎么配置_Laravel Redis队列使用教程  如何在橙子建站中快速调整背景颜色?  Laravel怎么实现模型属性的自动加密  实例解析Array和String方法  Laravel怎么发送邮件_Laravel Mail类SMTP配置教程  如何在阿里云域名上完成建站全流程?  Laravel如何优雅地处理服务层_在Laravel中使用Service层和Repository层  如何快速查询网站的真实建站时间?  js代码实现下拉菜单【推荐】  javascript基于原型链的继承及call和apply函数用法分析  Python图片处理进阶教程_Pillow滤镜与图像增强  JavaScript数据类型有哪些_如何准确判断一个变量的类型  Mybatis 中的insertOrUpdate操作  手机怎么制作网站教程步骤,手机怎么做自己的网页链接?  网站建设整体流程解析,建站其实很容易!  使用PHP下载CSS文件中的所有图片【几行代码即可实现】  Python文件流缓冲机制_IO性能解析【教程】  如何在Windows 2008云服务器安全搭建网站?  Laravel如何使用集合(Collections)进行数据处理_Laravel Collection常用方法与技巧  Java解压缩zip - 解压缩多个文件或文件夹实例  Laravel怎么实现API接口鉴权_Laravel Sanctum令牌生成与请求验证【教程】  网站制作报价单模板图片,小松挖机官方网站报价?  品牌网站制作公司有哪些,买正品品牌一般去哪个网站买?  怎么用AI帮你为初创公司进行市场定位分析?  谷歌浏览器下载文件时中断怎么办 Google Chrome下载管理修复