電商訂單綜合小項目

1. 項目簡介

1.1業務背景介紹

  • 本案例圍繞某個互聯網小型電商的訂單業務來開發。某電商公司,每天都有一些的用戶會在線上採購商品,該電商公司想通過數據分析,查看每一天的電商經營情況。例如:電商公司的運營部門想要清楚的看到每天的訂單筆數、訂單的下單總額、不同支付類型對應的訂單筆數和總額等等。
  • 為了實現公司的數據分析業務,我們需要開發一套數據分析的系統以實現電商公司的需求

1.2電商的購物流程

  • 這裡就假設為京東購物舉例

 

 

從上圖可以看到,每一個用戶購買商品,都會瀏覽商品、提交訂單。所以商品、訂單是電商中非常重要的。業務將主要圍繞商品、訂單展開。

1.3電商系統的簡單介紹

 

 

  • 用戶打開瀏覽器,訪問電商頁面
  • 用戶按下回車後,瀏覽器發出請求,請求電商網站的Web伺服器
  • Web伺服器從資料庫取出數據,返回
  • 前端頁面展示數據

結論

數據是存放在資料庫中,我們開展數據分析只需要能夠獲取到資料庫中的數據即可

1.4電商的相關業務術語介紹

1. 我們去淘寶、京東上買的東西,就是一件件的商品。商品包含這些內容:

 

 

 

 

 

 

 

1. 商品的標題

 

 

2. 商品的所屬分類

 

 

3. 商品的價格

 

 

4. 商品的顏色

 

 

5. 商品的版本

 

 

6. 商品的介紹

 

1.4.2商品分類

  • 絕大多數的電商都有商品商品。每個商品一定是會屬於某個類別。例如:電冰箱屬於 家用電器 > 大家電 分類。不同的商品可能對應的分類是不一樣的。

 

 

 

 

 

 1.4.3訂單

  • 用戶購買商品是通過提交訂單來完成的。用戶每一次購物都會有訂單,訂單中包含了訂單號、收貨人、訂單狀態、支付方式、商品評價等。

 

 

 1.4.4 訂單詳情

  • 用戶可能在一次購買中,買了多個商品。訂單詳情指的是訂單走過來包含的具體資訊。例如:訂單中包含的商品資訊、商品金額、商品數量等。

 

 

 

1.4.5   用戶

  • 想要購買商品,需要先在電商網站上註冊用戶。用戶包含了很多資訊,例如:用戶名、密碼、性別、生日、以及手機、密碼等資訊。

 

 

 

 

1.4.6    區域

每個訂單都有區域的概念,例如:我們可以選擇配送到哪兒,是配置到北京市昌平區百善鎮還是其他地方。

 

 

1.5     技術方案介紹

本項目基於MySQL資料庫,使用Kettle、Apache Superset實現數據可視化。案例使用MySQL作為數據分析的存儲以及查詢引擎、以Kettle作為數據處理腳本執行工具、以及Apache Superset實現數據可視化展示。

案例的最終效果如下:

 

 2.項目架構說明

 

2.1  系統架構

 

 

2.2數據流程圖

 

 

  1.  通過Kettle將MySQL業務系統資料庫中,將數據抽取出來,然後裝載到MySQL數據倉庫中。
  2. 編寫SQL腳本,對MySQL數據倉庫中的數據進行數據分析(分組、聚合等),並將分析後的結果保存。
  3. 使用 Superset 將保存下來的分析結果以圖形的方式展示出來。

 

 

3.搭建項目環境

這裡是寫部落格步驟又不可以少所以

第一步

  1. 搭建虛擬機
  2. 安裝jdk
  3. 安裝MySQL8.0
  4. 安裝superset

有問題參考我部落格的安裝文檔

第二步

  1. 用SQLyog執行連接虛擬機的MySQL

 

 

 

 第三部

執行下面SQL腳本

 //files.cnblogs.com/files/it-wp/BI%E6%A1%88%E4%BE%8B%E6%95%B0%E6%8D%AE%E5%BA%93%E8%84%9A%E6%9C%AC.7z

創建兩個偽數倉

#ods層數據倉庫

create database if not exists ods_it_shop;
#APP層數據倉庫

create database if not exists it_shop_bi;

