【问题标题】:Doctrine ORM on EAV TablesEAV 表上的学说 ORM
【发布时间】:2012-12-16 22:22:48
【问题描述】:

我正计划创建我的应用程序并为模型使用 ORM,但问题是,数据库的一部分使用实体-属性-值表。

我非常喜欢 Doctrine ORM,但我不知道当实际连接的表是 EAV 样式时,是否可以创建看起来像任何普通学说实体的类。

是否可以在这方面使用 Doctrine,如果可以,如何使用?

【问题讨论】:

  • 开箱即用,我对此表示怀疑。您可能会推出自己的实现。教义是相当可扩展的
  • 因为根据值的表关系(根据其数据类型加入正确的属性值表)是不可能的(据我所知),使用 Doctrine 做到这一点应该很棘手.

标签: php orm doctrine entity-attribute-value


【解决方案1】:

绝对有可能:

有这样的关系: 对象(一对多) -> AttributeValue -> 多对一 -> AttributeType

【讨论】:

  • 如果你想获取你在其他表中有关系的某个属性呢?
  • 是的,这就是问题所在 - 几乎可以肯定,唯一的解决方案是您必须在代码中使用接口来获取 EAV 属性的属性,不幸的是,这增加了一层复杂性。
【解决方案2】:

鉴于EAV,如何使用原则在entityattribute 之间建立关系似乎很明显。在最复杂的情​​况下,我们处理Many to Many 关系。

假设我们想要将属性Name 映射到实体User。假设一个用户只有一个名字并且每个名字都属于一个用户,这个链接可以使用One to One关系存档

但是如何建模attributevalue 之间的关系呢?问题是值可以是不同的类型,甚至需要不同数量的字段来保存它们的信息。

考虑属性namephone_number。虽然名称可能由字符串表示,但电话号码可能需要一个整数。或者甚至需要在一个单独的字段中,不仅是号码,而且还需要区号。

因为 EAV 需要非常灵活的值表示,所以不可能将它们全部存储在数据库表的同一字段中(忽略 blob、数据序列化等)。因此大多数 EAV 实现使用不同的表来表示不同的值类型。

为了达到这种灵活性,学说特征Inheritance Mapping。它基本上允许您扩展学说实体。这样做你为你的实体的每个子类型指定一个discriminator

/**
  * @Entity
  * @InheritanceType("JOINED")
  * @DiscriminatorColumn(name="value_type", type="string")
  * @DiscriminatorMap({"name" = "Name", "phone" = "PhoneNumber"})
*/
class Value
{
// ...
}

/** @Entity */
class Name extends Value
{
// ...
}

/** @Entity */
class PhoneNumber extends Value
{
// ...
}

Value 类为所有值提供通用实现,即 id。每个子类(即NamePhoneNumber)通过它们的特定值扩展这些公共值,例如附加字段。

  • @DiscriminatorColumn 定义了父关系中存储值类型的列。
  • 教义使用@DiscriminatorMap 将类型从@DiscriminatorColumn 映射到这些类之一。

attributevalue 之间的关系可以指定给父类。然后从属性调用值将获取所有类型的值,这些值可以在运行时使用例如instanceof 进行过滤(和处理)。

【讨论】:

  • 如果您需要 1000 个不同的属性,您必须编写 1000 个类?并且您的应用程序的用户无法添加新属性?
  • 例如,您将创建一个StingValue,以便用户可以添加string 类型的新值...当然,PhoneNumber 示例不是一个很好的示例。但这个概念是 EAV,而不是 Doctrine。
猜你喜欢
  • 1970-01-01
  • 2016-08-25
  • 1970-01-01
  • 1970-01-01
  • 2014-02-06
  • 1970-01-01
  • 2011-05-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多