構建一個電商通用型商品中心,可支援商品的種類和屬性繁多,可以售賣實物、虛擬、會員、服務類商品。每一種商品具有不同的規格,不同的規格的商品有多種價格,商品可支援多種貨幣的支付。
1)目的是什麼?
帶大家一起實現一個通用型商品中心,從中學到一些擴充套件性設計思想。
2)你能學到什麼?
3)不能學到什麼?
商品中心是電商各個系統的最基礎單元,為商城、訂單,優惠促銷、庫存、倉儲物流等系統提供基礎資料。
電商的基本術語。
參考下面的商品組成模組圖,商品模組的組成較為複雜,在定義SKU與SPU時,涉及類目、屬性、品牌、生產資訊等資料的組合,在定義出SKU後再建立SPU,在SPU上新增商品描述和規格最後就成了商品。根據商品又衍生出了價格管理、評論管理、搜尋篩選等模組。
商品類目分為兩層:基礎資料類目層(後臺類目)、前臺展示類目層(前臺類目)。那為什麼要將前、後臺類目分開管理,而不是前、後臺共用一套類目呢?
後臺類目面向商家或供應鏈人員,商品屬性、銷售屬性及品牌等很多資料都是在基礎類目上進行管理;
前臺類目面向使用者,方便使用者查詢商品,還可以隨著運營需要去調整。比如而且隨著節日、時令季節變化,運營會經常變更前臺類目。
後臺類目主要面向平臺運營人員或商家,用於管理商品、屬性和品牌等資料。
後臺類目相對固定,確定了之後不會輕易變更或刪除,如果類目下掛載有商品,就不能刪除或作廢。
類目樹的層次不能太深,一般三層或四層。如果太深,對於商品的管理不太方便。類目樹中最後一層類目稱為葉子類目,商品必須掛載於葉子類目下。
前臺類目主要面向使用者,方便使用者篩選查詢商品,如圖圖所示。
前臺類目可以根據運營需要,靈活多變。所以處理商品的前端類目時,就應該提供多樣化的前端類目來支援。
前臺類目可支援不同使用者端的設定。PC端、H5端、APP端等
前臺類目不同於固定的後臺類目,編輯很靈活、可重疊、可刪除、可隨時變動,定時生效。
CREATE TABLE `category` (
`id` bigint(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`name` varchar(32) NOT NULL COMMENT '類目名稱',
`parent_id` bigint(11) NOT NULL COMMENT '父id',
`leaf` tinyint(4) NOT NULL COMMENT '是否葉子節點 1是 0不是',
`level` tinyint(4) NOT NULL COMMENT '類目層級',
`path` varchar(128) DEFAULT NULL COMMENT '完整父級路徑:父父id_父id',
`sort` int(11) unsigned NOT NULL COMMENT '排序欄位',
`status` tinyint(4) NOT NULL COMMENT '分類狀態:1上架 2下架',
`del` tinyint(4) unsigned NOT NULL COMMENT '是否刪除',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新時間',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='類目表';
SKU算是電商中最基礎的概念,SKU是最小庫存單元。
以iPhone 8 Plus(SPU)為例,這個SPU的規格有多種(顏色包含金 色、白色、黑色、玫瑰金、銀色、亮黑、紅色等6種;記憶體包含32G、 128G、256G等3種),對應18(即3×6)種SKU。比如「iPhone 7 Plus白 色32G」、「iPhone 7 Plus黑色32G」這兩個SKU都能具化到實物。倉庫系統、採購系統、庫存系統等系統都是主要管理SKU。
CREATE TABLE `sku` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`sku_no` varchar(32) DEFAULT '' COMMENT '商品序列號',
`sku_name` varchar(50) DEFAULT NULL COMMENT '商品名稱',
`sku_description` varchar(256) DEFAULT NULL COMMENT '商品描述',
`sku_type` tinyint(4) DEFAULT NULL COMMENT '商品型別:1實物商品、2會員商品、3增值商品,4虛擬物品',
`status` tinyint(4) NOT NULL COMMENT '狀態 1未上架2.已上架 3.已下架',
`sort` int(10) DEFAULT '0' COMMENT '排序',
`boundle` tinyint(4) unsigned DEFAULT '0' COMMENT '是否組合商品 1是 0否',
`create_by` int(11) unsigned NOT NULL COMMENT '建立人ID',
`update_by` int(11) unsigned DEFAULT NULL COMMENT '修改人ID',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
`update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
PRIMARY KEY(`id`) USING BTREE,
UNIQUE KEY `uk_sku_no` (`sku_no`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8mb4 COMMENT = '商品表'
擴充套件性1:動態無限制建立屬性數量。
CREATE TABLE `sku_attr` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`sku_no` varchar(32) DEFAULT '' COMMENT '商品序列號',
`sku_attrs` json DEFAULT NULL COMMENT 'sku屬性(商品屬性)',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
`update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
PRIMARY KEY(`id`) USING BTREE,
UNIQUE KEY `uk_sku_no` (`sku_no`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8mb4 COMMENT = '商品屬性表'
不建立新欄位,還可以用sql查詢,你得到了什麼啟發?
擴充套件性2:根據不同類目載入不同屬性渲染動態表單。
將一組屬性掛載到類目來實現動態表單,你得到了什麼啟發?
CREATE TABLE `category_to_goods` (
`id` bigint(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`category_id` bigint(20) DEFAULT NULL COMMENT '類目id',
`goods_no` varchar(32) DEFAULT NULL COMMENT '商品編號',
`goods_type` tinyint(4) DEFAULT NULL COMMENT '商品型別:1sku、2spu',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '更新時間',
`is_deleted` tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT '是否刪除:0-否,1-是',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COMMENT='類目商品關聯表';
CREATE TABLE `bundle_to_sku` (
`id` bigint(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`goods_id` bigint(20) DEFAULT NULL COMMENT '商品id, 組合商品id',
`bundle_id` bigint(20) DEFAULT NULL COMMENT '組合商品id',
`quantity` int(11) DEFAULT NULL COMMENT '商品數量',
`entity_type` tinyint(4) DEFAULT '1' COMMENT '商品的型別:1sku,2組合商品',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '更新時間',
`is_deleted` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否刪除:0-否,1-是',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_bundle_to_goods_bundle_id_index` (`bundle_id`) USING BTREE,
KEY `idx_bundle_to_goods_object_id_entity_type_index` (`object_id`,`entity_type`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='套裝和sku關聯表||套裝和spu關聯表';
sku資料
為了方便商品管理,我們需要在系統中建立一套屬性庫。在定義一個屬性時,需要掛載在類目下,區分屬性分類(關鍵屬性、銷售屬性、非關鍵屬性、特殊屬性),並確定屬性值、顯示型別(單選、多選、可自定義)、是否必填。
CREATE TABLE `attribute` (
`id` bigint(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`name` varchar(32) NOT NULL DEFAULT '' COMMENT '屬性名稱',
`code` varchar(32) DEFAULT NULL COMMENT '屬性程式碼(非必填)',
`attr_type` tinyint(4) NOT NULL COMMENT '屬性應用:1商品屬性,2銷售屬性,3特殊屬性',
`value_type` tinyint(4) DEFAULT NULL COMMENT '屬性值型別:1:字串,2:數位',
`fill_type` tinyint(4) NOT NULL COMMENT '填寫型別:1填寫型(字元),2填寫型(僅整數數位),3選擇型(單選值,非id)4選擇型(多選值,非id),5多輸入框展示型',
`is_filter` tinyint(4) unsigned NOT NULL COMMENT '是否支援前臺篩選:0否 1是',
`status` tinyint(11) NOT NULL COMMENT '狀態:1 未上架 2已上架 3已下架',
`is_deleted` tinyint(4) unsigned NOT NULL COMMENT '是否刪除',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改時間',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COMMENT='屬性表';
CREATE TABLE `attribute_enum` (
`id` bigint(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`attr_id` bigint(20) NOT NULL COMMENT '屬性id',
`attr_code` varchar(32) DEFAULT NULL,
`enum_code` bigint(11) DEFAULT NULL COMMENT 'enumcode',
`enum_value` varchar(32) NOT NULL COMMENT '屬性列舉值名稱',
`sort` int(11) NOT NULL COMMENT '排序',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新時間',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='屬性列舉表';
CREATE TABLE `category_to_attr` (
`id` bigint(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`category_id` bigint(11) NOT NULL COMMENT '分類id',
`attr_id` bigint(20) NOT NULL COMMENT '屬性id',
`is_required` tinyint(4) unsigned NOT NULL COMMENT '是否必填',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新時間',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='分類屬性關聯表';
當屬性庫搭建完成後,就會被各個葉子類目呼叫,新增商品時就需要填寫這些屬性,商品就有了載體,如圖所示。
根據這些屬性便能確定商品的唯一性(SKU)。 淘寶的商品屬性(類目「男裝」→「風衣」) 特別需要注意的是一些規格屬性(如顏色、尺碼等)。很多產品有 多規格,例如衣服、鞋子等。以一雙男鞋為例,有顏色(假設白、紅、 黑3種顏色),有尺碼(從39~44共6種尺碼),那麼這個SPU(男鞋) 下面就有18個SKU。這些SKU的屬性除了規格屬性外,其他屬性都是一 致的,所以在新建商品時,可聚合到一起,共用其他屬性。
SPU 是標準化產品單元。SPU與SKU的關係有許多種,可以一對多、一對一, 絕大部分SPU與SKU都是一對一,多規格的SPU和SKU之間是通過規格屬性來連線的。SPU的庫存是由其對應的SKU庫存共同決定的。
以iPhone 11(SPU)為例,這個SPU的規格有多種(顏色包含白色、黑色、黃金、紫色、綠色、紅色等6種;記憶體包含32G、 128G、256G等3種),對應18(即3×6)種SKU。比如「iPhone 11 白色 64G」、「iPhone 11 黑色 64G」這兩個SKU都能具化到實物。倉庫系統、採購系統、庫存系統等系統都是主要管理SKU。 在日常運營中也很常見一個SKU對應多個SPU。
CREATE TABLE `spu` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`name` varchar(64) DEFAULT NULL COMMENT 'spu名稱',
`detail` varchar(256) DEFAULT NULL COMMENT '商品介紹',
`status` tinyint(4) DEFAULT NULL COMMENT '狀態 1未上架2.已上架 2.已下架',
`spu_specs` json DEFAULT NULL COMMENT '商品規格',
`creator_id` bigint(20) DEFAULT NULL COMMENT '建立者',
`is_deleted` tinyint(1) unsigned DEFAULT '0' COMMENT '是否刪除,0:未刪除 1:已刪除',
`sort` int(10) DEFAULT '0' COMMENT '排序',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '更新時間',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='spu';
sku屬性資料
spu表單圖片
CREATE TABLE `spu_to_sku` (
`id` bigint(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`sku_no` varchar(32) NOT NULL DEFAULT '' COMMENT 'sku id',
`spu_no` varchar(32) NOT NULL DEFAULT '' COMMENT 'spu id',
`is_deleted` tinyint(1) DEFAULT '0' COMMENT '是否刪除,0:未刪除 1:已刪除',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '更新時間',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_spu_to_sku` (`spu_no`,`sku_no`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COMMENT='spu商品關聯表';
價格包括:成本價、原價、售賣價、定金、膨脹金等會隨著需求的不斷增加,尤其是一些線上教育等垂直行業電商對金額會有各種玩法。
CREATE TABLE `sku_price` (
`id` bigint(11) NOT NULL AUTO_INCREMENT,
`sku_id` bigint(11) unsigned NOT NULL COMMENT '商品id',
`sku_no` varchar(20) NOT NULL DEFAULT '' COMMENT '商品編號',
`sku_type` tinyint(4) NOT NULL COMMENT '商品型別: 1單sku 2組合sku',
`sub_goods` tinyint(4) NOT NULL COMMENT '是否子商品:0否1是',
`bundle_id` bigint(20) DEFAULT NULL COMMENT '組合商品id 預設 空',
`price` decimal(10, 2) NOT NULL COMMENT '價格',
`price_type` varchar(32) NOT NULL COMMENT '價格型別列舉(1.商品原價REAL_PRICE 2.售賣價SELL_PRICE 3.售賣底價... )',
`currency_type` tinyint(4) NOT NULL DEFAULT '1' COMMENT '貨幣型別:1人民幣 2虛擬幣',
`enable` tinyint(4) unsigned DEFAULT '1' COMMENT '是否啟用 0 不啟用 1 啟用',
`create_by` int(11) unsigned NOT NULL COMMENT '建立人ID',
`update_by` int(11) unsigned DEFAULT NULL COMMENT '修改人ID',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
`update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_sku_id` (`sku_id`) USING BTREE,
KEY `idx_sku_no` (`sku_no`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8mb4 COMMENT = '商品價格表' "
擴充套件性3:不建立新欄位,同一個商品可支援多種價格和貨幣種類
本文詳細介紹了商品中心設計擴充套件性設計思想,並在設計方面做了各維度分析。
擴充套件性總結如下:
動態無限制建立屬性數量。
根據不同類目載入不同屬性渲染動態表單。
不建立新欄位,同一個商品可支援多種價格和貨幣種類。
希望自己總結的擴充套件性思想可以讓大家在開發過程中有所啟發。