4.  項目開發

4.1     表結構概覽

表名

說明

it_areas

行政區域表,例如:北京市、昌平區等。

it_goods

 

商品表,保存了商品的基本資訊。例如:商品的唯一標識、商品的名稱、店鋪ID、商品的分類等。

it_goods_cats

 

商品分類表,每一個商品都有自己的分類。例如:海爾的某個冰箱屬於:家用電器 > 大家電 > 冰箱 這樣的一個分類。

it_orders

 

訂單表,用戶提交的訂單將保存在該表中。表中包含了:下訂單的用戶、訂單的狀態、訂單的支付金額、訂單所屬的區域、用戶所屬的地址等。

it_order_goods

 

訂單明細表,訂單明細表包含了訂單中的包含的商品資訊。用戶可以同時買多個商品,然後提交一個訂單。例如:提交的訂單中包含一個手機、和一個電冰箱。訂單明細中包含了用戶買的商品數據和訂單資訊。例如:該訂單明細對應的訂單是什麼、買了幾個這樣的商品、商品的ID是什麼等。

it_users

 

用戶資訊表,包含了用戶的ID、用戶名、密碼等資訊。

 

4.2     表欄位解釋

it_areas/行政區域表

列名

類型

說明

areaId

int(11)

區域ID

parentId

int(11)

父ID

areaName

varchar(100)

地區名稱

areaKey

char(10)

地區首字母

areaType

tinyint(4)

級別標誌1:省,2:市,3:縣區

createTime

varchar(25)

創建時間

it_goods/商品表

列名

類型

說明

goodsId

bigint(11)

商品id

goodsSn

varchar(20)

商品編號

goodsName

varchar(200)

商品名稱

goodsImg

varchar(150)

商品圖片

shopId

bigint(11)

門店ID

marketPrice

decimal(11,2)

市場價

shopPrice

decimal(11,2)

門店價

isHot

tinyint(4)

是否熱銷產品

goodsCatId

int(11)

goodsCatId

saleNum

int(11)

總銷售量

createTime

varchar(25)

創建時間

 

it_goods_cats/商品分類

列名

類型

說明

catId

int(11)

品類ID

parentId

int(11)

父ID

catName

varchar(20)

分類名稱

dataFlag

tinyint(4)

刪除標誌

createTime

varchar(25)

建立時間

cat_level

tinyint(4)

分類級別,共3級

 

it_orders/訂單表

列名

類型

說明

orderId

bigint(11)

訂單id

orderNo

varchar(20)

訂單編號

shopId

bigint(11)

門店id

userId

bigint(11)

用戶id

orderStatus

tinyint(4)

訂單狀態 -3:用戶拒收 -2:未付款的訂單 -1:用戶取消 0:

goodsMoney

decimal(11,2)

商品金額

deliverMoney

decimal(11,2)

運費

totalMoney

decimal(11,2)

訂單金額(包括運費)

realTotalMoney

decimal(11,2)

實際訂單金額(折扣後金額)

payType

tinyint(4)

支付方式,0:未知;1:支付寶,2:微信;3、現金;4、其他

isPay

tinyint(4)

是否支付

userName

varchar(20)

收件人姓名

userAddress

varchar(255)

收件人地址

userPhone

char(20)

收件人電話

createTime

varchar(25)

下單時間

noticeDeliver

tinyint(3) unsigned

提醒發貨 0:未提醒 1:已提醒

payTime

varchar(25)

支付時間

totalPayFee

int(11)

總支付金額

it_order_goods/訂單明細表

列名

類型

說明

ogId

bigint(11)

訂單明細ID

orderId

bigint(11)

訂單ID

goodsId

bigint(11)

商品ID

goodsNum

bigint(11)

商品數量

goodsPrice

decimal(13,0)

商品價格

payPrice

decimal(13,0)

實際支付價格

goodsName

varchar(600)

商品名稱

goodsImg

varchar(450)

商品圖片

createtime

varchar(75)

創建時間

it_users/用戶表

 

列名

類型

說明

userId

int(11)

用戶ID

loginName

varchar(20)

登錄名

loginSecret

int(11)

登錄秘鑰

loginPwd

varchar(50)

登錄密碼

userSex

