天天看點

商城-商品規格管理-SPU和SKU資料結構3.SPU和SKU資料結構

商城-商品規格管理-SPU和SKU資料結構

  • 3.SPU和SKU資料結構
    • 3.1.SPU表
      • 3.1.1.表結構
      • 3.1.2.spu中的規格參數
        • 3.1.2.1.specifications字段
        • 3.1.2.2.spec_template字段
    • 3.2.SKU表
      • 3.2.1.表結構
      • 3.2.2.sku中的特有規格參數
        • 3.2.2.1.indexes字段
        • 3.2.2.2.own_spec字段
    • 3.3.導入圖檔資訊

3.SPU和SKU資料結構

規格确定以後,就可以添加商品了,先看下資料庫表

3.1.SPU表

3.1.1.表結構

SPU表:

CREATE TABLE `tb_spu` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'spu id',
  `title` varchar(255) NOT NULL DEFAULT '' COMMENT '标題',
  `sub_title` varchar(255) DEFAULT '' COMMENT '子标題',
  `cid1` bigint(20) NOT NULL COMMENT '1級類目id',
  `cid2` bigint(20) NOT NULL COMMENT '2級類目id',
  `cid3` bigint(20) NOT NULL COMMENT '3級類目id',
  `brand_id` bigint(20) NOT NULL COMMENT '商品所屬品牌id',
  `saleable` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否上架,0下架,1上架',
  `valid` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否有效,0已删除,1有效',
  `create_time` datetime DEFAULT NULL COMMENT '添加時間',
  `last_update_time` datetime DEFAULT NULL COMMENT '最後修改時間',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=208 DEFAULT CHARSET=utf8 COMMENT='spu表,該表描述的是一個抽象的商品,比如 iphone8';
           

與我們前面分析的基本類似,但是似乎少了一些字段,比如商品描述。

我們做了表的垂直拆分,将SPU的詳情放到了另一張表:tb_spu_detail

