PHP数据库ORM理念演变belongsTo

belongsTo 理念来源

1. 根本来源:关系型数据库设计

belongsTo 理念源于 关系型数据库的外键概念

sql 复制代码
-- 数据库层面:外键关系
CREATE TABLE shopro_commission_member_pv (
    id INT PRIMARY KEY,
    member_id INT,
    pv_amount INT,
    -- member_id 是外键,指向 shopro_user 表的 id
    FOREIGN KEY (member_id) REFERENCES shopro_user(id)
);

这表达了一种数据关系:PV 记录"属于"某个用户。


2. ORM 框架的抽象化

Rails 的 ActiveRecord ORM (2005年左右)首创了将数据库关系转化为代码方法:

ruby 复制代码
# Rails 中的做法(ActiveRecord)
class MemberPv < ApplicationRecord
  belongs_to :user, foreign_key: "member_id"
end

# 使用
pv = MemberPv.find(1)
pv.user.nickname  # 自动根据 foreign_key 关联查询

3. ThinkPHP 的借鉴

ThinkPHP 框架设计者参考了 Rails 的思想,设计了类似的 ORM 关联系统:

php 复制代码
// ThinkPHP 的做法(模仿 Rails)
class MemberPv extends Common {
    public function user() {
        return $this->belongsTo(User::class, 'member_id', 'id');
    }
}

4. 设计理念演变链

复制代码
关系型数据库外键
    ↓
SQL 中的 JOIN 操作
    ↓
Rails ActiveRecord ORM
    ↓
Eloquent (Laravel)
    ↓
ThinkPHP ORM
    ↓
其他 PHP 框架 (Doctrine, Propel)

5. 抽象化的三个层级

第一层:数据库层

sql 复制代码
-- 数据关系定义在数据库中
FOREIGN KEY (member_id) REFERENCES shopro_user(id)

第二层:SQL 查询层

sql 复制代码
-- 通过 JOIN 关联查询
SELECT pv.*, u.* FROM shopro_commission_member_pv pv
LEFT JOIN shopro_user u ON pv.member_id = u.id

第三层:ORM 对象层

php 复制代码
// belongsTo 将上面两层抽象为对象方法
$pv = MemberPv::with('user')->find(1);
$pv->user->nickname;  // 一句代码完成前两层的工作

6. 为什么要设计 belongsTo?

原因 说明
屏蔽 SQL 复杂性 开发者不需要写复杂的 JOIN 语句
思维对象化 用对象关系思考,而不是表和字段
减少重复代码 关联逻辑集中在模型中定义一次
提高可维护性 关系变化只需改模型定义
自动优化查询 框架可自动选择 JOIN 还是子查询

7. 同类产品对比

所有现代 ORM 都有类似的概念,名称略有不同:

框架 概念名 语法
Rails belongs_to belongs_to :user
Laravel belongsTo belongsTo(User::class, 'member_id')
ThinkPHP belongsTo belongsTo(User::class, 'member_id', 'id')
Doctrine (PHP) @ManyToOne 注解定义
Hibernate (Java) @ManyToOne 注解定义

8. 完整演变示例

php 复制代码
// ❌ 原始时代(2005年前)- 纯 SQL
$sql = "SELECT pv.*, u.* FROM shopro_commission_member_pv pv 
        LEFT JOIN shopro_user u ON pv.member_id = u.id 
        WHERE pv.id = 1";
$result = $db->query($sql);

// ⚠️ 中期(2005-2010)- 查询构造器
$result = $db->table('shopro_commission_member_pv')
            ->leftJoin('shopro_user', 'shopro_commission_member_pv.member_id', '=', 'shopro_user.id')
            ->where('shopro_commission_member_pv.id', 1)
            ->get();

// ✅ 现代(2010+)- ORM 关联
class MemberPv extends Common {
    public function user() {
        return $this->belongsTo(User::class, 'member_id', 'id');
    }
}
$pv = MemberPv::with('user')->find(1);

核心设计思想

belongsTo 的核心是: 用面向对象的语言描述关系型数据库的约束关系,让开发者可以像操作对象一样操作数据关联,而不是写 SQL。

这是 ORM (Object-Relational Mapping) 的核心目标。