P粉9304480302023-08-23 14:08:54
@StoneHeart
我會一直使用EAV和MVC。
@Bill Karvin
你在這裡提到的所有事情:
在我看來,這些都不應該出現在資料庫中,因為沒有任何資料庫能夠以適當的水平處理這些互動和要求,而應用程式的程式語言可以。
在我看來,以這種方式使用資料庫就像用石頭敲釘子。你可以用石頭做到,但你不應該使用更精確、專門為這種活動設計的錘子嗎?
可以透過對部分資料進行少量查詢並將其處理成表格佈局來解決這個問題。即使你有600GB的產品數據,如果你需要從這個表中取得每一行的數據,你也可以分批處理。
進一步說,如果你想提高查詢的效能,你可以選擇某些操作,例如報告或全域文字搜索,並準備索引表,儲存所需的數據,並定期重新生成,例如每30分鐘。
你甚至不需要擔心額外資料儲存的成本,因為它每天都在變得越來越便宜。
如果你仍然擔心應用程式執行的操作的效能,你始終可以使用Erlang、C 、Go語言預處理數據,然後在主應用程式中進一步處理優化後的數據。
P粉5049209922023-08-23 09:38:42
您至少有以下五種選項來建模您所描述的類型層次結構:
單表繼承:為所有產品類型使用一個表,具有足夠的欄位來儲存所有類型的所有屬性。這意味著每一行上有很多列,其中大多數在任何給定的行上都是NULL。
類別表繼承:為產品使用一個表,儲存所有產品類型的共同屬性。然後,為每個產品類型使用一個表,儲存特定於該產品類型的屬性。
具體表繼承:沒有用於共同產品屬性的表。相反,為每個產品類型使用一個表,儲存共同產品屬性和特定於產品的屬性。
序列化LOB:為產品使用一個表,儲存所有產品類型的共同屬性。一個額外的欄位儲存半結構化資料的BLOB,可以是XML、YAML、JSON或其他格式。這個BLOB允許您儲存每個產品類型特定的屬性。您可以使用複雜的設計模式來描述這個過程,例如Facade和Memento。但無論如何,您都有一個無法在SQL中輕鬆查詢的屬性BLOB,您必須將整個BLOB取回應用程式並在那裡進行排序。
實體-屬性-值:為產品使用一個表,以及一個將屬性旋轉到行而不是列的表。 EAV在關係範式方面不是一個有效的設計,但很多人仍然使用它。這是另一個答案中提到的「屬性模式」。在StackOverflow上查看帶有eav標籤的其他問題,以了解一些陷阱。
我在一個名為可擴展資料建模的演示中寫了更多關於這個的內容。
關於EAV的其他想法:雖然很多人似乎喜歡EAV,但我不喜歡。它似乎是最靈活的解決方案,因此是最好的。然而,請記住這句格言TANSTAAFL。以下是EAV的一些缺點:
NOT NULL
)。 JOIN
。 EAV提供的靈活性需要在其他方面做出犧牲,可能會使您的程式碼與以更傳統的方式解決原始問題的程式碼一樣複雜(或更糟)。
而且,在大多數情況下,擁有那種程度的靈活性是不必要的。在關於產品類型的問題中,為每個產品類型建立一個表格來儲存特定於產品的屬性會更簡單,這樣至少可以強制執行一些一致的結構,以適應相同產品類型的條目。
只有當每一行都允許具有不同的屬性集時,我才會使用EAV。當您有一組有限的產品類型時,EAV就過度了。類別表繼承將是我的首選。
2019年更新:我越來越看到人們將JSON作為「許多自訂屬性」問題的解決方案,我越不喜歡這個解決方案。即使使用特殊的JSON函數來支援它們,查詢也變得過於複雜。與儲存在常規行和列中相比,儲存JSON文件需要更多的儲存空間。
基本上,在關聯式資料庫中,這些解決方案都不容易或有效率。擁有「可變屬性」的整個概念與關係理論根本不一致。
歸根結底,您必須根據對資料的查詢方式選擇其中一種解決方案,這是基於對您的應用程式來說最不糟糕的解決方案。因此,在選擇資料庫設計之前,您需要知道如何查詢資料。沒有一種解決方案是「最佳」的,因為任何一種解決方案都可能是某個應用程式的最佳選擇。