CREATE TABLE `tb_spu_detail` (
  `spu_id` bigint(20) NOT NULL,
  `description` text COMMENT '商品描述資訊',
  `specifications` varchar(3000) NOT NULL DEFAULT '' COMMENT '全部規格參數資料',
  `spec_template` varchar(1000) NOT NULL COMMENT '特有規格參數及可選值資訊,json格式',
  `packing_list` varchar(1000) DEFAULT '' COMMENT '包裝清單',
  `after_service` varchar(1000) DEFAULT '' COMMENT '售後服務',
  PRIMARY KEY (`spu_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

           

這張表中的資料都比較大,為了不影響主表的查詢效率我們拆分出這張表。

需要注意的是這兩個字段:specifications和spec_template。

3.1.2.spu中的規格參數

前面講過規格參數與商品分類綁定,一個分類下的所有SPU具有類似的規格參數。SPU下的SKU可能會有不同的規格參數,是以我們計劃是這樣:

  • SPU中儲存全局的規格參數資訊。
  • SKU中儲存特有規格參數。

以手機為例,品牌、作業系統等肯定是全局屬性,記憶體、顔色等肯定是特有屬性。

當你确定了一個SPU,比如小米的:紅米4X

全局屬性舉例:

品牌:小米
型号:紅米4X
           

特有屬性舉例:

顔色:[香槟金, 櫻花粉, 磨砂黑]
記憶體:[2G, 3G]
機身存儲:[16GB, 32GB]
           

來看下我們的 表如何存儲這些資訊:

3.1.2.1.specifications字段

首先是specifications,其中儲存全部規格參數資訊,是以也是一個json格式:

整體來看:
商城-商品規格管理-SPU和SKU資料結構3.SPU和SKU資料結構

整體看上去與規格參數表中的資料一樣,也是一個數組,并且分組,每組下有多個參數

展開一組來看
商城-商品規格管理-SPU和SKU資料結構3.SPU和SKU資料結構

可以看到,與規格參數表中的模闆相比,最大的差別就是,這裡指定了具體的值,因為商品确定了,其參數值肯定也确定了。

特有屬性

剛才看到的是全局屬性,那麼特有屬性在這個字段中如何存儲呢?

商城-商品規格管理-SPU和SKU資料結構3.SPU和SKU資料結構

我們發現特有屬性也是有的,但是,注意看這裡是不确定具體值的,因為特有屬性隻有在SKU中才能确定。這裡隻是儲存了options,所有SKU屬性的可選項。

在哪裡會用到這個字段的值呢,商品詳情頁的規格參數資訊中:

商城-商品規格管理-SPU和SKU資料結構3.SPU和SKU資料結構

3.1.2.2.spec_template字段

既然specifications已經包含了所有的規格參數,那麼為什麼又多出了一個spec_template呢?

裡面又有哪些内容呢?

來看資料格式:

商城-商品規格管理-SPU和SKU資料結構3.SPU和SKU資料結構

可以看出,裡面隻儲存了規格參數中的特有屬性,而且格式進行了大大的簡化,隻有屬性的key,和待選項。

為什麼要備援儲存一份?

因為很多場景下我們隻需要查詢特有規格屬性,如果放在一起,每次查詢再去分離比較麻煩。

比如,商品詳情頁展示可選的規格參數時:

商城-商品規格管理-SPU和SKU資料結構3.SPU和SKU資料結構

3.2.SKU表

3.2.1.表結構

CREATE TABLE `tb_sku` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'sku id',
  `spu_id` bigint(20) NOT NULL COMMENT 'spu id',
  `title` varchar(255) NOT NULL COMMENT '商品标題',
  `images` varchar(1000) DEFAULT '' COMMENT '商品的圖檔,多個圖檔以‘,’分割',
  `price` bigint(15) NOT NULL DEFAULT '0' COMMENT '銷售價格,機關為分',
  `indexes` varchar(100) COMMENT '特有規格屬性在spu屬性模闆中的對應下标組合',
  `own_spec` varchar(1000) COMMENT 'sku的特有規格參數,json格式,反序列化時應使用linkedHashMap,保證有序',
  `enable` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否有效,0無效,1有效',
  `create_time` datetime NOT NULL COMMENT '添加時間',
  `last_update_time` datetime NOT NULL COMMENT '最後修改時間',
  PRIMARY KEY (`id`),
  KEY `key_spu_id` (`spu_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='sku表,該表表示具體的商品實體,如黑色的64GB的iphone 8';
           

還有一張表,代表庫存:

CREATE TABLE `tb_stock` (
  `sku_id` bigint(20) NOT NULL COMMENT '庫存對應的商品sku id',
  `seckill_stock` int(9) DEFAULT '0' COMMENT '可秒殺庫存',
  `seckill_total` int(9) DEFAULT '0' COMMENT '秒殺總數量',
  `stock` int(9) NOT NULL COMMENT '庫存數量',
  PRIMARY KEY (`sku_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='庫存表,代表庫存,秒殺庫存等資訊';
           

問題:為什麼要将庫存獨立一張表?

因為庫存字段寫頻率較高,而SKU的其它字段以讀為主,是以我們将兩張表分離,讀寫不會幹擾。

特别需要注意的是sku表中的

indexes

字段和

own_spec

字段。sku中應該儲存特有規格參數的值,就在這兩個字段中。

3.2.2.sku中的特有規格參數

3.2.2.1.indexes字段

在SPU表中,已經對特有規格參數及可選項進行了儲存,結構如下:

{
    "機身顔色": [
        "香槟金",
        "櫻花粉",
        "磨砂黑"
    ],
    "記憶體": [
        "2GB",
        "3GB"
    ],
    "機身存儲": [
        "16GB",
        "32GB"
    ]
}
           

這些特有屬性如果排列組合,會産生12個不同的SKU,而不同的SKU,其屬性就是上面備選項中的一個。

比如:

  • 紅米4X,香槟金,2GB記憶體,16GB存儲
  • 紅米4X,磨砂黑,2GB記憶體,32GB存儲

你會發現,每一個屬性值,對應于SPUoptions數組的一個選項,如果我們記錄下角标,就是這樣:

  • 紅米4X,0,0,0
  • 紅米4X,2,0,1

既然如此,我們是不是可以将不同角标串聯起來,作為SPU下不同SKU的标示。這就是我們的indexes字段。

商城-商品規格管理-SPU和SKU資料結構3.SPU和SKU資料結構

這個設計在商品詳情頁會特别有用:

商城-商品規格管理-SPU和SKU資料結構3.SPU和SKU資料結構

當使用者點選選中一個特有屬性,你就能根據 角标快速定位到sku。

3.2.2.2.own_spec字段

看結構:

儲存的是特有屬性的鍵值對。

SPU中儲存的是可選項,但不确定具體的值,而SKU中的儲存的就是具體的鍵值對了。

這樣,在頁面展示規格參數資訊時,就可以根據key來擷取值,用于顯示。

3.3.導入圖檔資訊

現在商品表中雖然有資料,但是所有的圖檔資訊都是無法通路的,我們需要把圖檔導入到虛拟機:

首先,把課前資料提供的資料上傳到虛拟機下:

/leyou/static

目錄:

商城-商品規格管理-SPU和SKU資料結構3.SPU和SKU資料結構

然後,使用指令解壓縮:

unzip images.zip
           

修改Nginx配置,使nginx反向代理這些圖檔位址:

vim /opt/nginx/config/nginx.conf
           

修改成如下配置:

server {
    listen       80;
    server_name  image.leyou.com;

    # 監聽域名中帶有group的,交給FastDFS子產品處理
    location ~/group([0-9])/ {
        ngx_fastdfs_module;
    }
    # 将其它圖檔代理指向本地的/leyou/static目錄
    location / {
        root   /leyou/static/;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }

}
           

繼續閱讀