EAV 是否 適合在對像上收集並存的豐富元數據的“事實估計”?
我正在嘗試建構一個系統,該系統將收集對許多 (300K+) 對像中的每一個的各種數量 (10+) 的估計,並根據這些估計的歷史記錄做出決策。例如,我們有許多人工和自動化流程,它們可能試圖確定對象的 PowerLevel,並且當它們報告可能(或可能不會)相互取代的結果時,我們希望跟踪這些報告,以及來自流程的元數據(日期、調整參數、程式碼版本等)。具體來說,我們可能想要執行諸如“按實體 id 分組,對於每個不同的屬性,查找最新估計”或“查找其屬性具有由程式碼庫 573ae4 執行的任何更新的所有實體”之類的查詢。
作為從未在生產中實際使用過實體屬性值模式的人,這似乎是 EAV 之類的完美案例,為源添加了額外的元數據列。具體來說,我想像這樣的表:
entity_id | attribute_id | string_value | numeric_value | datetime_value | discovery_time | discovery_source | discovery_tuning_parameters | discovery_code_hash
但是我聽到了很多對這些類型模式的批評,比如這個 answer。我很難找到在非傳統系統上使用 EAV 的人,這讓我非常猶豫,我可能正在重新發明一個非常過時的輪子……
另一方面,我能想到的唯一其他選擇是完整的 NoSQL (bleh) 或一些邪惡的混合體,例如:
id | power | power_current_discovery_date | power_current_discovery_source | power_history (an array of hstores?) | foobar | foobar_current_discovery_date | ...
因為我們需要每個屬性的元數據。
有什麼想法嗎?這是 EAV 非常適合的少數幾次之一?謝謝你的幫助!
EAV 不是邪惡的;像任何其他工具一樣,它可能實施不佳並被濫用。您可以找到垃圾談話游標、動態 SQL、觸發器,甚至 SQL Server 本身的文章。這並不會使他們成為壞事。
EAV 可能是一個合適的解決方案。在您的具體情況下,它是否是正確的答案可能比任何事情都更基於意見;我的回答更多是為了建議您不要因為有人說它不好而對解決方案閉上思緒。總是有相反的觀點需要考慮:
我有一個用於跟踪伺服器/數據庫配置的 EAV。非常適合獲取數據*。我們可以向它拋出任何數據,載入器確保“E”和“A”反映給定的數據。然而,一旦我們在 Values 表中獲得了超過幾億行,獲取數據就會*變得越來越困難。(我認為返回 100K 行的 400 列 PIVOT 查詢與此有很大關係。)
總的來說,我相信我們做出了正確的選擇。只需很少的規範,我們就能在幾週內啟動一個功能係統並提供可行的見解。現在我們的需求、報告、臨時負載和案例已經解決,我們正在將數據複製到“規範化”表以滿足互動需求。不過,我不想擺脫 EAV 部分——它太有用了!
順便說一句,如果一組 INSERT 不包含所有屬性的值,那麼您的“前滾”查詢,即給我每個屬性的最新值,無論我何時收集該值,也會很昂貴。