我计划创建我的应用程序并为模型使用ORM,但问题是,数据库的一部分使用了实体 - 属性 - 值表。
我非常喜欢Doctrine ORM,但我不知道是否有可能创建类似于任何普通教义实体的类,当表实际连接到EAV风格时。
是否可以在此使用Doctrine,如果可以,如何使用?
答案 0 :(得分:4)
绝对可能:
拥有这样的关系: 对象(一对多) - > AttributeValue - >多对一 - >属性类型
答案 1 :(得分:0)
鉴于EAV,如何使用学说建立entity
和attribute
之间的关系似乎很明显。在最复杂的情况下,我们处理Many to Many关系。
因此,我们想要将属性Name
映射到实体User
。假设用户只有一个名称,并且每个名称只属于一个用户,则可以使用One to One关系存档此链接
但是如何建模attribute
和value
之间的关系?问题是值可以是不同类型,甚至需要不同数量的字段以保存其信息。
考虑属性name
和phone_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。每个子类(即Name
和PhoneNumber
)都会按特定值扩展这些常用值,例如其他字段。
@DiscriminatorColumn
定义父关系中的一列,用于存储值的类型。@DiscriminatorMap
将类型从@DiscriminatorColumn
映射到其中一个类。可以为父类指定attribute
和value
之间的关系。从属性调用值然后将获取所有类型的值,这些值可以在运行时使用例如instanceof进行过滤(和处理)。