使用 27 列(20 列相同)規範未優化 SKU 表的最佳實踐
這是一次怎樣的學習經歷。
一開始對 SQL 規範化或數據庫技術一無所知。隨著時間的推移,我開始看到試圖維護一個越來越大的數據庫的陷阱。
它是這樣開始的:新工作是一家通過各種渠道(亞馬遜、ebay 等)完成大部分銷售的電子商務企業,正在努力維護庫存系統。
由於列表中存在 SKU 結構,並且某些列表會在一個列表中捆綁多達 20 個 SKU,因此市場上的任何選項都不適合他們!
我真的不知道該做什麼,只是想設計一個可行的系統,我創建了一個 MySQL 數據庫,其中包含一個名為
MasterSKU
CREATE TABLE `MasterSKU` ( `id` int(11) NOT NULL AUTO_INCREMENT, `SKU` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `AltSKU` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `QtySKU` int(11) NOT NULL DEFAULT '1', `MultSKU` tinyint(1) NOT NULL DEFAULT '0', `SKU_1` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `SKU_2` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `SKU_3` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `SKU_4` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `SKU_5` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `SKU_6` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `SKU_7` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `SKU_8` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `SKU_9` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `SKU_10` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `SKU_11` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `SKU_12` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `SKU_13` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `SKU_14` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `SKU_15` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `SKU_16` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `SKU_17` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `SKU_18` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `SKU_19` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `SKU_20` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `processed` tinyint(1) NOT NULL DEFAULT '0', `comments` mediumtext COLLATE utf8_unicode_ci, PRIMARY KEY (`id`), UNIQUE KEY `SKU` (`SKU`) ) ENGINE=InnoDB AUTO_INCREMENT=8901 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
看起來完美優化,對吧?
我創作時的邏輯是這樣的。
SKU
表示列表中的 SKU(不是庫存 SKU 本身)。AltSKU
適用於僅附有一個庫存 SKU 的(普通)商品。在這裡,我輸入了實際的庫存 SKU。-QtySKU
用於Listing中有大宗(或多於一個)數量的listing(例如X SKU的10件T卹,數據庫需要知道這個listing應該扣除10個)。-MultSKU
是預設值0
,但如果一個列表附加了多個庫存 SKU,就像大多數捆綁列表一樣,我設置為 1,因此我的腳本知道查看SKU_1
—- >SKU_20
以查找附加的 SKU到列表。processed
是另一個預設值0
,我有一個腳本可以執行並插入和搜尋要放入MasterSKU
表中的新列表。如果它設置為0
,我知道我沒有附加任何 SKU 並且需要盡快讓庫存系統開始扣除。comments
只是我的個人評論,我可以刪除這個沒問題,可能應該在我做出這個重大改變之前,我想要一些優化技巧/策略來讓事情變得正確。我目前的主要問題是,由於這個表正在增長,我的查詢變得越來越慢,因為它必須搜尋 20
SKU_x
- 到SKU_xx
列,然後根據這些進行扣除,這使得它很痛苦並減慢了伺服器相當。確定一個我可以組合
SKU_1
,,SKU_2
…SKU_3
所有 20 列,直到SKU_20
.. 讓我們稱之為mSKUs
。突然出現在我腦海中的想法……轉換“MultSKU” - 即,
SKU_1
通過SKU_20
列中的 json 格式mSKUs
。或者只是在 SKU 之間添加一個分隔符,因此此列將包含 likeInventory SKU #1|Inventory SKU #2|Inventory SKU #3
等。我傾向於第二個,但也許我應該先讀一本書哈哈,因為我的想法是可行的,但從長遠來看並不是真正可持續的。json 替代方案似乎沒問題,但是我想到了連接這些數據庫的所有 PHP 腳本,並且不得不解碼和重新編碼可能更令人頭疼,我假設它們被編碼時性能會變慢。
而已。那是我的凌亂凌亂的桌子。
關於該表可以或應該如何標準化以提高性能的任何想法/第一想法/傾向?
非常感謝!
創建第二個表來儲存與單個 MasterSKU 相關的 SKU。
就像是:
CREATE TABLE `MasterSKU` ( `id` int(11) NOT NULL AUTO_INCREMENT, `SKU` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `processed` tinyint(1) NOT NULL DEFAULT '0', `comments` mediumtext COLLATE utf8_unicode_ci, PRIMARY KEY (`id`), UNIQUE KEY `SKU` (`SKU`) ) ENGINE=InnoDB AUTO_INCREMENT=8901 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; CREATE TABLE `ChildSKU` ( `id` int(11) NOT NULL AUTO_INCREMENT, `MasterSKUid` int(11) NOT NULL, INDEX MasterSKU_ind (MasterSKUid), FOREIGN KEY (`MasterSKUid`) REFERENCES MasterSKU(id), `SKU` varchar(255) COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`id`), ) ENGINE=InnoDB AUTO_INCREMENT=8901 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
插入數據如下所示:
INSERT INTO `MasterSKU` (`SKU`, `processed`, `comments`) VALUES ("1", 0, "test master sku"); INSERT INTO `ChildSKU` (`MasterSKUid`, `SKU`) VALUES (8901, "2"); INSERT INTO `ChildSKU` (`MasterSKUid`, `SKU`) VALUES (8901, "3"); INSERT INTO `ChildSKU` (`MasterSKUid`, `SKU`) VALUES (8901, "4");
查詢表如下所示:
SELECT mk.SKU , mk.processed , mk.comments , ck.SKU AS "Child SKU" FROM `MasterSKU` mk INNER JOIN `ChildSKU` ck ON mk.id = ck.MasterSKUid ORDER BY mk.id, ck.id;
| 貨號 | 加工 | 評論 | 兒童 SKU | |-----|-----------|-----------------|-----------| | 1 | 假 | 測試大師sku | 2 | | 1 | 假 | 測試大師sku | 3 | | 1 | 假 | 測試大師sku | 4 |
從上面可以看出,每個主 SKU 可以有任意數量的子 SKU。這是關係數據庫管理系統的基本原則之一,因為它只允許插入
ChildSKU
具有有效引用行的行MasterSKU
;稱為參照完整性。可以通過列向
ChildSKU
表中添加其他列,以表示每個子 SKU 的屬性,例如它是AltSKU
、 還是QtySKU
等SKUtype
。我將把它作為練習留給讀者。