在我的cakephp3应用程序中,我有一个Players表和一个Matches表,记录两个玩家之间完成的每个匹配。我的表匹配的结构是:
我已经定义了玩家和匹配之间的关联,如下所示:
// in src/Model/Table/PlayersTable.php
$this->hasMany('Victories', [
'className' => 'Matches',
'foreignKey' => 'winner_id'
]);
$this->hasMany('Losses', [
'className' => 'Matches',
'foreignKey' => 'loser_id'
]);
当我想要找回所有比赛的球员时,我会这样做:
// in src/Controller/PlayersController.php
$player = $this->Players->findById($user_id)->contain(['Victories', 'Losses'])->first();
但这不是很方便,因为要在一个地方获得所有玩家的比赛,我必须合并$player->victories
和$player->losses
。
另外,我不能轻易地执行简单的请求,例如“让最后一场比赛获得50名球员”。
所以我觉得我的数据库模式不理想,我可以改进。但我真的不明白。有什么建议吗?
答案 0 :(得分:1)
正确的架构是删除匹配项中的winner_id
和loser_id
,并将它们放入另一个可以称为contenders
的表中
表格竞争者:
* match_id
* player_id
* has_won (boolean)
您使用hasMany
:
$this->hasMany('Contenders');
现在,您还可以使用belongsToMany
关联将Matchers与玩家相关联:
$this->belongsToMany('Players', ['through' => 'Contenders']);
您还可以将玩家表关联到胜利和损失:
$this->belongsToMany('Victories', [
'className' => 'Matches',
'through' => 'Contenders'
'conditions' => ['Contenders.has_won' => true]
]);
$this->belongsToMany('Losses', [
'className' => 'Matches',
'through' => 'Contenders'
'conditions' => ['Contenders.has_won' => false]
]);
最后,您还可以通过添加另一个belognsToMany
来了解玩家的所有匹配项:
$this->belongsToMany('Matches');