多对多、一对多或多对一

Posted

技术标签:

【中文标题】多对多、一对多或多对一【英文标题】:Many to Many, One to Many or Many to One 【发布时间】:2014-10-25 18:34:15 【问题描述】:

我试图了解 Doctrine 2 ORM 关系,我以为我已经掌握了窍门,但在阅读了一些 symfony 食谱条目后,我怀疑我实际上有点困惑。

我目前有一个系统,其中一个模板可以包含多个模块(每种类型包括多个模块),并且多个模板可以使用同一个模块。

我认为这将保证多对多关系,并且确实看着我的桌子,它似乎工作得很好。

但是,当我编写数据库查询时,我意识到我需要以特定顺序加载模块,这意味着我的连接表需要有第三个“order_by”列。我读过一个真正的连接表只有两列。

因此混乱。我应该在我的实体中进行什么设置?

【问题讨论】:

【参考方案1】:

就像@Kris 所说的那样——你会选择一对多的中间实体。如果您选择多对多,那么您将没有中间表的类文件,这在大多数情况下是一个问题。

M-N 假设: 一个学生学习多门课程,一门课程可以有许多学生。

以下两个示例都在数据库中为您提供了此 ERD,但您希望选择 ONE to MANY 版本。

多对多:

这将在数据库中创建 StudentCourse 实体,但您看不到实际的类文件供您处理。

class Student

    protected $id;
    protected $name;

    /**
     * @ORM\ManyToMany(targetEntity="Course")
     * @ORM\JoinTable(
     * name="StudentCourse",
     * joinColumns=@ORM\JoinColumn(name="studentId", referencedColumnName="id"),
     * inverseJoinColumns=@ORM\JoinColumn(name="courseId", referencedColumnName="id")
     * )
     */
    private $course;


class Course

    protected $id;
    protected $name;

一对多:

这将在数据库中创建StudentCourse 实体,如您所见,在编码时有一个实际的类文件供您处理,例如persist() 等。

class Student

    protected $id;
    protected $name;

    /**
     * @ORM\OneToMany(targetEntity="StudentCourse", mappedBy="studentMap",
     * cascade="persist", "remove")
     */
    protected $studentInverse;


class StudentCourse

    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="Course", inversedBy="courseInverse")
     * @ORM\JoinColumn(name="course", referencedColumnName="id",
     * nullable=false, onDelete="CASCADE")
     */
    protected $courseMap;

    /**
     * @ORM\ManyToOne(targetEntity="Student", inversedBy="studentInverse")
     * @ORM\JoinColumn(name="student", referencedColumnName="id",
     * nullable=false, onDelete="CASCADE")
     */
    protected $studentMap;


class Course

    protected $id;
    protected $name;

    /**
     * @ORM\OneToMany(targetEntity="StudentCourse", mappedBy="courseMap",
     * cascade="persist", "remove")
     */
    protected $courseInverse;

编辑: onDelete="CASCADE"cascade="persist", "remove" 位不是强制性的。他们处理数据冗余。 Is it bad to use redundant relationships?

【讨论】:

哇谢谢你解释得这么清楚!这非常有帮助。 没问题。您可能已经知道,但我只是在 EDIT 下添加了一条注释。 好的,我已经进行了这些更改,并且数据库本身似乎设置正确。然而,我的装置似乎不再快乐了。当我尝试加载它们时,我收到了我添加到问题底部的错误。 您介意打开一个新问题并在此处发布链接,因为这是一个新问题。我有解决方案,但无法发表评论。 在这里:***.com/questions/26575174/… :)【参考方案2】:

你需要一个 OneToMany/ManyToOne 如果您不需要保存订单,那将是多对多,但既然您这样做了,那么不幸的是,该中间表现在必须是它自己的实体。 所以你需要以下实体

模板

使用 OneToMany 到

TemplateModules(这个名字可能更好)

使用多对一来

模块

【讨论】:

这是有道理的。非常感谢。

以上是关于多对多、一对多或多对一的主要内容,如果未能解决你的问题,请参考以下文章

思考具有两个外键的一对多或多对多关系的正确方法是啥?

数据库设计 - 多对多或一对多“交易”系统?

连接空间连接与关联

关联查询 一对多,多对一,多对多,自关联

MyBatis一对多,多对一,多对多

mybatis 一对一 一对多 多对多