Roe*_*and 16 php mysql orm doctrine doctrine-orm
首先让我概述一下这个场景.我有一个Note对象,可以分配给许多不同的对象
我想象数据库看起来像:
书
id | title | pages
1 | harry potter | 200
2 | game of thrones | 500
Run Code Online (Sandbox Code Playgroud)
图片
id | full | thumb
2 | image.jpg | image-thumb.jpg
Run Code Online (Sandbox Code Playgroud)
地址
id | street | city
1 | 123 street | denver
2 | central ave | tampa
Run Code Online (Sandbox Code Playgroud)
注意
id | object_id | object_type | content | date
1 | 1 | image | "lovely pic" | 2015-02-10
2 | 1 | image | "red tint" | 2015-02-30
3 | 1 | address | "invalid" | 2015-01-05
4 | 2 | book | "boobies" | 2014-09-06
5 | 1 | book | "prettygood" | 2016-05-05
Run Code Online (Sandbox Code Playgroud)
问题是,我如何在Doctrine中对此进行建模.我读到的关于单表继承的讨论,没有一对多的关系.
要注意(没有双关语;),您可能会注意到音符永远不需要基于与其相关的对象的唯一属性.
理想情况下,我可以做$address->getNotes()返回相同类型的Note对象$image->getNotes().
至少我要解决的问题是避免使用三个不同的表:image_notes,book_notes和address_notes.
这个问题给应用程序带来了不必要的复杂性。仅仅因为音符具有相同的结构并不意味着它们是相同的实体。在 3NF 中对数据库建模时,它们不是同一个实体,因为注释不能从 Book 移动到 Address。在您的描述中,book 和 book_note 等之间存在明确的父子关系,因此对其进行建模。
更多的表对数据库来说不是问题,但不必要的代码复杂性是,正如这个问题所展示的那样。这只是为了聪明而聪明。这是 ORM 的问题,人们停止进行完全规范化并且没有正确建模数据库。
就我个人而言,我不会在这里使用超类。认为有更多的情况可以通过,和实现接口:BookImageAddress
interface iNotable
{
public function getNotes();
}
Run Code Online (Sandbox Code Playgroud)
这里以书为例:
class Book implements iNotable {
/**
* @OneToMany(targetEntity="Note", mappedBy="book")
**/
protected $notes;
// ...
public function getNotes()
{
return $this->notes;
}
}
Run Code Online (Sandbox Code Playgroud)
Note然后需要@ManyToOne相反的关系,只有其中一个适用于每个实体实例:
class Note {
/**
* @ManyToOne(targetEntity="Book", inversedBy="notes")
* @JoinColumn
**/
protected $book;
/**
* @ManyToOne(targetEntity="Image", inversedBy="notes")
* @JoinColumn
**/
protected $image;
/**
* @ManyToOne(targetEntity="Address", inversedBy="notes")
* @JoinColumn
**/
protected $address;
// ...
}
Run Code Online (Sandbox Code Playgroud)
如果您不喜欢此处对每个值得注意的类的多个引用,您可以使用继承并拥有类似AbstractNotable使用单表继承的超类之类的东西。虽然这现在看起来更整洁,但我不推荐它的原因是,随着数据模型的增长,您可能需要引入类似的模式,最终可能使继承树变得难以管理。
编辑:让验证器通过检查为每个实例设置的,或Note之一来确保数据完整性也很有用。像这样的东西:$book$image$address
/**
* @PrePersist @PreUpdate
*/
public function validate()
{
$refCount = is_null($book) ? 0 : 1;
$refCount += is_null($image) ? 0 : 1;
$refCount += is_null($address) ? 0 : 1;
if ($refCount != 1) {
throw new ValidateException("Note references are not set correctly");
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2334 次 |
| 最近记录: |