教义中的多对多关系
Posted
技术标签:
【中文标题】教义中的多对多关系【英文标题】:many-to-many relationship in doctrine 【发布时间】:2009-12-08 17:32:39 【问题描述】:我的系统上有一些表格,如下所示:
news
--id
--title
--content
video
--id
--title
--url
album
--id
--title
现在,我需要以一种灵活的方式与这些表建立多对多关系。我创建了一个名为“链接”的表,其结构如下:
links
--parent_entity (example: news)
--parent_id (example: 5)
--child_entity (exmaple: video)
--child_id (example: 2)
我如何使用 Doctrine 映射它?
【问题讨论】:
您能解释一下为什么要尝试做不可知映射表之类的事情吗?仅仅是因为您想减少表格数量还是其他原因?使用多对多表提供了一些优势,例如外键约束。 【参考方案1】:这是不可能的,因为您无法进行正确的连接。这种情况下的连接将取决于 parent_entity 和 child_entity 中的值(即,每一行可能需要连接到不同的表)。此外,学说如何知道要合并哪种记录类型(即,因为它取决于实体类型)。
您可以通过在您的联接上使用 WITH 子句来取消这样的事情(尽管这会很奇怪)。例如,在新闻模型的 setUp() 方法中,您可以这样做:
$this->hasMany('Links as NewsVideoLinks', array('local' => 'id', 'foreign' => 'parent_id'));
在你的链接模型的设置中:
$this->hasMany('Videos as videos', array('local' => 'child_id', 'foreign' => 'id'));
您需要在链接模型中定义所有连接组合。我的意思是,你需要告诉它它有很多新闻和专辑,同时使用 child_id 和 parent_id。
然后在您的查询中,您需要执行以下操作:
$query = Doctrine_Query::create();
$query->from('News n');
$query->innerJoin("n.NewsVideoLinks as links WITH parent_entity = 'news'");
$query->innerJoin("links.Videos as vids WITH child_entity = 'videos'");
$results = $query->execute();
如您所见,这非常麻烦。我强烈建议为每个关系创建连接表。通过加入每个连接表,您仍然可以获得所需的内容。
【讨论】:
【参考方案2】:Doctrine 的documentation 相当不错。我不太清楚你所说的“灵活”是什么意思,但这里是 Doctrine 版本 1.2 的 Many-To-Many 关系的 yaml 配置示例。
---
User:
columns:
id:
type: integer(4)
autoincrement: true
primary: true
username:
type: string(255)
password:
type: string(255)
attributes:
export: all
validate: true
Group:
tableName: group_table
columns:
id:
type: integer(4)
autoincrement: true
primary: true
name:
type: string(255)
relations:
Users:
foreignAlias: Groups
class: User
refClass: GroupUser
GroupUser:
columns:
group_id:
type: integer(4)
primary: true
user_id:
type: integer(4)
primary: true
relations:
Group:
foreignAlias: GroupUsers
User:
foreignAlias: GroupUsers
【讨论】:
这是一个简单的多对多。我想要做的是一个表与许多表的关系,就像发布的示例一样。 您可以这样做,但您会失去外键约束的优势,并且必须自己强制执行数据完整性。我不认为教义支持这样的东西,我建议使用传统的多对多表。【参考方案3】:如果我正确理解您的数据库布局,“parent_entity”和“child_entity”代表您希望将 id 链接到的表。
这是“技术上”不正确的数据库结构(请参阅database normalization),因为您无法将这些列映射到任何其他 single 表列。基本上,您不能使用您的 id现在列,因为它不明确。
我认为您必须重新考虑您的数据库逻辑,然后才能更轻松地编写代码。
【讨论】:
以上是关于教义中的多对多关系的主要内容,如果未能解决你的问题,请参考以下文章