我們在之前的文章探討過很多[產品/訂單]的實作練習 :
這些資料表結構其實都很簡單,就是產品資料表、產品類別資料表、訂單表頭資料表、訂單表身資料表。但是在實際應用上,到了公司上班以後,當老闆叫你從後台撈資料做報表時,你會發現怎麼跟我在學校學的都不一樣呢?
就好像下面這幅漫畫描述的一樣 :
學生會抱怨「老師教的都是沒用的東西」,因為上班時會發現怎麼跟學校學的差這麼多?其實老師心裡想的是 : 「我教這麼簡單的內容,你都學不會了,我教企業現場應用的東西,不是自找麻煩嗎?」
現在,我們就來自找麻煩一下,看看許多中小企業在使用的 WordPress 平台下,使用 Woocommerce 電子商務的資料表是長什麼樣子?
我們將使用 InfinityFree 的免費平台安裝 WordPress 跟 Woocommerce ,安裝過程就不在這邊贅述,有空再另文說明。
從 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
wpdp_woocommerce_attribute_taxonomies
我們在商店頁面上,看到如下的商品資料放在哪些資料表呢 ?
價格 : 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
再去分類資料表查看,如下圖 :
如果要列出商品編號、商品名稱、價格、分類名稱,就可以使用以下的指令 :
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 留言