tinyint(4)

用戶性別

userName

varchar(100)

用戶名

trueName

varchar(100)

用戶真實姓名

brithday

date

生日

userPhoto

varchar(200)

用戶照片

userQQ

varchar(20)

用戶QQ

userPhone

char(11)

用戶電話

userScore

int(11)

用戶積分

userTotalScore

int(11)

用戶總積分

userFrom

tinyint(4)

用戶來源

userMoney

decimal(11,2)

用戶現金

lockMoney

decimal(11,2)

賬戶現金

createTime

datetime

創建時間

payPwd

varchar(100)

支付密碼

rechargeMoney

decimal(11,2)

充值金額

4.3.1    數據抽取業務分析

我們已經大概熟悉了上面的6張表,這6張表有時候並不是將所有數據一次性原封不動地同步到數據倉庫中,而是有一些處理細節。考慮以下幾個可能出現的業務場景:

  1. 每一天都需要進行訂單的分析,例如:2021年2月2日一共有多少筆訂單、訂單的總額是多少。

  2. 每一天都需要進行用戶的分析,例如:2021年2月2日一共註冊有多少個用戶。

  3. 商品分類、區域的變化率很少,因為分類、區域幾乎都是常年不變的。

  4. 商品的數據相對變化頻率較高,因為可能每天都會有商品資訊的更新。

表名

說明

裝載表

抽取方式

抽取周期

it_areas

行政區域表

ods_it_areas

增量同步抽取

每年

it_goods

商品表

ods_it_goods

增量同步抽取

每天

it_goods_cats

商品分類表

ods_it_goods_cats

全量同步抽取

每周

it_orders

訂單表

ods_it_orders

增量同步抽取

每天

it_order_goods

訂單明細表

ods_it_order_goods

增量同步抽取

每天

it_users

用戶資訊表

ods_it_users

增量同步抽取

每天

  • 全量同步抽取:將所有數據同步抽取到數據倉庫
  • 增量同步抽取:只抽取新增的數據到數據倉庫

4.3.2    關於 ods 的意義

  • ODS(英語:Operational 業務/ Data 數據/ Store 存儲)是一種數據架構或資料庫設計的概念,出現原因是來自於當需要集成來自多個系統的數據,結果又要給一或多個系統使用時。
  • 數據倉庫的ods表是將業務系統資料庫表原樣抽取進來,結構幾乎是一樣的,只不過加了一個抽取數據的日期欄位。

4.3.3    每周數據抽取作業開發

4.3.3.1 開發行政區域數據抽取

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 資料庫配置就參考輸入

其他轉換配置參考上面

其他看板參考上面的看板

4.4.4.2   開發商品分類數據抽取

 

 

 4.3.3.3開發每周數據抽取作業

新建-作業-從通用裡面拖出組件-配置-連線

 

 

 其他作業參考這個

4.3.4.1    開發商品表數據抽取

 

 

 

4.3.4.2   開發訂單數據抽取

 

 

 

 

 

 

4.3.4.3    開發用戶資訊表抽取

 

 

 

4.4.2   創建用於保存數據分析結果的表

--創建APP層的資料庫
CREATE DATABASE `it_shop_bi`;
-- 訂單支付總額/總筆數分析
CREATE TABLE IF NOT EXISTS it_shop_bi.app_order_total(
  id INTEGER  PRIMARY KEY AUTO_INCREMENT,    -- 用作唯一記錄標識的組件,無實際意義
  dt DATE,                                    -- 對應的日期
  total_money DOUBLE,                       -- 總支付金額
  total_cnt INTEGER                          -- 總訂單筆數
);


SELECT
  SUBSTRING(t1.createTime, 1, 10) AS dt,  -- 某一天
  SUM(t1.realTotalMoney) AS total_money,  -- 訂單總金額
  COUNT(1) AS total_cnt                     -- 訂單總筆數
FROM
 ods_it_orders t1
WHERE
 SUBSTRING(t1.createTime, 1, 10) = '2019-09-05'
GROUP BY  SUBSTRING(t1.createTime, 1, 10);


