EAV表上的Doctrine ORM

时间:2013-01-02 14:40:06

标签: php orm doctrine entity-attribute-value

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

我非常喜欢Doctrine ORM,但我不知道是否有可能创建类似于任何普通教义实体的类,当表实际连接到EAV风格时。

是否可以在此使用Doctrine,如果可以,如何使用?

2 个答案:

答案 0 :(得分:4)

绝对可能:

拥有这样的关系: 对象(一对多) - > AttributeValue - >多对一 - >属性类型

答案 1 :(得分:0)

鉴于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进行过滤(和处理)。

相关问题