如題,正在做一個商城項目。比如一個商品是手機,它有版本 內存 容量 等等。那麼另一件商品是衣服,它有尺碼 顏色 等等。這就是不同的商品它又不同的參數。那麼資料庫該怎麼設計?

想了好幾天,就是想不到解決方案。求助


Web後端程序猿一枚,剛好做過商城項目,簡單分享一下。

在閱讀以下內容之前,首先你要對MySQL有基礎,對Table的一對多關係,多對多關係有一定了解。

一、MySQL可視化工具

為了便於後面的理解,你需要一套資料庫設計工具。簡單來說就是畫草圖的工具。類似思維導導圖。有助於你理解資料庫之間的關係,我用的是Navicat Data Modeler

Navicat Data Modeler

官網下載,免費試用,有了工具之後。如圖所示,這個工具能直觀顯示多表之間的對應關係。在開發過程中,有助於你更快了解多表之間的一對多,多對多關係。使用這個工具需要一定的學習時間,鑒於大部分人可能沒這麼多時間,作為前期,也可一簡單的自己手動花個類似的草圖。


二、SPU與SKU

2-1,了解SPU與SKU的概念。

  • SPU = Standard Product Unit (標準產品單位)
  • SKU = Stock Keeping Unit(庫存量單位)

SPU是商品信息聚合的最小單位,是一組可復用、易檢索的標準化信息的集合,該集合描述了一個產品的特性。

SKU是指一款商品,每款SPU最少都有出現一個SKU,便於電商品牌識別商品。

舉個栗子:

iPhone Xs:這是一個標準產品單位,即SPU

IPhone Xs 金色 256G:這是庫存量單位,即使SKU

已經具體到所有該款產品的所有配置信息了。

2-2,SPU與SKU的實例展示

舉個常見的商城SPU和SKU實例展示:

我們新建一張goods 表。裡面記錄所有SPU信息,

注意裡面只記錄SPU信息,比如:iPhone Xs,iPhone Xs Max,iPhone XR等。裡面沒有涉及任何具體配置方面的信息

再建一張SKU,裡面具體到SPU所有產品具體配置的具體ID,但不包括配置信息

比如說我我們現在有這些產品,

iPhone Xs,256,銀色,ID為1

iPhone Xs,256,金色,ID為2

iPhone Xs,120,銀色,ID為3....等等

這些數據裡面,我只記錄ID,其他比如:iPhone 型號,顏色,內存,我都不記錄。這些數據由後面的兩張表來記錄。

SPU表和SKU表並不直接關聯,還需要通過另外三張張表來關鍵,即通過間接的關係來進行關聯,為了便於理解,暫定為規格表,和規格選項表, SKU規格信息表

一張是SPU規格表,比如說,iPhone Xs,有兩個規格種類可以確定一個具體配置的iPhone ,以京東為例子,就是【顏色】和【內存版本】。

把SPU規格表,設置一個外鍵為SPU的主鍵。

那麼我們可以通過SPU的主鍵查詢到SPU的規格有哪些。

再新建一個規格選項表。

比如說,顏色。有金色銀色。

版本有,64,256,如圖。

同樣,把規格選項表,關鍵到SPU規格表。

就能獲取到SPU的規格,和具體的選項。再把SKU關聯到規格選項表。這樣就能把SPU,SKU關聯起來了。這裡只是兩一個大致思路。公司保密,不然可以拿我當時的設計圖來講一下。

算了,直接從我以前學習的視頻裡面截圖一張吧。能看懂最好。

這圖改改欄位就能用。我公司用的也就按這個設計來的

手機碼字,給個贊吧?

第二次更

怕一些童鞋看不清圖示,簡單講解一下

這幾張表中間的連接線上面意思

表裡面會有各種各樣多對多,一對多的關係。

十字的一端表示,一的一方

分叉端表示,多的一方。

這樣更好理解,

雖然SPU和SKU 有一對多的關係,但是我們不能直接從SPU的具體配置找到對應的SKU產品

所以,我們從SPU-------&>找到SPU相應的商品規格-------&>獲取到具體規格的具體選項------&>確定到唯一的對應SKU

這個流程


三、案例總結

當你看到上面案例,基本上也能總結出這樣一幅圖表對應關係

這樣是不是能夠通過SPU憑藉---&>規格表---&>規格選項表-----&>SKU規格信息表----&>找到對應的具體的SKU_ID?

練習:從SKU_ID三中,填入對應的sku配置信息--&>規格選項信息--&>規格信息

第三更,給個贊吧,畫圖表關係真累。。。

裡面SKU 表裡面還應該對應一個SPU_id的關係忘了畫了。。。


有幾種典型的做法,具體怎麼做看情況吧。

  1. 就是用大寬表,每次需要一個新列就加,但總是nullable的。這樣不同類型的記錄,代碼要自己記得取哪些列。好處是編碼簡單;壞處是,每次都要加列,做DDL很煩,如果是生產庫,運維上會很鬱悶,而且直接看錶,不太容易分清楚哪個列是給哪個類型的記錄預備的,必須另外單獨記錄文檔。
  2. 表上增加一個json列(比如叫properties)每個類型數據特有的屬性都塞這個json列里。在不直接支持json的db上,只能用varchar,然後業務代碼自己解析這個json。如果在支持json的db上(比如mysql &> 5.7.10),就稍微方便點,可以用json_extract之類的函數。此外一些ORM工具對json支持的不是很好,於是這個json到了object里就是string,需要額外處理。提一句mybatis通過掛一個type handler可以解決,還算容易。此方法的缺點是開發人員要管住json的schema,自己確保數據的合法性。
  3. 將共性的欄位放在一個主表裡(比如product),此外給每種類型建立一個子表(xxx_product_part)維護特有的欄位。這樣結構比較清晰,但是每次查詢需要引入join。每次增加一種新的類型的時候也要增加對應的新表。
  4. 用主表 + 屬性表。屬性表就是一個大的kv(pid, key, value)。但問題是value的類型會很麻煩,畢竟可能需要字元串,整數,decimal,日期,時刻,enum等不同的類型。所以要不就是服務得自己搞這個解析轉換工作,這時表就得定義為(pid, key, value_type, value_data);要不就是挨個類型定義一列,上層自己取(pid, key, value_int, value_varchar, value_decimal, ...)
  5. 每種產品直接建立新表(xxx_product, yyy_product, ...) 但這麼干基本上就是在埋坑, 沒人會這麼干吧。

如果經常增加產品的類型,可能方法2或者4會比較適合,避免每次都創建新列/新表。並且會比較靈活(但管不好就會亂套)。

如果產品類型增加的不是很頻繁,方法1或者3會比較適合。


公有欄位放主表,特殊欄位放子表,根據類型查子表。


我以前看過使用MongoDB來建模的,天然的schemeless,欄位索引可以靈活添加。但是這也意味著沒有了數據一致性的約束。

我建議嘗試關係資料庫+NoSQL的混合模式,關係資料庫里存放每個商品的主鍵,做到一致性外鍵約束,在NoSQL里存放具體的商品的數據。


1、json支持比較好的庫用 json (productid,jsonprops)

2、量不多用擴展表(pid,name,value)

3、用緩存同2

4、類別固定 (pid,prop1,prop2).。。


推薦閱讀:
相关文章