USE `ods_it_shop`;
INSERT INTO it_shop_bi.app_order_total
SELECT
  NULL,
  SUBSTRING(t1.createTime, 1, 10) AS dt,  -- 某一天
  SUM(t1.realTotalMoney) AS total_money,  -- 訂單總金額
  COUNT(1) AS total_cnt                     -- 訂單總筆數
FROM
 ods_it_orders t1
WHERE
 SUBSTRING(t1.createTime, 1, 10) = '2019-09-05'
GROUP BY  SUBSTRING(t1.createTime, 1, 10);

USE ``;
-- 訂單用戶分析表
CREATE TABLE IF NOT EXISTS it_shop_bi.app_order_user(
  id INTEGER  PRIMARY KEY AUTO_INCREMENT,   -- 唯一標識
  dt DATE,                       -- 統計日期
  total_user_cnt INTEGER                 -- 總用戶數
);

-- 統計每日下訂單用戶數
SELECT
  SUBSTRING(t1.createTime, 1, 10) AS dt,
  COUNT(DISTINCT t1.userId) AS user_total
FROM
  `ods_it_shop`.ods_it_orders t1
WHERE
  SUBSTRING(t1.createTime, 1, 10) = '2019-09-05'
GROUP BY  SUBSTRING(t1.createTime, 1, 10);


-- 統計每日下訂單用戶數
INSERT INTO `it_shop_bi`.app_order_user
SELECT
  NULL,
  SUBSTRING(t1.createTime, 1, 10) AS dt,
  SUM(DISTINCT t1.userId) AS user_total
FROM
  `ods_it_shop`.ods_it_orders t1
WHERE
  SUBSTRING(t1.createTime, 1, 10) = '2019-09-05'
GROUP BY  SUBSTRING(t1.createTime, 1, 10);




-- 創建支付方式訂單總額/訂單筆數分析
CREATE TABLE IF NOT EXISTS `it_shop_bi`.app_order_paytype
(
    id          INTEGER AUTO_INCREMENT PRIMARY KEY, -- 唯一標識(無意義)
    dt          DATE,                               -- 統計日期
    pay_type    VARCHAR(20),                      -- 支付方式
    total_money DOUBLE,                             -- 總支付金額
    total_cnt   INTEGER                             -- 總訂單筆數
);

-- 統計不同支付方式的訂單總金額、總筆數
SELECT
   '2019-09-05',
  CASE WHEN payType = 1 THEN '支付寶'
   WHEN payType = 2 THEN '微信'
   WHEN payType = 3 THEN '信用卡'
   ELSE '其他'
  END AS payType,
  SUM(t1.realTotalMoney) AS total_money,
  COUNT(1) AS total_cnt
FROM
 `ods_it_shop`.ods_it_orders t1
WHERE
 SUBSTRING(dt,1,10) = '2019-09-05'
GROUP BY t1.payType;



-- 統計不同支付方式的訂單總金額、總筆數
INSERT INTO `it_shop_bi`.app_order_paytype
SELECT
   NULL,
   '2019-09-05',
  CASE WHEN payType = 1 THEN '支付寶'
   WHEN payType = 2 THEN '微信'
   WHEN payType = 3 THEN '現金'
   ELSE '其他'
  END AS payType,
  SUM(t1.realTotalMoney) AS total_money,
  COUNT(1) AS total_cnt
FROM
 `ods_it_shop`.ods_it_orders t1
WHERE
 SUBSTRING(dt,1,10) = '2019-09-05'
GROUP BY t1.payType;


-- 創建下訂單用戶最多的前5名
CREATE TABLE IF NOT EXISTS `it_shop_bi`.app_order_user_top5
(
    id        INTEGER AUTO_INCREMENT PRIMARY KEY,-- 唯一標識(無意義)
    dt        VARCHAR(10),-- 統計日期
    userid    VARCHAR(20),                       -- 用戶id
    username  VARCHAR(50),                       -- 用戶姓名
    total_cnt INTEGER                            -- 總訂單筆數
);

-- 方式1
-- 統計訂單筆數TOP5用戶分析
SELECT
 '2019-09'
 , t.userId
  ,t.userName
  ,COUNT(orderId)  AS total_cnt
FROM `ods_it_shop`.ods_it_orders t
WHERE SUBSTRING(createTime,1,7) = '2019-09' # 2019-09
GROUP BY t.userName, t.userId
ORDER BY total_cnt DESC
LIMIT 5;


