我不是在詢問索引和分區,而是詢問有關選擇的問題,在添加大號數據之間。或者將數據添加爲行。 說明:我們目前有一個設計要求,用於處理多個屬性及其某些特定產品的值 產品可能會達到1億條記錄,並且每個產品可能具有多個屬性,因此ProductProperties的表可能會達到數十億。 有些人認爲將屬性添加爲ProductProperties表中的屬性,屬性1和值1,屬性2和值2等。 如果產品不包含該屬性的值,則該屬性的相關字段將爲空。此外,他們將添加約80-100屬性,以便能夠動態地覆蓋各種屬性。 建築師拒絕這種方法,因爲這不是一個好設計。 任何人都可以告訴我如何達到良好的設計加上良好的性能。 謝謝具有大型數據集的數據庫性能
回答
我會創建兩個表:Product
和ProductProperties
。
Product
將包含單個產品的基本屬性。那種東西,需要和項目,如name
,weight
,selling_quantity
等
ProductProperties
將包含一切之間常見。規範化屬性的屬性,命名它們並創建你的表。所有你需要的是FK到Product
,你準備好了。如果大多數屬性都爲空(我懷疑每個產品都需要80-100個屬性,但我不知道您列出的產品是什麼類型),那麼表之間的1:n關係要好得多, 。
我在使用數十億行時沒有任何第一手經驗,但數據庫應該規範化,而不是用空列填充。這個答案似乎支持我的想法:Optimal database structure - 'wider' table with empty fields or greater number of tables?
我覺得你的第一個問題出現時,你的ProductProperties
表有更多的行比unsigned bigint
可以處理。這可能需要一段時間,我希望...
這個問題出現在一些僞裝。就你而言,似乎你有一系列產品,其中每一種產品都可能有不同的屬性。我認爲你需要一種可擴展的方式來存儲這些屬性,以便你可以將新產品添加到系統中。
方法1:在該行+補充的元數據的通用領域
你建議,可以稍微修改了第一種方法通過標準化的產品屬性的元數據到它自己的表:
使用一些通用字段(代碼1,代碼2,IntVal1,IntVal2,FloatVal1 ...)構建產品表格
構建父級子引用的補充集表格
ProductType
和ProductAttribute
(或某些類似)可以指導產品表上哪些列包含哪些屬性。構建功能來將其解釋爲應用程序的數據訪問層。
這樣做的主要優點是結構的查詢效率高。缺點是product
表的內容在沒有補充元數據的情況下是不透明的。然而,其他方法的低效率和複雜性通常大大超過了這個缺點。
如果不同產品類型的數量相對較少,您還可以使用元數據生成視圖或解釋元數據的產品表上的一系列視圖。這可以緩解很多不透明的問題。
另一個優點是,對產品有多個過濾條件的查詢不必針對非常大的子表執行多個連接。如果表中的單個字段爲空,則每個字段的開銷(通常爲每列一個字節,具體取決於平臺)。未使用的字段會浪費記錄中的空間。
方法2:實體屬性值
這通常建議作爲解決這一類的問題。在這種情況下,您有Product
和ProductAttribute
表與子產品關係中的某些參考數據,這些參考數據根據產品類型過濾產品屬性類型。
這種方法看起來在概念上是優雅的並且是可擴展的,但是查詢和佔用相當多的磁盤空間是煩瑣和低效的。一些數據庫設計的黑客可以在各種平臺上使用,以緩解性能問題。你還沒有指定你正在使用的DBMS平臺,所以很難指出你正確的方向。主要優勢和EAV結構的缺點是:
,靈活度極高,而無需更改數據庫schena(+)
低效和繁瑣的查詢,特別是如果你想通過多個屬性過濾( - )
更多的磁盤空間使用情況。 ( - )
除非您有令人信服的要求,否則不建議使用EAV結構。
方法3:XML領域
套用弗雷德裏克Lundh開發:'now you have two problems'。 XML字段是無限可擴展的 - 您可以將任何想要的東西放入它們中,但對於除應用程序之外的任何東西都是不透明的,而且它們查詢速度慢並且很費勁。從SQL查詢中的XML字段中獲取數據要比存儲在列上的數據更有效。
通常,在數據庫中使用XML字段來存儲非固有的XML文檔是一個壞主意。很多人都寫過關於在數據庫中濫用XML字段的非智慧。我個人對構建ETL過程以從XML領域提取數據的經驗使我同意。最好避免,除非你有一個令人信服的理由。
結論
方法1是類似於你最初提出的,但移動列元伸到自己的結構。儘管它看起來並不高雅,但它幾乎在所有情況下都是最好的選擇。
擁有超過80個產品屬性的表格真的很有效率嗎?第一種方法是否表明我誤解了你的解釋?現在我很難應付這樣一個事實,即需要80多個物業。也許應該將產品組織成組,並向DB添加一些表格,以便產品組A使用來自一個表格的屬性和來自另一個表格的組B。 – 2012-04-15 17:37:16
@ ZZ-bb如果您有80個可爲空的列,則開銷通常爲每行80位或80個字節,具體取決於物理實現。如果您將其摺疊到使用外部元數據設置的通用列,則該值將更小。一個EAV結構要求你多次加入一個大的子表,以獲得所有的屬性,而對這種類型的結構的複雜搜索可能效率很低。 – ConcernedOfTunbridgeWells 2012-04-15 17:44:45
感謝您的信息。希望@Hossam可以判斷產品分組是否有助於進一步最小化空字段。如果您擁有數百萬種產品,很難想象分組/標準化不是一種選擇。我希望Hossam沒有一個有數百個指甲的產品表,唯一不同的是它們有多長或多長(但其中每一個都是獨特的產品)... – 2012-04-15 17:53:45
現有的答案是正確的,非常好。這是一個新的想法:顯然,將設計分成兩個表格(Products,ProductAttributeValues)是最正常和最正確的方法。
但是,性能可以超過建築的純度。重要的唯一設計目標是將總體解決方案的成本降至最低。沒有其他數字。如果非規範化模式提高了性能,以至於可以在其他地方節省性能,或者降低硬件成本,那麼這是正確的。 只有TCO很重要。那很簡單。
非規範化,如果它保存了你即使長期工作,或者它在硬件上保存。
總的來說,我同意但你如何確定TCO是主觀的。今天,在要求已知的情況下,可能會使數據不規範化,從而降低TCO。但是在9個月內需求增加了20個,而且如果我們開始使用規範化的數據,那麼該解決方案的TCO成本要高出很多......您是否計劃未來或者不是?是關於您現在知道的或您未來預期的投資回報率?但我會離開對其他討論離開@ConcernedOfTunbridgeWells。 – xQbert 2012-04-15 21:17:15
您可以在無限的未來優化預期的TCO,並且您可以預見它。這就是我們偏向主觀性的地方......對於任何一種解決方案都沒有硬性的論據。你期望有人回答「總是做X」嗎?答案是:這取決於。你需要估計你期望發生的事情。 – usr 2012-04-15 21:19:25
- 1. 大型數據庫的mysqldbcopy的性能
- 2. jqgrid具有大型本地數據集
- 3. 使用大型數據庫/數據集
- 4. 批量導入大型數據集時的數據庫性能建議
- 5. 大型數據集上的SQL數據庫查詢性能圖表?
- 6. 大行數據庫性能
- 7. 數據庫性能和數據類型
- 8. 未能將大型數據集加載到h2數據庫中
- 9. 具有小數據的大型MySQL數據庫
- 10. 在具有大型3D點數據集的SELECT查詢中提高性能
- 11. 大型數據集
- 12. 與大型數據庫集成的Chatbot
- 13. 具有數百個請求的大型SQL數據集
- 14. Neo4j大數據集的性能
- 15. 大型數據庫
- 16. javascript/html5大型數據集圖表庫
- 17. 彈性搜索:在大型數據集上性能較差
- 18. 從sql server中的大型數據集中篩選數據的性能調整
- 19. 用於大型數據集的MySQL數據庫建模
- 20. 用於大型數據集的嵌入式Java數據庫
- 21. 從Python中的Sqlite數據庫顯示大型數據集wx
- 22. 在大型數據集上的MySQL中的IFNULL的性能
- 23. 淘汰賽+大數據集性能
- 24. 具有每個用戶唯一的大數據集的MySQL關係數據庫
- 25. 與大型數據集的視圖與索引表的性能
- 26. 測試數據庫性能工具?
- 27. LINQ和有類型和無類型數據集的性能?
- 28. Linq與大型數據集的實體性能問題
- 29. 大型數據集上的ODP.Net存儲過程性能問題
- 30. 將大型元素/數據集附加到dom的性能
鑑於給定產品具有M種特性可能性的所有產品的特性的N個可能性;通用數據庫設計將表明,隨着時間的推移,屬性的數量可能會發生變化,行將是合乎邏輯的選擇;因爲它不需要隨着時間的推移而改變結構。 – xQbert 2012-04-15 16:05:52
@Hossam - 您可能想考慮在[dba.se](http://dba.stackexchange.com/)[[這不僅僅是針對數據庫管理員]](http://dba.stackexchange。 COM /常見問題)和標記這個MODS遷移。像這樣的問題往往會迷失在SO上的噪音中,並經常得到不正確的答案。 – ConcernedOfTunbridgeWells 2012-04-15 18:20:39