Mysql

庫存系統中訂單表非規範化組的數據庫模式重新設計策略

  • July 12, 2019

作為我的第一個數據庫驅動和 SQL 驅動的程序,我或多或少地在執行中創建了這個,邊走邊學.. 試圖保持謹慎-但或多或少是為了簡單工作而創建的..很少對壽命、穩定性、可靠性、組織性——所有其他方面的遠見。

一個典型的例子是電子商務商店。眾多銷售渠道,在某些情況下,所述渠道上的眾多賬戶。

由此產生的是每個頻道的表格,如果頻道有多個帳戶,則每個帳戶都有一個表格。

訂單的目前表格設置

╔══════════════╦═════════════════════╦═════════════════════╦═════════════════════╗
║ AmazonOrders ║ eBayOrders_account1 ║ eBayOrders_account2 ║ eBayOrders_account3 ║
╚══════════════╩═════════════════════╩═════════════════════╩═════════════════════╝

實際上,來自不同帳戶的 eBayOrders 最多可使用 5 個不同的表。

不止於此。

在我的數據庫中有表用於..

╔═══════════════╦══════════════╦═══════════════╦═══════════════════╗
║ BonanzaOrders ║ NewEggOrders ║ ShopifyOrders ║ WooCommerceOrders ║
╚═══════════════╩══════════════╩═══════════════╩═══════════════════╝

老實說,這還不是全部,但這應該讓您了解它的設置方式。

為了深入研究,每個表都有大致相同的數據或列,或者至少有一個“基礎”用於我想要獲取並插入數據庫的數據。

例子:

CREATE TABLE `WooCommerceOrders` (
 `id` int(11) NOT NULL,
 `OrderID` int(11) DEFAULT NULL,
 `OrderLineItemID` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `BuyerEmail` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `Title` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `SKU` varchar(80) COLLATE utf8_unicode_ci DEFAULT NULL,
 `Quantity` int(11) NOT NULL,
 `TransactionPrice` decimal(6,2) DEFAULT NULL,
 `processed` tinyint(1) NOT NULL DEFAULT '0',
 `createdtime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

一個很好的對比是 eBay Store Table,根據要求,我添加了更多列來儲存數據,例如 eBay 特有的相關費用等。

CREATE TABLE `eBayOrders_account1` (
 `id` int(11) NOT NULL,
 `OrderLineItemID` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `SalesRecordNumber` int(11) DEFAULT NULL,
 `BuyerUserID` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `BuyerEmail` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `Title` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `SKU` varchar(80) COLLATE utf8_unicode_ci DEFAULT NULL,
 `Quantity` int(11) NOT NULL,
 `TransactionPrice` decimal(6,2) DEFAULT NULL,
 `FinalValueFee` decimal(6,2) DEFAULT NULL,
 `PayPalFee` decimal(6,2) DEFAULT NULL,
 `processed` tinyint(1) NOT NULL DEFAULT '0',
 `createdtime` datetime DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

快速分解..通常需要兩個訂單行來在表中設置唯一鍵約束以避免重複。背後的原因OrderID,這是WooCommerce 所稱OrderLineItemID的原始訂單的子訂單。OrderID

eBay 有一個他們用來分配訂單的術語,因此OrderLineItemIDSalesRecordNumber

唯一的異常值是我的 ShopifyOrders 表,該表中有三個訂單標識符。OrderID OrderLineIDOrderNumber

現在我不想把它寫成小說,但我真的在尋找關於如何最好地進行這個數據庫重新設計的建議。

我現在對關係表、規範化、外鍵關係等非常熟悉,至少是一般概念和一些實踐。

我的問題是,對於這樣的訂單和來源數據庫,什麼是可接受的架構?

我不應該將我所有的訂單表合併為一個,不是嗎?使用所有頻道的外鍵表,將它們連結在一起。我認為如果所有表的列數一致,這可能沒問題,但例如 Shopify 與三個訂單標識符,我認為如果我要合併表,我可能應該通過 Channel 這樣做?

意思是把我的 eBay 訂單組合成一個,並分配另一個表給它一個唯一的鍵來關聯——因為我所有的 eBay 表和列都是相同的。

第二個想法,我可能應該盡量使表格盡可能統一。這在現在看來相當明顯。讓一個表將一Price列表示為不同的術語,例如TransactionPrice,ItemPrice等等,似乎只會使事情複雜化。

eBay 訂單的 FinalValueFee、PayPalFee 等費用似乎最好在關係表中而不是表本身中提供。

還有其他提示或策略嗎?我仍然在學習,希望這是我對它的最後改革,讓它下來。

我對文章的主要好奇心和意圖是..我應該如何對錶格進行分組/合併?我在過去規範化技術方面的經驗會推斷我想將來自所有渠道的所有訂單放在一張表中,但是(我可能是錯的),出於組織和數據的原因,我認為這裡不是最好的服務-列不一致的原因。是否應該對 eBay 訂單表進行分組?還是我錯過了一些簡單的東西,應該以其他方式分解它?

在我深入研究並嘗試清理我以前的一些混亂之前,如何設計此模式以最好地為系統中的數據提供服務?

非常感謝,這對我來說是一項巨大的壯舉,可以嘗試正確,任何意見或提示 - 將不勝感激。

  • 一個“訂單”由多個“項目”組成,是嗎?好吧,不要把這兩種東西混在一張桌子上。
  • 同樣eBayOrders_account1似乎是orders,orderitemsusers的混搭payment
  • 一般來說,沒有多個“相同”的表。我猜這就是正在發生的事情eBayOrders_account*
  • TransactionPrice僅限於 9999.99,但Quantity可能高達 20 億。
  • price表中的ATransactions可以簡單地命名為price。表同上Items,但您可能同時需要 aUnitPriceTotalPrice,尤其是在有數量折扣的情況下。
  • 我看不到索引。他們是後來添加的嗎?
  • “亞馬遜”訂單和“eBay”訂單之間是否存在顯著差異?NULLable在一個Orders表中包含幾列以允許細微的差異並沒有什麼壞處。

咀嚼這些建議,然後用一組新的問題重新開始一個新的問題CREATE TABLEs,包括索引。這只是幾輪中的第一輪。

引用自:https://dba.stackexchange.com/questions/242711