-- 統計訂單筆數TOP5用戶分析
INSERT INTO `it_shop_bi`.app_order_user_top5
SELECT
    NULL,
    '2019-09',
    userId,
    userName,
    COUNT(orderId) AS total_cnt
FROM `ods_it_shop`.ods_it_orders
WHERE SUBSTRING(createTime, 1, 7) = '2019-09'
GROUP BY userId,userName
ORDER BY total_cnt DESC
LIMIT 5

-- 創建商品分類訂單總額/訂單筆數分析結果表
CREATE TABLE IF NOT EXISTS `it_shop_bi`.app_order_goods_cat
(
    id          INTEGER AUTO_INCREMENT PRIMARY KEY,-- 唯一標識(無意義)
    dt          DATE,                              -- 統計日期
    cat_name    VARCHAR(50),                       -- 一級分類名稱
    total_money DOUBLE,                            -- 訂單總金額
    total_num   INTEGER                            -- 訂單總筆數
);


-- 統計不同一級商品分類訂單總額/總筆數分析
CREATE TABLE `it_shop_bi`.tmp_goods_cat
AS
SELECT t3.catId   AS cat_id_l3,   -- 3級分類id
       t3.catName AS cat_name_l3, -- 3級分類名稱
       t2.catId   AS cat_id_l2,   -- 2級分類id
       t2.catName AS cat_name_l2, -- 2級分類名稱
       t1.catId   AS cat_id_l1,   -- 1級分類id
       t1.catName AS cat_name_l1  -- 1級分類名稱
FROM `ods_it_shop`.ods_it_goods_cats t3,
     `ods_it_shop`.ods_it_goods_cats t2,
     `ods_it_shop`.ods_it_goods_cats t1
WHERE t3.parentId = t2.catId
  AND t2.parentId = t1.catId
  AND t3.cat_level = 3;

SELECT * FROM `it_shop_bi`.tmp_goods_cat;





-- 統計分析不同一級商品分類對應的總金額、總筆數
SELECT
  '2019-09-05',
  t1.cat_name_l1 AS goods_cat_l1,
  SUM(t3.payPrice * t3.goodsNum) AS total_money,
  COUNT(DISTINCT t3.orderId) AS total_cnt
FROM
  `it_shop_bi`.tmp_goods_cat t1
LEFT JOIN `ods_it_shop`.ods_it_goods t2
  ON t1.cat_id_l3 = t2.goodsCatId
LEFT JOIN `ods_it_shop`.ods_it_order_goods t3
  ON t2.goodsId = t3.goodsId
WHERE
  SUBSTRING(t3.createTime, 1, 10) = '2019-09-05'
GROUP BY
  t1.cat_name_l1;
  
-- 執行跑了2.03秒  
  
  
#性能優化
CREATE UNIQUE INDEX idx_goods_cat3 ON `it_shop_bi`.tmp_goods_cat(cat_id_l3);

CREATE UNIQUE INDEX idx_it_goods ON `ods_it_shop`.ods_it_goods(goodsId);

CREATE INDEX idx_it_order_goods ON `ods_it_shop`.ods_it_order_goods(goodsId);


-- 優化後跑了0.038秒
 SELECT
    NULL,
   '2019-09-05',
   t1.cat_name_l1 AS goods_cat_l1,
   SUM(t3.payPrice * t3.goodsNum) AS total_money,
   COUNT(DISTINCT t3.orderId) AS total_cnt
 FROM
   `it_shop_bi`.tmp_goods_cat t1
 LEFT JOIN
   `ods_it_shop`.ods_it_goods t2
   ON t1.cat_id_l3 = t2.goodsCatId
 LEFT JOIN
   `ods_it_shop`.ods_it_order_goods t3
   ON t2.goodsId = t3.goodsId
 WHERE
   SUBSTRING(t3.createTime, 1, 10) = '2019-09-05'
 GROUP BY
   t1.cat_name_l1;

-- 分析某天的訂單總筆數、總金額
INSERT INTO `it_shop_bi`.app_order_total
SELECT NULL,                                  -- 對應無意義的唯一標識列
       dt,                                    -- 某一天
       SUM(t1.realTotalMoney) AS total_money, -- 訂單總金額
       COUNT(1)               AS total_cnt    -- 訂單總筆數
