WordPress 加上 Woocommerce,電子商務資料庫[商品資料表]研究

我們在之前的文章探討過很多[產品/訂單]的實作練習 : 

公司的產品資料與訂單 

B2B網站的資料流流向圖

這些資料表結構其實都很簡單,就是產品資料表、產品類別資料表、訂單表頭資料表、訂單表身資料表。但是在實際應用上,到了公司上班以後,當老闆叫你從後台撈資料做報表時,你會發現怎麼跟我在學校學的都不一樣呢?

就好像下面這幅漫畫描述的一樣 : 

學生會抱怨「老師教的都是沒用的東西」,因為上班時會發現怎麼跟學校學的差這麼多?

其實老師心裡想的是 : 「我教這麼簡單的內容,你都學不會了,我教企業現場應用的東西,不是自找麻煩嗎?」

現在,我們就來自找麻煩一下,看看許多中小企業在使用的 WordPress 平台下,使用 Woocommerce 電子商務的資料表是長什麼樣子? 

我們將使用 InfinityFree 的免費平台安裝 WordPressWoocommerce ,安裝過程就不在這邊贅述,有空再另文說明。

從 phpMyAdmin 管理介面可以看到 WordPress 與 Woocommerce 的一大堆資料表如下 : 

我們的目的不是要研究全部資料表,我們只把焦點放在跟 Woocommerce 有關的資料表上。

Woocommerce 由於要跟 WordPress 整合,所以很多資料會放在 WordPress 既有的資料表上,也會有自己專有的資料表。

以下的 WordPress 表單,Woocommerce 都會用到 : 
wpdp_commentmeta
wpdp_comments
wpdp_options
wpdp_postmeta
wpdp_posts
wpdp_termmeta
wpdp_terms
wpdp_term_relationships
wpdp_term_taxonomy
wpdp_users
wpdp_usermeta

以上前置詞 wpdp 可能在不同的環境下,可能會有不同。

而其他表單名稱上有 wc 或是 woocommerce 字樣,都是 Woocommerce 專有的資料表。

例如跟商品有關的 : 
wpdp_woocommerce_termmeta
wpdp_woocommerce_attribute_taxonomies

我們在商店頁面上,看到如下的商品資料放在哪些資料表呢 ? 



商品名稱 : Album
價格 : NT$15
商品描述 : This is a simple, virtual product.
分類 : music

我們在 wpdp_posts 資料表中看到 : 
ID : 26
post_title : Album
post_content : 描述商品內容
post_name : album
post_type : product
post_excerpt : This is a simple, virtual product.
post_status : publish

再從 wpdp_postmeta 抓出對應的資料 : 


看到 
meta_key 與 meta_value 這兩個欄位,_regular_price 對應資料是 15
meta_key 與 meta_value 這兩個欄位,_price 對應資料也是 15
這個就應該是訂價與售價。

我們在 wpdp_terms 資料表中看到 : 
term_id : 20
name : Music
slug : music

我們在 wpdp_term_taxonomy 資料表中看到 : 
term_id : 20
taxonomy : product_cat
count : 2 

我們在 wpdp_term_relationships 資料表中看到 : 
object_id:對應到產品的 ID(來自 wp_posts 表格)。 
term_taxonomy_id:對應到分類的 ID。

透過這個語法找到產品對應的分類 : 
SELECT * FROM `wpdp_term_relationships` WHERE object_id=26



產品編號為 26 的對應分類有兩個 : 2、20

再去分類資料表查看,如下圖 : 


產品編號為 26 的對應分類名稱就是 simple、Music,除了 simple 之外,還有 grouped (組合商品)、variable (變體商品)、external (外部/聯盟商品)。

如果要列出商品編號、商品名稱、價格、分類名稱,就可以使用以下的指令 :

SELECT
    p.ID AS 'Product ID',
    p.post_title AS 'Product Name',
    pm.meta_value AS 'Price',
    GROUP_CONCAT(DISTINCT t.name SEPARATOR ', ') AS 'Categories'
FROM
    wpdp_posts p
-- 1. 取得價格 (Price)
LEFT JOIN
    wpdp_postmeta pm ON p.ID = pm.post_id AND pm.meta_key = '_price'
-- 2. 取得分類關係 (Relationship)
LEFT JOIN
    wpdp_term_relationships tr ON p.ID = tr.object_id
