1

我一直在寻找这个问题的明确答案,但一直无法解决。我最近一直在使用(和学习)CakePHP,并且遇到了障碍。为了简化我的数据库,假设我们只有两个表:

persons relationships(或persons_persons

Persons 与自身有一个多对多的关系——事实上,两个人彼此之间可以有多个关系:

persons
-------
*person_id*
name

relationships
-------------
*relationship_id*
person_1_id
person_2_id
start_date
end_date

现在,如果我想说 Person1 (id=1) 与 Person2 结婚,我会在relationships表中输入一个条目。person_1_id将是1,并且person_2_id将是两个。

我可以在 CakePHP 中创建这种关系,并显示每个 Person 记录的关系(和人员)列表。但是,这是一个单向关系:对于 Person 1,查询只会拉取匹配的Relationship对象。person_1_id如果我想查询 Person 2 的关系,我必须有第二个相同的行,person_1_idperson_2_id交换 and 。

这是模型:

class Member extends AppModel {
    public $hasMany = array(
        'Relationships' => array(
            'className' => 'Relationship',
            'foreignKey' => 'person_1_id'
        )
    );
}

class Relationship extends AppModel {
    public $belongsTo = array(
        'Person1' => array(
            'className' => 'Person',
            'foreignKey' => 'person_1_id'
        ),
        'Person2' => array(
            'className' => 'Person',
            'foreignKey' => 'person_2_id'
        )
    );
}

有什么建议么?当 person_1_id 实际上与 person_2_id 没有分离时,复制关系实体没有逻辑意义。

4

1 回答 1

3

我认为你有两个选择:

1.复制关系记录

换个角度看;考虑有图与无向图的概念。您当前的模式支持离开一个对象(人)并到达另一个对象的有向边。从您的应用程序的角度来看,一个人不能在他们不知情的情况下与另一个人建立关系。

如果您确实选择了这条路线,那么数据库中的空间量可以忽略不计,并且实现起来比选项 2 更简单。请记住,您应该采取措施确保关系始终保持对称。

2. 处理应用程序中的关系不对称

创建另一个关系,使您的模型如下所示:

class Member extends AppModel {
    public $hasMany = array(
        'RelationshipsA' => array(
            'className' => 'Relationship',
            'foreignKey' => 'person_1_id'
        ),
        'RelationshipsB' => array(
            'className' => 'Relationship',
            'foreignKey' => 'person_2_id'
        )
    );
}

然后,根据您的人存在的关系的哪一方,您可以为您的关系提供单独的垃圾箱。然后,您必须在任何地方放置额外的逻辑,以便您可以将关系箱作为一个同质集合来处理。

很抱歉,我不能再有帮助了,但我无法想到如何实现一个无向图而不将其构建在有向图之上。

2013 年 5 月 5 日更新

总结评论线程,设置关联可以掩盖重复查找与(文档finderQuery)关联的需要:hasManyperson_2_id

'Relationship' => array(
    'finderQuery' => 'SELECT Relationship.* FROM relationships AS Relationship WHERE Relationship.person_2_id = {$__cakeID__$} OR Relationship.person_1_id = {$__cakeID__$};'
)

这隐藏了复杂的检索机制,但存储关系可能需要进一步考虑。

于 2013-05-04T13:00:47.753 回答