Mysql

使用 27 列(20 列相同)規範未優化 SKU 表的最佳實踐

  • November 13, 2020

這是一次怎樣的學習經歷。

一開始對 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_2SKU_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、 還是QtySKUSKUtype。我將把它作為練習留給讀者。

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