我打算創建我的應用程序,併爲這些模型使用ORM,但問題是,有一部分數據庫使用實體屬性值表。EAV表中的學說ORM
我非常喜歡Doctrine ORM,但我不知道是否有可能創建類似於任何普通教義實體的類,當這個表實際連接到EAV風格時。
對此可以使用Doctrine嗎?如果是這樣,怎麼辦?
我打算創建我的應用程序,併爲這些模型使用ORM,但問題是,有一部分數據庫使用實體屬性值表。EAV表中的學說ORM
我非常喜歡Doctrine ORM,但我不知道是否有可能創建類似於任何普通教義實體的類,當這個表實際連接到EAV風格時。
對此可以使用Doctrine嗎?如果是這樣,怎麼辦?
絕對有可能的:
有這樣的關係: 對象(一對多) - >的AttributeValue - >多對一 - >屬性類型
如果你想獲取某個屬性,你有其他表中的關係,那麼怎麼辦? – Nico
是的,這是個問題 - 幾乎可以肯定唯一的解決方案就是不得不在代碼中使用接口來獲取EAV屬性的屬性,不幸的是,增加了一層複雜性。 –
鑑於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進行過濾(並處理)。
開箱即用,我懷疑它。你可能會推出自己的實現。原則是相當可擴展的 – ZolaKt
由於表的關係根據一個值(根據其數據類型加入正確的屬性值表)是不可能的(據我所知),這應該是非常棘手的做到這一點使用Doctrine。 –