FleaPHP 开发指南 - 7. 数据表关联

数据表关联是指两个或者多个数据表的记录之间的逻辑关系。

例如:

  • 每一个公民都有一个身份证号码
  • 每一位作者都写了多本(0-n)书籍,而每一本书籍都有多个(1-n)作者
  • 每一篇文章都有多个(0-n)评论
  • 每一个评论都属于一篇文章

目前,FleaPHP 支持四种类型的数据表关联,分别是:

  • HAS_ONE: 当前表的每一条记录都拥有最多一条(0–1)关联记录
  • HAS_MANY: 当前表的每一条记录都拥有多条(0-n)关联记录
  • MANY_TO_MANY: 当前表的每一条记录都和其他表的多条(0-n)记录关联
  • BELONGS_TO: 当前表的每一条记录都属于另一个表的某条记录

在 FleaPHP 中,可以为每一个表数据入口定义多个不同的关联,例如:

<?php

load_class('FLEA_Db_TableDataGateway');

class Model_ProductClass extends FLEA_Db_TableDataGateway
{
    var $tableName = 'product_class';
    var $primaryKey = 'pclass_id';

    var $hasMany = array(
        array(
            'tableClass' => 'Model_Permissions',
            'foreignKey' => 'pclass_id',
            'mappingName' => 'permissions',
        ),
        array(
            'tableClass' => 'Model_Products',
            'foreignKey' => 'pclass_id',
            'mappingName' => 'products',
            'enabled' => false,
        ),
    );
    var $hasOne = array(
        array(
            'tableClass' => 'Model_ProductClassAdverts',
            'foreignKey' => 'pclass_id',
            'mappingName' => 'advert',
        )
    );
}

?>


术语

在详细介绍这四种关联之前,先了解一些后文将会用到的术语。

  • 关联: 一个关联是一个关系,这个关系属于某一个数据表。例如 users 表可能就拥有一个或者多个关联。
  • 主表: 对于一个关联,拥有该关联的数据表就是主表。例如 posts 表定义了一个 MANY_TO_MANY 关联。那么在这里(指这个关联),posts 就是主表。
  • 关联表: 在一个关联中,关联表就是除主表外的另一个表。
  • 外键: 在数据库原理中,外键的含义很复杂。但在 FleaPHP 框架中的数据库关联功能中,外键泛指一个记录中用于关联另一个记录的字段。例如 profile 表中的 user_id 字段就是用于关联 users 表的字段。这个 user_id 字段就是一个外键。
  • 中间表: 在 MANY_TO_MANY 关联中,除了主表和关联表,还需要另一个表来保存这两个表的记录之间的互相关联关系。这个表称为中间表。

理解这几个术语后,我们再来看每一种关联的详细解释。



HAS_ONE 一对一关联

HAS_ONE 是一种非常简单的关联关系。表示一个记录拥有另一个记录。这两个记录分别位于两个数据表中。

示例

在一个信息管理系统中,users 表用于存储用户帐户的基本信息,例如用户名、密码等。而 profiles 表则用于存储用户的个人信息,例如家庭住址、邮政编码等。

由于每一个用户(一条 users 表中的记录)都有一份对应的个人信息(一条 profiles 表中的记录)。因此,我们就可以为 users 表定义一个 HAS_ONE 关联。

很明显,users 表的记录拥有一条 profiles 表的记录。因此,当 users 表中的一条记录被删除时,被删除记录所拥有的 profiles 表中的关联记录也会被自动删除。

表定义

在 HAS_ONE 关联中,要求外键放置在关联表中。

上述例子的表定义简化版如下:

users 表:

  • user_id 主键字段
  • username

profiles 表:

  • profile_id 主键字段
  • address
  • postcode
  • user_id 外键字段

对应的 MySQL 代码如下:

CREATE TABLE `users` (
    `user_id` INT NOT NULL AUTO_INCREMENT ,
    `username` VARCHAR( 32 ) NOT NULL ,
    PRIMARY KEY ( `user_id` )
);

CREATE TABLE `profiles` (
    `profile_id` INT NOT NULL AUTO_INCREMENT ,
    `address` VARCHAR( 128 ) NOT NULL ,
    `postcode` VARCHAR( 8 ) NOT NULL ,
    `user_id` INT NOT NULL ,
    PRIMARY KEY ( `profile_id` )
);

对应的 FLEA_Db_TableDataGateway 继承类的定义如下:

<?php

load_class('FLEA_Db_TableDataGateway');

class Users extends FLEA_Db_TableDataGateway
{
    var $tableName = 'users';
    var $primaryKey = 'user_id';

    var $hasOne = array(
        'tableClass' => 'Profiles',
        'foreignKey' => 'user_id',
        'mappingName' => 'profile',
    );
}

class Profiles extends FLEA_Db_TableDataGateway
{
    var $tableName = 'profiles';
    var $primaryKey = 'profile_id';
}

?>

演示代码

<?php

// 首先插入一条 users 记录
$modelUsers =& new Users();
$newUserId = $modelUsers->create(
    array('username' => 'dualface')
);

// 接下来,再插入一条 profiles 记录
$modelProfiles =& new Profiles();
$modelProfiles->create(
    array(
        'address' => 'SiChuan ZiGong',
        'postcode' => '643000',
        'user_id' => $newUserId
    )
);

// OK,我们现在尝试读取一条 users 记录,看看会得到什么结果
$user = $modelUsers->find($newUserId);
dump($user);

?>

结果很有趣,多出来的 ‘profile’ 字段正好是我们刚刚插入 profiles 表的记录内容:

Array
(
    [user_id] => 1
    [username] => dualface
    [ref___id] => 1
    [profile] => Array
        (
            [profile_id] => 1
            [address] => SiChuan ZiGong
            [postcode] => 643000
            [user_id] => 1
            [ref___id] => 1
        )
)

说明

在上面的例子中,Users 类中有一个 $hasOne 成员变量。该变量为一个数组:

var $hasOne = array(
    'tableClass' => 'Profiles',
    'foreignKey' => 'user_id',
    'mappingName' => 'profile',
);

$hasOne 成员变量用于为一个表数据库入口指定 HAS_ONE 关联。

在关联的定义中,tableClass 指定关联表的表数据入口类名称,foreignKey 指定外键字段名,而 mappingName 则指定在主表的查询结果中用什么字段映射关联表的数据。





未完待续。。。。

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值