-- 3. 過濾出分類法為 'product_cat' 的項目
LEFT JOIN
    wpdp_term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id AND tt.taxonomy = 'product_cat'
-- 4. 取得分類名稱 (Term Name)
LEFT JOIN
    wpdp_terms t ON tt.term_id = t.term_id
WHERE
    p.post_type = 'product'      -- 只找產品
    AND p.post_status = 'publish' -- 只找已發佈的
GROUP BY
    p.ID;

得到如下的結果 : 


如果要統計每個分類下到底有多少個商品,就可以使用以下的指令 :

SELECT
    t.term_id AS 'ID',
    t.name AS 'Category Name',
    t.slug AS 'Slug',
    COUNT(p.ID) AS 'Product Count'
FROM
    wpdp_terms t
INNER JOIN
    wpdp_term_taxonomy tt ON t.term_id = tt.term_id
INNER JOIN
    wpdp_term_relationships tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
INNER JOIN
    wpdp_posts p ON tr.object_id = p.ID
WHERE
    tt.taxonomy = 'product_cat'      -- 1. 指定為產品分類
    AND p.post_type = 'product'      -- 2. 指定為產品 (排除文章)
    AND p.post_status = 'publish'    -- 3. 只計算已上架 (排除草稿、回收桶)
GROUP BY
    t.term_id, t.name, t.slug
ORDER BY
    COUNT(p.ID) DESC;                -- 4. 數量多的排前面

得到如下的結果 : 


我們還可以找出以下的資料 : 

(1) 查詢「空分類」 (找出沒有商品的分類)

SELECT
    t.name AS 'Empty Category Name',
    t.slug,
    tt.count AS 'System Count'
FROM
    wpdp_terms t
INNER JOIN
    wpdp_term_taxonomy tt ON t.term_id = tt.term_id
WHERE
    tt.taxonomy = 'product_cat'
    AND tt.count = 0;

(2) 找出「沒有設定圖片」的產品

SELECT
    p.ID,
    p.post_title AS 'Product Name',
    p.post_status
FROM
    wpdp_posts p
LEFT JOIN
    wpdp_postmeta pm ON p.ID = pm.post_id AND pm.meta_key = '_thumbnail_id'
WHERE
    p.post_type = 'product'
    AND p.post_status = 'publish'
    AND pm.meta_value IS NULL;

(3) 查詢「庫存量」與「SKU」 (庫存盤點用)

SELECT
    p.ID,
    p.post_title AS 'Product Name',
    sku.meta_value AS 'SKU',
    stock_status.meta_value AS 'Status', -- instock, outofstock
    CAST(stock_qty.meta_value AS SIGNED) AS 'Quantity'
FROM
    wpdp_posts p
LEFT JOIN wpdp_postmeta sku ON p.ID = sku.post_id AND sku.meta_key = '_sku'
LEFT JOIN wpdp_postmeta stock_status ON p.ID = stock_status.post_id AND stock_status.meta_key = '_stock_status'
LEFT JOIN wpdp_postmeta stock_qty ON p.ID = stock_qty.post_id AND stock_qty.meta_key = '_stock'
WHERE
    p.post_type = 'product'
    AND p.post_status = 'publish';

(4) 找出「重量」缺失的商品 (避免運費計算錯誤)

SELECT
    p.ID,
    p.post_title
FROM
    wpdp_posts p
LEFT JOIN
    wpdp_postmeta pm ON p.ID = pm.post_id AND pm.meta_key = '_weight'
WHERE
    p.post_type = 'product'
    AND p.post_status = 'publish'
    AND (pm.meta_value IS NULL OR pm.meta_value = '');

我們就可以透過這樣的方式,逐步拆解 Woocommerce 電子商務資料庫表單的結構。

以上的商品資料表單的結構是不是跟簡單的 product/category 結構差很多呢? 

之所以要這麼複雜,除了要適應原本 WordPress 的表單之外,另外一個原因就是要能夠彈性的適應更多不同的需求。

例如,如果把產品分類結構寫死了,需要階層式的分類怎麼辦? 產品需要多種分類怎麼辦?

因此不要再說學校教的沒用了,學校教的是基礎,你自己必須靠著這些基礎去深入研究職場上會遇到的問題。因為今天企業會用 WordPress + Woocommerce ,也許未來又是另外一套東西。

後續我們再來仔細的拆解更多細節。

張貼留言

0 留言