FROM `ods_it_shop`.ods_it_orders t1
WHERE t1.dt = '${dt}';


-- 統計每日下訂單用戶數
INSERT INTO it_shop_bi.app_order_user
SELECT NULL,
       dt,
       SUM(DISTINCT t1.userId)
FROM `ods_it_shop`.ods_it_orders t1
WHERE t1.dt = '${dt}';


-- 統計不同支付方式的訂單總金額、總筆數
INSERT INTO `it_shop_bi`.app_order_paytype
SELECT NULL,
       dt,
       CASE
           WHEN payType = 1 THEN '支付寶'
           WHEN payType = 2 THEN '微信'
           WHEN payType = 3 THEN '現金'
           ELSE '其他'
           END                AS payType,
       SUM(t1.realTotalMoney) AS total_money,
       COUNT(1)               AS total_cnt
FROM `ods_it_shop`.ods_it_orders t1
WHERE dt = '${dt}'
GROUP BY t1.payType;


-- 統計不同一級商品分類訂單總額/總筆數分析
DROP TABLE IF EXISTS `it_shop_bi`.tmp_goods_cat;
CREATE TEMPORARY TABLE `it_shop_bi`.tmp_goods_cat
AS
SELECT t3.catId   AS cat_id_l3,   -- 3級分類id
       t3.catName AS cat_name_l3, -- 3級分類名稱
       t2.catId   AS cat_id_l2,   -- 2級分類id
       t2.catName AS cat_name_l2, -- 2級分類名稱
       t1.catId   AS cat_id_l1,   -- 1級分類id
       t1.catName AS cat_name_l1  -- 1級分類名稱
FROM `ods_it_shop`.ods_it_goods_cats t3,
     `ods_it_shop`.ods_it_goods_cats t2,
     `ods_it_shop`.ods_it_goods_cats t1
WHERE t3.parentId = t2.catId
  AND t2.parentId = t1.catId
  AND t3.cat_level = 3;


-- 在商品分類臨時表上添加索引
CREATE UNIQUE INDEX idx_goods_cat3 ON `it_shop_bi`.tmp_goods_cat (cat_id_l3);

-- 查看臨時表中的數據
SELECT *
FROM `it_shop_bi`.tmp_goods_cat;

INSERT INTO `it_shop_bi`.app_order_goods_cat
SELECT NULL,
       t3.dt,
       t1.cat_name_l1                 AS goods_cat_l1,
       SUM(t3.payPrice * t3.goodsNum) AS total_money,
       COUNT(DISTINCT t3.orderId)     AS total_cnt
FROM `it_shop_bi`.tmp_goods_cat t1
         LEFT JOIN
    `ods_it_shop`.ods_it_goods t2
     ON t1.cat_id_l3 = t2.goodsCatId
         LEFT JOIN
     `ods_it_shop`.ods_it_order_goods t3
     ON t2.goodsId = t3.goodsId
WHERE t3.dt = '${dt}'
GROUP BY t1.cat_name_l1;



-- 統計訂單筆數TOP5用戶分析
INSERT INTO `it_shop_bi`.app_order_user_top5
SELECT
    NULL,
    SUBSTRING(CURDATE(), 1, 7) AS today,
    userId,
    userName,
    COUNT(orderId) AS total_cnt
FROM `ods_it_shop`.ods_it_orders t2
WHERE SUBSTRING(createTime, 1, 7) IS NOT NULL
GROUP BY userId,userName
ORDER BY total_cnt DESC
LIMIT 5

 


4.9   開發Kettle作業

 

 

 

 

 

 

 

5.使用Apache Superset進行數據可視化

 

 

 

cd  cd /root/anaconda3/

superset run -h 192.168.88.100 -p 8080 –with-threads –reload –debugger

1.1.1    添加MySQL資料庫

mysql://root:[email protected]/it_shop_bi?charset=utf8

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1.1     訂單支付方式分析開發

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

5.7 訂單商品分類分析

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

5.8 Superset Dashboard(看板)開發

 

 

 

 

 

 

 

 

 

 

 

Tags: