CakePHP中的自反多对多关系
我一直在寻找这个问题的明确答案,但一直无法解决它。我最近一直在使用(并学习)CakePHP,遇到了一个障碍。为了简化我的数据库,假设我们只有两个表:CakePHP中的自反多对多关系,php,cakephp,Php,Cakephp,我一直在寻找这个问题的明确答案,但一直无法解决它。我最近一直在使用(并学习)CakePHP,遇到了一个障碍。为了简化我的数据库,假设我们只有两个表: 人员 关系(或人与人) 人与自身有多对多的关系——事实上,两个人之间可以有不止一种关系: persons ------- *person_id* name relationships ------------- *relationship_id* person_1_id person_2_id start_date end_date 现在,如果
人员
关系
(或人与人
)
人与自身有多对多的关系——事实上,两个人之间可以有不止一种关系:
persons
-------
*person_id*
name
relationships
-------------
*relationship_id*
person_1_id
person_2_id
start_date
end_date
现在,如果我想说Person1(id=1)与Person2结婚,我会在关系表中有一个条目<代码>人员id
将是1
,而人员id
将是两个
我可以用CakePHP创建这个关系,并显示每个人记录的关系(和人)列表。但是,它是一种单向关系:对于Person 1,查询将只提取关系
匹配Person\u 1\u id
的对象。如果我想查询Person 2的关系,我必须有第二个相同的行,Person\u 1\u id
和Person\u 2\u id
交换
以下是模型:
类成员扩展了AppModel{
public$hasMany=array(
“关系”=>数组(
'className'=>'Relationship',
'foreignKey'=>'person\u 1\u id'
)
);
}
类关系扩展了AppModel{
public$belongsTo=数组(
“Person1”=>数组(
“className”=>“Person”,
'foreignKey'=>'person\u 1\u id'
),
“Person2”=>数组(
“className”=>“Person”,
'foreignKey'=>'person\u 2\u id'
)
);
}
有什么建议吗?当person\u 1\u id实际上与person\u 2\u id不分离时,复制关系实体在逻辑上是没有意义的。我认为您有两种选择: 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日更新
要总结注释线程,在hasMany
关联上设置finderQuery
,可以屏蔽重复查找与person_2_id
()关联的需要:
这隐藏了复杂的检索机制,但存储关系可能需要进一步思考。感谢您深思熟虑的回答,Sam。这基本上是我一直在考虑的两个选项。我保留的一部分是,我可以不使用ORM轻松地实现这一点-连接将是一个OR键,我正在尝试解决如何在这里应用它。我尝试了hasMany关系的finderQuery,但没有成功。现在,我不回答这个问题,但最终我可能会选择选项1。别担心@AnthonyAziz,我很高兴我能帮你解决一点难题。当你指的是finderQuery时,你的意思是
$this->Model->query(“…”)
?在hasMany关系中,finderQuery应该是一种指定自定义查询的方法-这个想法来自于这篇文章:在玩了一些之后,Sam,我能够让它与finder查询一起工作-问题是我的hasMany关联被命名了“关系”和SQL查询的表别名为“关系”“显然这是个问题?无论如何,我将此标记为一个答案,或者是为了您的有用提示,或者是因为我最终可能会使用具有复制/反向关系的定向设计。再次感谢你的帮助!谢谢@AnthonyAziz我已经在更新答案中总结了我们的讨论,以便对其他人有所帮助。
'Relationship' => array(
'finderQuery' => 'SELECT Relationship.* FROM relationships AS Relationship WHERE Relationship.person_2_id = {$__cakeID__$} OR Relationship.person_1_id = {$__cakeID__$};'
)