部分人都不能理解外键, 主键问题

来源:8-3 模型关联----嵌套关联查询

周康武

2019-07-16

首先贴一下代码, 分别是Banner , BannerItem 和Image 的模型代码

class Banner extends Model
{
    public function items(){
        return $this->hasMany('BannerItem', 'banner_id', 'id');
    }
}
class BannerItem extends Model
{
    public function img(){
//        return $this->belongsTo('Image', 'img_id', 'id');
        return $this->hasOne('Image', 'id', 'img_id');
//        return $this->belongsTo('Image', 'id', 'img_id'); 错误
    }
}
class Image extends Model
{
}

学完这节课, 部分人对主键外键很疑惑,我也不例外。主要的问题就是在Banner 模型类里面的方法

 $this->hasMany('BannerItem', 'banner_id', 'id');

第一个参数是关联的模型 BannerItem 没问题
第二个参数是外键(foreignkey), 就是BannerItem 表的 banner_id 属性
第三个参数是主键(localkey), 就是Banner 表的 id 属性
所以说外键banner_id就 BannerItem 外表 里面。
而主键id 就是在$this 也就是Banner 主表里面。

接下来看第二段代码, 就发现有点不对劲了

$this->belongsTo('Image', 'img_id', 'id');

上面的代码是BannerItem 里面的,也就是说 $this 就是BannerItem 对象
第一个参数 关联Image模型
第二个参数是外键(foreignkey), 那就是Image 外表的 id 属性才对
第三个参数是主键(localkey), 就是 $this BannerItem 表的 img_id 属性才对
所以说应该这样写

return $this->belongsTo('Image', 'id', 'img_id'); // 错误

经测试发现会报错。

重新查看老师的sql 语句
图片描述

老师在创建数据库的时候以及订好了主键, 可是没有定外键, 所以问题来了, 怎么确定外键??? 真的是因为创建表的时候,定了主键吗??
我觉得不是 (别问我为什么)

我重新查询了Thinkphp5文档 发现一对一模型还有一个方法 hasOne, 我用hasOne 测试了一下

 return $this->hasOne('Image', 'id', 'img_id');

测试通过, 之前的逻辑一下子通了
这里$this 是BannerItem 对象
第一个参数就是关联外表 image ,
第二个参数 外键就是关联外表 image 里面的属性id
第三个参数 主键就是 $this BannerItem 表的img_id 属性

那么belongsTo 方法的后面两个参数为什么会反转呢,其实这里有个包含关系

 $this->hasMany('BannerItem', 'banner_id', 'id');

上面的意思是 $this (Banner表) 有很多 BannerItem 数据, Banner 包含 BannerItem , 自然Banner 就是主表, BannerItem 是外表
主键在主表, 外键在外表的逻辑就通了

同理

$this->hasOne('Image', 'id', 'img_id');

就是说BannerItem 有一个Image , BannerItem 包含Image,
主表BannerItem , 外表Image,
因为 主键在主表, 外键在外表;
所以 主键就是img_id 外键就是 id

最后

return $this->belongsTo('Image', 'img_id', 'id');

老师这里用的是belongsTo ,这个方法跟hasOne 方向是反的
这句代码的意思是BannerItem 属于 Image , 这包含关系就是Image 有一个BannerItem, 所以说 这里Image才是主表, BannerItem 是外表, 主键就id, 外键就是img_id 了

总结: 这些方法的主键外键是相对的, 并不是在创建表的时候的, 用sql语句设定的主键外键

个人的理解, 不知对不对, 欢迎指正

写回答

2回答

大大大嘴

2019-09-24

给力!

0
0

7七月

2019-07-18

整理的不错~~~,这个外键是逻辑外键,并不是物理外键。

0
0

微信小程序电商实战 从前端到后端的全流程精讲

全栈工程师/前后端都讲/架构思想/ RESTFul API、MySQL表设计

4805 学习 · 4382 问题

查看课程