如何設計表格 - 涉獵問題
我可以理解這是一個基本問題,但這與知識(我認為)無關,而與實踐經驗有關。
我來自另一個領域,所以請善待。
我有我的訂單
每個訂單都有項目
每個項目都有他的變體
每個變體都有他的數量
當我需要儲存訂單的內容時,我的第一反應是創建一個包含商品、變體和數量的數組,然後將其轉換為字元串,最後將其儲存為 ORDERS 表的欄位。
我能聞到有什麼不對勁。
訂單中的項目可以是表格,VARIANTS 和 QUANTITY 也可以。在我看來,這似乎是解決問題的一種更整潔的方法。
但是,當我必須使用第一種方法重建 ORDER 時,這非常容易,我只需要將字元串轉換為原始 3D 數組,而第二種方法我必須查看 3 個不同的表,這不是我感覺舒服,主要是因為看起來工作量很大,而且如果只有幾個請求,這很容易,但是如果我當時有1000個使用者,我擔心DBMS無法應對工作量。
我用 MySQL 嘗試了一些基本的查詢,我所有的擔心似乎都過分了,但我不知道事情在實際工作應用程序中是如何工作的。
我很高興知道專業人士如何解決這個問題。在生產中,您會使用奇怪的串聯還是單獨的表(並且數據庫始終保持穩定和響應)?
所以 Akina 給了你一些 MySQL 程式碼來自己創建表,這很有幫助,你應該看看以了解結構。但這裡有一些資訊可以為您提供背景資訊,並希望通過給您提供視角來緩解您的擔憂。
雖然您目前將所有資訊儲存在一個對像中的方法似乎更容易,但它也有很多缺點,這就是關係數據庫管理系統 ( RDBMS ) 的目的所在。
首先,當您需要使用RDBMS詢問複雜的數據問題而不是詢問單個單體對象的相同問題時,該過程更簡單且更重要的是性能。這些問題的範例是:“在 2019 年銷售了多少個帶有變體 2 的商品 A 和帶有變體 7 的商品 C 的訂單? ”、“在過去的 6 個月中,銷售量最低的 3 個變體及其商品是什麼? ” ,“什麼變體及其項目在夏季的平均訂單數? ”,“去年從項目 D 的所有變體加上項目 E 的變體 1 和 2 的訂單中獲得的總利潤是多少? ”。
上述任何問題都可能要求您編寫需要掃描整體對象所有實例的整個數據集的程式碼,但在RDBMS中,數據點通過它們的關係解耦,您可以編寫只尋找回答上述問題所需的確切數據點(當架構和索引正確時)。
此外,您對“ 1,000 個使用者”同時使用RDBMS的擔憂其實並不可怕。實際上,與使用數據庫系統相比,與目前使用的單個整體對象相比,您會遇到更多的並發問題。這是因為當您只需要將所有數據寫入一個對象時,該對像被鎖定的總時間比在將數據寫入表的時間被拆分(並且可以並行化)的數據庫系統中更長,因此相對而言,任何給定的數據表都被單獨鎖定的時間要短得多。
在數據庫系統中,通過數據的關係解耦數據的美妙之處在於數據的性能和管理。我之前曾使用過半大數據(具有 10 億行的表),並且嘗試在單體對像中管理它是不可持續的,並且由於多種原因絕對不具有性能。甚至可以將您上面提到的表進一步解耦以提高性能並減少數據冗餘,例如擁有一個
Orders
表和一個OrderLines
表,假設您可以Item
在單個Order
.雖然您可能認為重建原始
Order
數據更困難,因為數據存在於三個表中而不是一個對像中,但實際上非常簡單:SELECT TheFieldsYouWant FROM Orders INNER JOIN Items ON Orders.ItemKeyField = Items.KeyField INNER JOIN Variants ON Items.VariantKeyField = Variant.KeyField
從字面上看,四行程式碼可以
Order
根據需要為您提供原始對象(可能比操作字元串數組的程式碼行更少;)。這只是習慣語法和關係邏輯的問題。但同樣,使用數據庫系統的三個好處是:
- 靈活性——通過解耦您的數據點,您可以根據需要以有效的方式查詢它們
- 性能 - 通過減少數據冗餘、提高並發性(寫入和讀取並發性)以及通過索引輔助僅查找您需要的確切數據點而不是掃描整個數據集
- 更簡單的程式碼 - 如上所示,但再次只是需要習慣它是一個新概念