第一章 電商業務簡介
1.1 電商業務流程
電商的業務流程可以以一個普通用戶的瀏覽足跡爲例進行說明,用戶點開電商首頁開始瀏覽,可能會通過分類查詢也可能通過全文搜索尋找自己中意的商品,這些商品無疑都是存儲在後臺的管理系統中的。
當用戶尋找到自己中意的商品,可能會想要購買,將商品添加到購物車後發現需要登錄,登錄後對商品進行結算,這時候購物車的管理和商品訂單信息的生成都會對業務數據庫產生影響,會生成相應的訂單數據和支付數據。
訂單正式生成之後,還會對訂單進行跟蹤處理,直到訂單全部完成。
電商的主要業務流程包括用戶前臺瀏覽商品時的商品詳情的管理,用戶商品加入購物車進行支付時用戶個人中心&支付服務的管理,用戶支付完成後訂單後臺服務的管理,這些流程涉及到了十幾個甚至幾十個業務數據表,甚至更多。
1.2 電商常識
1.2.1 SKU和SPU
SKU = Stock Keeping Unit(庫存量基本單位)。現在已經被引申爲產品統一編號的簡稱,每種產品均對應有唯一的SKU號。
SPU(Standard Product Unit):是商品信息聚合的最小單位,是一組可複用、易檢索的標準化信息集合。
例如:iPhoneX手機就是SPU。一臺銀色、128G內存的、支持聯通網絡的iPhoneX,就是SKU。
SPU表示一類商品。同一SPU的商品可以共用商品圖片、海報、銷售屬性等。
1.2.2 平臺屬性和銷售屬性
1)平臺屬性
2)銷售屬性
1.3 電商系統表結構
以下爲本電商數倉系統涉及到的業務數據表結構關係。這34個表以訂單表、用戶表、SKU商品表、活動表和優惠券表爲中心,延伸出了優惠券領用表、支付流水錶、活動訂單表、訂單詳情表、訂單狀態表、商品評論表、編碼字典表退單表、SPU商品表等,用戶表提供用戶的詳細信息,支付流水錶提供該訂單的支付詳情,訂單詳情表提供訂單的商品數量等情況,商品表給訂單詳情表提供商品的詳細信息。本次講解以此34個表爲例,實際項目中,業務數據庫中表格遠遠不止這些。
電商數據表:
後臺管理系統:
1.3.1 活動信息表(activity_info)
字段名 |
字段說明 |
id |
活動id |
activity_name |
活動名稱 |
activity_type |
活動類型(1:滿減,2:折扣) |
activity_desc |
活動描述 |
start_time |
開始時間 |
end_time |
結束時間 |
create_time |
創建時間 |
1.3.2 活動規則表(activity_rule)
id |
編號 |
activity_id |
活動ID |
activity_type |
活動類型 |
condition_amount |
滿減金額 |
condition_num |
滿減件數 |
benefit_amount |
優惠金額 |
benefit_discount |
優惠折扣 |
benefit_level |
優惠級別 |
1.3.3 活動商品關聯表(activity_sku)
字段名 |
字段說明 |
id |
編號 |
activity_id |
活動id |
sku_id |
sku_id |
create_time |
創建時間 |
1.3.4 平臺屬性表(base_attr_info)
字段名 |
字段說明 |
id |
編號 |
attr_name |
屬性名稱 |
category_id |
分類id |
category_level |
分類層級 |
1.3.5 平臺屬性值表(base_attr_value)
字段名 |
字段說明 |
id |
編號 |
value_name |
屬性值名稱 |
attr_id |
屬性id |
1.3.6 一級分類表(base_category1)
字段名 |
字段說明 |
id |
編號 |
name |
分類名稱 |
1.3.7 二級分類表(base_category2)
字段名 |
字段說明 |
id |
編號 |
name |
二級分類名稱 |
category1_id |
一級分類編號 |
1.3.8 三級分類表(base_category3)
字段名 |
字段說明 |
id |
編號 |
name |
三級分類名稱 |
category2_id |
二級分類編號 |
1.3.9 字典表(base_dic)
字段名 |
字段說明 |
dic_code |
編號 |
dic_name |
編碼名稱 |
parent_code |
父編號 |
create_time |
創建日期 |
operate_time |
修改日期 |
1.3.10 省份表(base_province)
字段名 |
字段說明 |
id |
id |
name |
省名稱 |
region_id |
大區id |
area_code |
行政區位碼 |
iso_code |
國際編碼 |
iso_3166_2 |
ISO3166編碼 |
1.3.11 地區表(base_region)
字段名 |
字段說明 |
id |
大區id |
region_name |
大區名稱 |
1.3.12 品牌表(base_trademark)
字段名 |
字段說明 |
id |
編號 |
tm_name |
屬性值 |
logo_url |
品牌logo的圖片路徑 |
1.3.13 購物車表(cart_info)
字段名 |
字段說明 |
id |
編號 |
user_id |
用戶id |
sku_id |
skuid |
cart_price |
放入購物車時價格 |
sku_num |
數量 |
img_url |
圖片文件 |
sku_name |
sku名稱 (冗餘) |
is_checked |
是否已經下單 |
create_time |
創建時間 |
operate_time |
修改時間 |
is_ordered |
是否已經下單 |
order_time |
下單時間 |
source_type |
來源類型 |
source_id |
來源編號 |
1.3.14 評價表(comment_info)
字段名 |
字段說明 |
id |
編號 |
user_id |
用戶id |
nick_name |
用戶暱稱 |
head_img |
圖片 |
sku_id |
商品sku_id |
spu_id |
商品spu_id |
order_id |
訂單編號 |
appraise |
評價 1 好評 2 中評 3 差評 |
comment_txt |
評價內容 |
create_time |
創建時間 |
operate_time |
修改時間 |
1.3.15 優惠券信息表(coupon_info)
字段名 |
字段說明 |
id |
購物券編號 |
coupon_name |
購物券名稱 |
coupon_type |
購物券類型 1 現金券 2 折扣券 3 滿減券 4 滿件打折券 |
condition_amount |
滿額數(3) |
condition_num |
滿件數(4) |
activity_id |
活動編號 |
benefit_amount |
減金額(1 3) |
benefit_discount |
折扣(2 4) |
create_time |
創建時間 |
range_type |
範圍類型 1、商品(spuid) 2、品類(三級分類id) 3、品牌 |
limit_num |
最多領用次數 |
taken_count |
已領用次數 |
start_time |
可以領取的開始日期 |
end_time |
可以領取的結束日期 |
operate_time |
修改時間 |
expire_time |
過期時間 |
range_desc |
範圍描述 |
1.3.16 優惠券優惠範圍表(coupon_range)
字段名 |
字段說明 |
id |
購物券編號 |
coupon_id |
優惠券id |
range_type |
範圍類型 1、商品(spuid) 2、品類(三級分類id) 3、品牌 |
range_id |
範圍id |
1.3.17 優惠券領用表(coupon_use)
字段名 |
字段說明 |
id |
編號 |
coupon_id |
購物券ID |
user_id |
用戶ID |
order_id |
訂單ID |
coupon_status |
購物券狀態(1:未使用 2:已使用) |
get_time |
獲取時間 |
using_time |
使用時間 |
used_time |
支付時間 |
expire_time |
過期時間 |
1.3.18 收藏表(favor_info)
字段名 |
字段說明 |
id |
編號 |
user_id |
用戶id |
sku_id |
skuid |
spu_id |
商品id |
is_cancel |
是否已取消 0 正常 1 已取消 |
create_time |
創建時間 |
cancel_time |
修改時間 |
1.3.19 訂單明細表(order_detail)
字段名 |
字段說明 |
id |
編號 |
order_id |
訂單編號 |
sku_id |
sku_id |
sku_name |
sku名稱(冗餘) |
img_url |
圖片名稱(冗餘) |
order_price |
購買價格(下單時sku價格) |
sku_num |
購買個數 |
create_time |
創建時間 |
source_type |
來源類型 |
source_id |
來源編號 |
split_total_amount |
分攤總金額 |
split_activity_amount |
分攤活動減免金額 |
split_coupon_amount |
分攤優惠券減免金額 |
1.3.20 訂單明細活動關聯表(order_detail_activity)
字段名 |
字段說明 |
id |
編號 |
order_id |
訂單id |
order_detail_id |
訂單明細id |
activity_id |
活動ID |
activity_rule_id |
活動規則 |
sku_id |
skuID |
create_time |
獲取時間 |
1.3.21 訂單明細優惠券關聯表(order_detail_coupon)
字段名 |
字段說明 |
id |
編號 |
order_id |
訂單id |
order_detail_id |
訂單明細id |
coupon_id |
購物券ID |
coupon_use_id |
購物券領用id |
sku_id |
skuID |
create_time |
獲取時間 |
1.3.22 訂單表(order_info)
字段名 |
字段說明 |
id |
編號 |
consignee |
收貨人 |
consignee_tel |
收件人電話 |
total_amount |
總金額 |
order_status |
訂單狀態 |
user_id |
用戶id |
payment_way |
付款方式 |
delivery_address |
送貨地址 |
order_comment |
訂單備註 |
out_trade_no |
訂單交易編號(第三方支付用) |
trade_body |
訂單描述(第三方支付用) |
create_time |
創建時間 |
operate_time |
操作時間 |
expire_time |
失效時間 |
process_status |
進度狀態 |
tracking_no |
物流單編號 |
parent_order_id |
父訂單編號 |
img_url |
圖片路徑 |
province_id |
地區 |
activity_reduce_amount |
促銷金額 |
coupon_reduce_amount |
優惠金額 |
original_total_amount |
原價金額 |
feight_fee |
運費 |
feight_fee_reduce |
運費減免 |
refundable_time |
可退款日期(簽收後30天) |
1.3.23 退單表(order_refund_info)
字段名 |
字段說明 |
id |
編號 |
user_id |
用戶id |
order_id |
訂單id |
sku_id |
skuid |
refund_type |
退款類型 |
refund_num |
退貨件數 |
refund_amount |
退款金額 |
refund_reason_type |
原因類型 |
refund_reason_txt |
原因內容 |
refund_status |
退款狀態(0:待審批 1:已退款) |
create_time |
創建時間 |
1.3.24 訂單狀態流水錶(order_status_log)
字段名 |
字段說明 |
id |
編號 |
order_id |
訂單編號 |
order_status |
訂單狀態 |
operate_time |
操作時間 |
1.3.25 支付表(payment_info)
字段名 |
字段說明 |
id |
編號 |
out_trade_no |
對外業務編號 |
order_id |
訂單編號 |
user_id |
|
payment_type |
支付類型(微信 支付寶) |
trade_no |
交易編號 |
total_amount |
支付金額 |
subject |
交易內容 |
payment_status |
支付狀態 |
create_time |
創建時間 |
callback_time |
回調時間 |
callback_content |
回調信息 |
1.3.26 退款表(refund_payment)
字段名 |
字段說明 |
id |
編號 |
out_trade_no |
對外業務編號 |
order_id |
訂單編號 |
sku_id |
商品sku_id |
payment_type |
支付類型(微信 支付寶) |
trade_no |
交易編號 |
total_amount |
退款金額 |
subject |
交易內容 |
refund_status |
退款狀態 |
create_time |
創建時間 |
callback_time |
回調時間 |
callback_content |
回調信息 |
1.3.27 SKU平臺屬性表(sku_attr_value)
字段名 |
字段說明 |
id |
編號 |
attr_id |
屬性id(冗餘) |
value_id |
屬性值id |
sku_id |
skuid |
attr_name |
屬性名稱 |
value_name |
屬性值名稱 |
1.3.28 SKU信息表(sku_info)
字段名 |
字段說明 |
id |
庫存id(itemID) |
spu_id |
商品id |
price |
價格 |
sku_name |
sku名稱 |
sku_desc |
商品規格描述 |
weight |
重量 |
tm_id |
品牌(冗餘) |
category3_id |
三級分類id(冗餘) |
sku_default_img |
默認顯示圖片(冗餘) |
is_sale |
是否銷售(1:是 0:否) |
create_time |
創建時間 |
1.3.29 SKU銷售屬性表(sku_sale_attr_value)
字段名 |
字段說明 |
id |
id |
sku_id |
庫存單元id |
spu_id |
spu_id(冗餘) |
sale_attr_value_id |
銷售屬性值id |
sale_attr_id |
銷售屬性id |
sale_attr_name |
銷售屬性值名稱 |
sale_attr_value_name |
銷售屬性值名稱 |
1.3.30 SPU信息表(spu_info)
字段名 |
字段說明 |
id |
商品id |
spu_name |
商品名稱 |
description |
商品描述(後臺簡述) |
category3_id |
三級分類id |
tm_id |
品牌id |
1.3.31 SPU銷售屬性表(spu_sale_attr)
字段名 |
字段說明 |
id |
編號(業務中無關聯) |
spu_id |
商品id |
base_sale_attr_id |
銷售屬性id |
sale_attr_name |
銷售屬性名稱(冗餘) |
1.3.32 SPU銷售屬性值表(spu_sale_attr_value)
字段名 |
字段說明 |
id |
銷售屬性值編號 |
spu_id |
商品id |
base_sale_attr_id |
銷售屬性id |
sale_attr_value_name |
銷售屬性值名稱 |
sale_attr_name |
銷售屬性名稱(冗餘) |
1.3.33 用戶地址表(user_address)
字段名 |
字段說明 |
id |
編號 |
user_id |
用戶id |
province_id |
省份id |
user_address |
用戶地址 |
consignee |
收件人 |
phone_num |
聯繫方式 |
is_default |
是否是默認 |
1.3.34 用戶信息表(user_info)
字段名 |
字段說明 |
id |
編號 |
login_name |
用戶名稱 |
nick_name |
用戶暱稱 |
passwd |
用戶密碼 |
name |
用戶姓名 |
phone_num |
手機號 |
|
郵箱 |
head_img |
頭像 |
user_level |
用戶級別 |
birthday |
用戶生日 |
gender |
性別 M男,F女 |
create_time |
創建時間 |
operate_time |
修改時間 |
status |
狀態 |
第二章 業務數據採集模塊
2.1 MySQL安裝
相關mysql和jar
鏈接:https://pan.baidu.com/s/1Y76xSBscsB9_qQa1gwXLVA
提取碼:lqi4
1)檢查當前系統是否安裝過Mysql
[atguigu@hadoop102 ~]$ rpm -qa|grep mariadb
mariadb-libs-5.5.56-2.el7.x86_64 //如果存在通過如下命令卸載
[atguigu @hadoop102 ~]$ sudo rpm -e --nodeps mariadb-libs //用此命令卸載mariadb
2)將MySQL安裝包拷貝到/opt/software/mysql-lib目錄下
3)解壓MySQL安裝包
//解壓*.tar包,參數只需要-xf; 解壓*.tar.gz,參數:-zxvf
[atguigu @hadoop102 mysql-lib]$ tar -xf mysql-5.7.28-1.el7.x86_64.rpm-bundle.tar -C
4)在安裝目錄下執行rpm安裝, 要以下按照順序依次執行
[atguigu @hadoop102 mysql-lib]$ sudo rpm -ivh mysql-community-common-5.7.28-1.el7.x86_64.rpm
[atguigu @hadoop102 mysql-lib]$ sudo rpm -ivh mysql-community-libs-5.7.28-1.el7.x86_64.rpm
[atguigu @hadoop102 mysql-lib]$ sudo rpm -ivh mysql-community-libs-compat-5.7.28-1.el7.x86_64.rpm
[atguigu @hadoop102 mysql-lib]$ sudo rpm -ivh mysql-community-client-5.7.28-1.el7.x86_64.rpm
[atguigu @hadoop102 mysql-lib]$ sudo rpm -ivh mysql-community-server-5.7.28-1.el7.x86_64.rpm
如果Linux是最小化安裝的,在安裝mysql-community-server-5.7.28-1.el7.x86_64.rpm時可能會出現如下錯誤:
[atguigu@hadoop102 software]$ sudo rpm -ivh mysql-community-server-5.7.28-1.el7.x86_64.rpm
警告:mysql-community-server-5.7.28-1.el7.x86_64.rpm: 頭V3 DSA/SHA1 Signature, 密鑰 ID 5072e1f5: NOKEY
錯誤:依賴檢測失敗:
libaio.so.1()(64bit) 被 mysql-community-server-5.7.28-1.el7.x86_64 需要
libaio.so.1(LIBAIO_0.1)(64bit) 被 mysql-community-server-5.7.28-1.el7.x86_64 需要
libaio.so.1(LIBAIO_0.4)(64bit) 被 mysql-community-server-5.7.28-1.el7.x86_64 需要
通過yum安裝缺少的依賴,然後重新安裝mysql-community-server-5.7.28-1.el7.x86_64 即可
[atguigu@hadoop102 mysql-lib] yum install -y libaio
5)刪除/etc/my.cnf文件中datadir指向的目錄下的所有內容,如果有內容的情況下需要刪除
查看datadir的值
datadir=/var/lib/mysql
[atguigu@hadoop102 mysql-lib]$ vim /etc/my.cnf
# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html
[mysqld]
#
# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
# innodb_buffer_pool_size = 128M
#
# Remove leading # to turn on a very important data integrity option: logging
# changes to the binary log between backups.
# log_bin
#
# Remove leading # to set options mainly useful for reporting servers.
# The server defaults are faster for transactions and fast SELECTs.
# Adjust sizes as needed, experiment to find the optimal values.
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M
datadir=/var/lib/mysql
刪除/var/lib/mysql目錄下的所有內容:
[atguigu @hadoop102 mysql]# cd /var/lib/mysql
[atguigu @hadoop102 mysql]# sudo rm -rf ./* //注意執行命令的位置
6)初始化數據庫
[atguigu @hadoop102 opt]$ sudo mysqld --initialize --user=mysql
7)查看臨時生成的root用戶的密碼
[atguigu @hadoop102 opt]$ sudo cat /var/log/mysqld.log
8)啓動mysql服務
[atguigu @hadoop102 opt]$ sudo systemctl start mysqld
9)登錄mysql數據庫
[atguigu @hadoop102 opt]$ mysql -uroot -p
Enter password: 輸入臨時生成的密碼
必須先修改root用戶的密碼,否則執行其他的操作會報錯, 記住自己設置的密碼
mysql> set password = password("123456");
10)修改mysql庫下的user表中的root用戶允許任意ip連接,可以客戶端遠程登錄
mysql> update mysql.user set host='%' where user='root';
mysql> flush privileges;
11)通過navicat遠程登錄驗證
2.2 業務數據生成
在Navicat中創建數據庫,設置數據庫名稱爲gmall,編碼爲utf-8,排序規則爲utf8_general_ci,導入數據庫結構腳本(gmall.sql)
1)在hadoop102的/opt/module/目錄下創建db_log文件夾
[atguigu@hadoop102 module]$ mkdir db_log/
2)把gmall2020-mock-db-2021-01-22.jar和application.properties上傳到hadoop102的/opt/module/db_log路徑上。
3)根據需求修改application.properties相關配置
logging.level.root=info spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://hadoop102:3306/gmall?characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8 spring.datasource.username=root spring.datasource.password=000000 logging.pattern.console=%m%n mybatis-plus.global-config.db-config.field-strategy=not_null #業務日期 mock.date=2020-06-14 #是否重置 注意:第一次執行必須設置爲1,後續不需要重置不用設置爲1 mock.clear=1 #是否重置用戶 注意:第一次執行必須設置爲1,後續不需要重置不用設置爲1 mock.clear.user=1 #生成新用戶數量 mock.user.count=100 #男性比例 mock.user.male-rate=20 #用戶數據變化概率 mock.user.update-rate:20 #收藏取消比例 mock.favor.cancel-rate=10 #收藏數量 mock.favor.count=100 #每個用戶添加購物車的概率 mock.cart.user-rate=50 #每次每個用戶最多添加多少種商品進購物車 mock.cart.max-sku-count=8 #每個商品最多買幾個 mock.cart.max-sku-num=3 #購物車來源 用戶查詢,商品推廣,智能推薦, 促銷活動 mock.cart.source-type-rate=60:20:10:10 #用戶下單比例 mock.order.user-rate=50 #用戶從購物中購買商品比例 mock.order.sku-rate=50 #是否參加活動 mock.order.join-activity=1 #是否使用購物券 mock.order.use-coupon=1 #購物券領取人數 mock.coupon.user-count=100 #支付比例 mock.payment.rate=70 #支付方式 支付寶:微信 :銀聯 mock.payment.payment-type=30:60:10 #評價比例 好:中:差:自動 mock.comment.appraise-rate=30:10:10:50 #退款原因比例:質量問題 商品描述與實際描述不一致 缺貨 號碼不合適 拍錯 不想買了 其他 mock.refund.reason-rate=30:10:20:5:15:5:5
4)並在該目錄下執行,如下命令,生成2020-06-14日期數據:
[atguigu@hadoop102 db_log]$ java -jar gmall2020-mock-db-2021-01-22.jar
5)查看gmall數據庫,觀察是否有2020-06-14的數據出現
2.3 Sqoop安裝
2.3.1 下載並解壓
1)sqoop官網地址:http://sqoop.apache.org
2)下載地址:http://mirrors.hust.edu.cn/apache/sqoop/1.4.6/
3)上傳安裝包sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz到hadoop102的/opt/software路徑中
4)解壓sqoop安裝包到指定目錄,如:
[atguigu@hadoop102 software]$ tar -zxf sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz -C /opt/module/
5)解壓sqoop安裝包到指定目錄,如:
[atguigu@hadoop102 module]$ mv sqoop-1.4.6.bin__hadoop-2.0.4-alpha/ sqoop
2.3.2 修改配置文件
1)進入到/opt/module/sqoop/conf目錄,重命名配置文件
[atguigu@hadoop102 conf]$ mv sqoop-env-template.sh sqoop-env.sh
2)修改配置文件
[atguigu@hadoop102 conf]$ vim sqoop-env.sh
增加如下內容
export HADOOP_COMMON_HOME=/opt/module/hadoop-3.1.3 export HADOOP_MAPRED_HOME=/opt/module/hadoop-3.1.3 export HIVE_HOME=/opt/module/hive export ZOOKEEPER_HOME=/opt/module/zookeeper-3.5.7 export ZOOCFGDIR=/opt/module/zookeeper-3.5.7/conf
2.3.3 拷貝JDBC驅動
1)將mysql-connector-java-5.1.48.jar 上傳到/opt/software路徑
2)進入到/opt/software/路徑,拷貝jdbc驅動到sqoop的lib目錄下。
[atguigu@hadoop102 software]$ cp mysql-connector-java-5.1.48.jar /opt/module/sqoop/lib/
2.3.4 驗證Sqoop
(1)我們可以通過某一個command來驗證sqoop配置是否正確:
[atguigu@hadoop102 sqoop]$ bin/sqoop help
(2)出現一些Warning警告(警告信息已省略),並伴隨着幫助命令的輸出:
Available commands: codegen Generate code to interact with database records create-hive-table Import a table definition into Hive eval Evaluate a SQL statement and display the results export Export an HDFS directory to a database table help List available commands import Import a table from a database to HDFS import-all-tables Import tables from a database to HDFS import-mainframe Import datasets from a mainframe server to HDFS job Work with saved jobs list-databases List available databases on a server list-tables List available tables in a database merge Merge results of incremental imports metastore Run a standalone Sqoop metastore version Display version information
2.3.5 測試Sqoop是否能夠成功連接數據庫
[atguigu@hadoop102 sqoop]$ bin/sqoop list-databases --connect jdbc:mysql://hadoop102:3306/ --username root --password 123456
出現如下輸出:
information_schema
metastore
mysql
oozie
performance_schema
2.3.6 Sqoop基本使用
將mysql中user_info表數據導入到HDFS的/test路徑
bin/sqoop import \ --connect jdbc:mysql://hadoop102:3306/gmall \ --username root \ --password 123456 \ --table user_info \ --columns id,login_name \ --where "id>=10 and id<=30" \ --target-dir /test \ --delete-target-dir \ --fields-terminated-by '\t' \ --num-mappers 2 \ --split-by id
2.4 同步策略
數據同步策略的類型包括:全量同步、增量同步、新增及變化同步、特殊情況
- 全量表:存儲完整的數據。
- 增量表:存儲新增加的數據。
- 新增及變化表:存儲新增加的數據和變化的數據。
- 特殊表:只需要存儲一次。
2.4.1 全量同步策略
2.4.2 增量同步策略
2.4.3 新增及變化策略
2.4.4 特殊策略
某些特殊的表,可不必遵循上述同步策略。例如某些不會發生變化的表(地區表,省份表,民族表)可以只存一份固定值。
2.5 業務數據導入HDFS
2.5.1 分析表同步策略
在生產環境,個別小公司,爲了簡單處理,所有表全量導入。
中大型公司,由於數據量比較大,還是嚴格按照同步策略導入數據。
2.5.2 業務數據首日同步腳本
1)腳本編寫
(1)在/home/atguigu/bin目錄下創建
[atguigu@hadoop102 bin]$ vim mysql_to_hdfs_init.sh
添加如下內容:
#! /bin/bash APP=gmall sqoop=/opt/module/sqoop/bin/sqoop if [ -n "$2" ] ;then do_date=$2 else echo "請傳入日期參數" exit fi import_data(){ $sqoop import \ --connect jdbc:mysql://hadoop102:3306/$APP \ --username root \ --password 123456 \ --target-dir /origin_data/$APP/db/$1/$do_date \ --delete-target-dir \ --query "$2 where \$CONDITIONS" \ --num-mappers 1 \ --fields-terminated-by '\t' \ --compress \ --compression-codec lzop \ --null-string '\\N' \ --null-non-string '\\N' hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/common/hadoop-lzo-0.4.20.jar com.hadoop.compression.lzo.DistributedLzoIndexer /origin_data/$APP/db/$1/$do_date } import_order_info(){ import_data order_info "select id, total_amount, order_status, user_id, payment_way, delivery_address, out_trade_no, create_time, operate_time, expire_time, tracking_no, province_id, activity_reduce_amount, coupon_reduce_amount, original_total_amount, feight_fee, feight_fee_reduce from order_info" } import_coupon_use(){ import_data coupon_use "select id, coupon_id, user_id, order_id, coupon_status, get_time, using_time, used_time, expire_time from coupon_use" } import_order_status_log(){ import_data order_status_log "select id, order_id, order_status, operate_time from order_status_log" } import_user_info(){ import_data "user_info" "select id, login_name, nick_name, name, phone_num, email, user_level, birthday, gender, create_time, operate_time from user_info" } import_order_detail(){ import_data order_detail "select id, order_id, sku_id, sku_name, order_price, sku_num, create_time, source_type, source_id, split_total_amount, split_activity_amount, split_coupon_amount from order_detail" } import_payment_info(){ import_data "payment_info" "select id, out_trade_no, order_id, user_id, payment_type, trade_no, total_amount, subject, payment_status, create_time, callback_time from payment_info" } import_comment_info(){ import_data comment_info "select id, user_id, sku_id, spu_id, order_id, appraise, create_time from comment_info" } import_order_refund_info(){ import_data order_refund_info "select id, user_id, order_id, sku_id, refund_type, refund_num, refund_amount, refund_reason_type, refund_status, create_time from order_refund_info" } import_sku_info(){ import_data sku_info "select id, spu_id, price, sku_name, sku_desc, weight, tm_id, category3_id, is_sale, create_time from sku_info" } import_base_category1(){ import_data "base_category1" "select id, name from base_category1" } import_base_category2(){ import_data "base_category2" "select id, name, category1_id from base_category2" } import_base_category3(){ import_data "base_category3" "select id, name, category2_id from base_category3" } import_base_province(){ import_data base_province "select id, name, region_id, area_code, iso_code, iso_3166_2 from base_province" } import_base_region(){ import_data base_region "select id, region_name from base_region" } import_base_trademark(){ import_data base_trademark "select id, tm_name from base_trademark" } import_spu_info(){ import_data spu_info "select id, spu_name, category3_id, tm_id from spu_info" } import_favor_info(){ import_data favor_info "select id, user_id, sku_id, spu_id, is_cancel, create_time, cancel_time from favor_info" } import_cart_info(){ import_data cart_info "select id, user_id, sku_id, cart_price, sku_num, sku_name, create_time, operate_time, is_ordered, order_time, source_type, source_id from cart_info" } import_coupon_info(){ import_data coupon_info "select id, coupon_name, coupon_type, condition_amount, condition_num, activity_id, benefit_amount, benefit_discount, create_time, range_type, limit_num, taken_count, start_time, end_time, operate_time, expire_time from coupon_info" } import_activity_info(){ import_data activity_info "select id, activity_name, activity_type, start_time, end_time, create_time from activity_info" } import_activity_rule(){ import_data activity_rule "select id, activity_id, activity_type, condition_amount, condition_num, benefit_amount, benefit_discount, benefit_level from activity_rule" } import_base_dic(){ import_data base_dic "select dic_code, dic_name, parent_code, create_time, operate_time from base_dic" } import_order_detail_activity(){ import_data order_detail_activity "select id, order_id, order_detail_id, activity_id, activity_rule_id, sku_id, create_time from order_detail_activity" } import_order_detail_coupon(){ import_data order_detail_coupon "select id, order_id, order_detail_id, coupon_id, coupon_use_id, sku_id, create_time from order_detail_coupon" } import_refund_payment(){ import_data refund_payment "select id, out_trade_no, order_id, sku_id, payment_type, trade_no, total_amount, subject, refund_status, create_time, callback_time from refund_payment" } import_sku_attr_value(){ import_data sku_attr_value "select id, attr_id, value_id, sku_id, attr_name, value_name from sku_attr_value" } import_sku_sale_attr_value(){ import_data sku_sale_attr_value "select id, sku_id, spu_id, sale_attr_value_id, sale_attr_id, sale_attr_name, sale_attr_value_name from sku_sale_attr_value" } case $1 in "order_info") import_order_info ;; "base_category1") import_base_category1 ;; "base_category2") import_base_category2 ;; "base_category3") import_base_category3 ;; "order_detail") import_order_detail ;; "sku_info") import_sku_info ;; "user_info") import_user_info ;; "payment_info") import_payment_info ;; "base_province") import_base_province ;; "base_region") import_base_region ;; "base_trademark") import_base_trademark ;; "activity_info") import_activity_info ;; "cart_info") import_cart_info ;; "comment_info") import_comment_info ;; "coupon_info") import_coupon_info ;; "coupon_use") import_coupon_use ;; "favor_info") import_favor_info ;; "order_refund_info") import_order_refund_info ;; "order_status_log") import_order_status_log ;; "spu_info") import_spu_info ;; "activity_rule") import_activity_rule ;; "base_dic") import_base_dic ;; "order_detail_activity") import_order_detail_activity ;; "order_detail_coupon") import_order_detail_coupon ;; "refund_payment") import_refund_payment ;; "sku_attr_value") import_sku_attr_value ;; "sku_sale_attr_value") import_sku_sale_attr_value ;; "all") import_base_category1 import_base_category2 import_base_category3 import_order_info import_order_detail import_sku_info import_user_info import_payment_info import_base_region import_base_province import_base_trademark import_activity_info import_cart_info import_comment_info import_coupon_use import_coupon_info import_favor_info import_order_refund_info import_order_status_log import_spu_info import_activity_rule import_base_dic import_order_detail_activity import_order_detail_coupon import_refund_payment import_sku_attr_value import_sku_sale_attr_value ;; esac
說明1:
[ -n 變量值 ] 判斷變量的值,是否爲空
-- 變量的值,非空,返回true
-- 變量的值,爲空,返回false
說明2:
查看date命令的使用,[atguigu@hadoop102 ~]$ date --help
(2)增加腳本執行權限
[atguigu@hadoop102 bin]$ chmod +x mysql_to_hdfs_init.sh
2)腳本使用
[atguigu@hadoop102 bin]$ mysql_to_hdfs_init.sh all 2020-06-14
2.5.3 業務數據每日同步腳本
1)腳本編寫
(1)在/home/atguigu/bin目錄下創建
[atguigu@hadoop102 bin]$ vim mysql_to_hdfs.sh
添加如下內容:
#! /bin/bash APP=gmall sqoop=/opt/module/sqoop/bin/sqoop if [ -n "$2" ] ;then do_date=$2 else do_date=`date -d '-1 day' +%F` fi import_data(){ $sqoop import \ --connect jdbc:mysql://hadoop102:3306/$APP \ --username root \ --password 123456 \ --target-dir /origin_data/$APP/db/$1/$do_date \ --delete-target-dir \ --query "$2 and \$CONDITIONS" \ --num-mappers 1 \ --fields-terminated-by '\t' \ --compress \ --compression-codec lzop \ --null-string '\\N' \ --null-non-string '\\N' hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/common/hadoop-lzo-0.4.20.jar com.hadoop.compression.lzo.DistributedLzoIndexer /origin_data/$APP/db/$1/$do_date } import_order_info(){ import_data order_info "select id, total_amount, order_status, user_id, payment_way, delivery_address, out_trade_no, create_time, operate_time, expire_time, tracking_no, province_id, activity_reduce_amount, coupon_reduce_amount, original_total_amount, feight_fee, feight_fee_reduce from order_info where (date_format(create_time,'%Y-%m-%d')='$do_date' or date_format(operate_time,'%Y-%m-%d')='$do_date')" } import_coupon_use(){ import_data coupon_use "select id, coupon_id, user_id, order_id, coupon_status, get_time, using_time, used_time, expire_time from coupon_use where (date_format(get_time,'%Y-%m-%d')='$do_date' or date_format(using_time,'%Y-%m-%d')='$do_date' or date_format(used_time,'%Y-%m-%d')='$do_date' or date_format(expire_time,'%Y-%m-%d')='$do_date')" } import_order_status_log(){ import_data order_status_log "select id, order_id, order_status, operate_time from order_status_log where date_format(operate_time,'%Y-%m-%d')='$do_date'" } import_user_info(){ import_data "user_info" "select id, login_name, nick_name, name, phone_num, email, user_level, birthday, gender, create_time, operate_time from user_info where (DATE_FORMAT(create_time,'%Y-%m-%d')='$do_date' or DATE_FORMAT(operate_time,'%Y-%m-%d')='$do_date')" } import_order_detail(){ import_data order_detail "select id, order_id, sku_id, sku_name, order_price, sku_num, create_time, source_type, source_id, split_total_amount, split_activity_amount, split_coupon_amount from order_detail where DATE_FORMAT(create_time,'%Y-%m-%d')='$do_date'" } import_payment_info(){ import_data "payment_info" "select id, out_trade_no, order_id, user_id, payment_type, trade_no, total_amount, subject, payment_status, create_time, callback_time from payment_info where (DATE_FORMAT(create_time,'%Y-%m-%d')='$do_date' or DATE_FORMAT(callback_time,'%Y-%m-%d')='$do_date')" } import_comment_info(){ import_data comment_info "select id, user_id, sku_id, spu_id, order_id, appraise, create_time from comment_info where date_format(create_time,'%Y-%m-%d')='$do_date'" } import_order_refund_info(){ import_data order_refund_info "select id, user_id, order_id, sku_id, refund_type, refund_num, refund_amount, refund_reason_type, refund_status, create_time from order_refund_info where date_format(create_time,'%Y-%m-%d')='$do_date'" } import_sku_info(){ import_data sku_info "select id, spu_id, price, sku_name, sku_desc, weight, tm_id, category3_id, is_sale, create_time from sku_info where 1=1" } import_base_category1(){ import_data "base_category1" "select id, name from base_category1 where 1=1" } import_base_category2(){ import_data "base_category2" "select id, name, category1_id from base_category2 where 1=1" } import_base_category3(){ import_data "base_category3" "select id, name, category2_id from base_category3 where 1=1" } import_base_province(){ import_data base_province "select id, name, region_id, area_code, iso_code, iso_3166_2 from base_province where 1=1" } import_base_region(){ import_data base_region "select id, region_name from base_region where 1=1" } import_base_trademark(){ import_data base_trademark "select id, tm_name from base_trademark where 1=1" } import_spu_info(){ import_data spu_info "select id, spu_name, category3_id, tm_id from spu_info where 1=1" } import_favor_info(){ import_data favor_info "select id, user_id, sku_id, spu_id, is_cancel, create_time, cancel_time from favor_info where 1=1" } import_cart_info(){ import_data cart_info "select id, user_id, sku_id, cart_price, sku_num, sku_name, create_time, operate_time, is_ordered, order_time, source_type, source_id from cart_info where 1=1" } import_coupon_info(){ import_data coupon_info "select id, coupon_name, coupon_type, condition_amount, condition_num, activity_id, benefit_amount, benefit_discount, create_time, range_type, limit_num, taken_count, start_time, end_time, operate_time, expire_time from coupon_info where 1=1" } import_activity_info(){ import_data activity_info "select id, activity_name, activity_type, start_time, end_time, create_time from activity_info where 1=1" } import_activity_rule(){ import_data activity_rule "select id, activity_id, activity_type, condition_amount, condition_num, benefit_amount, benefit_discount, benefit_level from activity_rule where 1=1" } import_base_dic(){ import_data base_dic "select dic_code, dic_name, parent_code, create_time, operate_time from base_dic where 1=1" } import_order_detail_activity(){ import_data order_detail_activity "select id, order_id, order_detail_id, activity_id, activity_rule_id, sku_id, create_time from order_detail_activity where date_format(create_time,'%Y-%m-%d')='$do_date'" } import_order_detail_coupon(){ import_data order_detail_coupon "select id, order_id, order_detail_id, coupon_id, coupon_use_id, sku_id, create_time from order_detail_coupon where date_format(create_time,'%Y-%m-%d')='$do_date'" } import_refund_payment(){ import_data refund_payment "select id, out_trade_no, order_id, sku_id, payment_type, trade_no, total_amount, subject, refund_status, create_time, callback_time from refund_payment where (DATE_FORMAT(create_time,'%Y-%m-%d')='$do_date' or DATE_FORMAT(callback_time,'%Y-%m-%d')='$do_date')" } import_sku_attr_value(){ import_data sku_attr_value "select id, attr_id, value_id, sku_id, attr_name, value_name from sku_attr_value where 1=1" } import_sku_sale_attr_value(){ import_data sku_sale_attr_value "select id, sku_id, spu_id, sale_attr_value_id, sale_attr_id, sale_attr_name, sale_attr_value_name from sku_sale_attr_value where 1=1" } case $1 in "order_info") import_order_info ;; "base_category1") import_base_category1 ;; "base_category2") import_base_category2 ;; "base_category3") import_base_category3 ;; "order_detail") import_order_detail ;; "sku_info") import_sku_info ;; "user_info") import_user_info ;; "payment_info") import_payment_info ;; "base_province") import_base_province ;; "activity_info") import_activity_info ;; "cart_info") import_cart_info ;; "comment_info") import_comment_info ;; "coupon_info") import_coupon_info ;; "coupon_use") import_coupon_use ;; "favor_info") import_favor_info ;; "order_refund_info") import_order_refund_info ;; "order_status_log") import_order_status_log ;; "spu_info") import_spu_info ;; "activity_rule") import_activity_rule ;; "base_dic") import_base_dic ;; "order_detail_activity") import_order_detail_activity ;; "order_detail_coupon") import_order_detail_coupon ;; "refund_payment") import_refund_payment ;; "sku_attr_value") import_sku_attr_value ;; "sku_sale_attr_value") import_sku_sale_attr_value ;; "all") import_base_category1 import_base_category2 import_base_category3 import_order_info import_order_detail import_sku_info import_user_info import_payment_info import_base_trademark import_activity_info import_cart_info import_comment_info import_coupon_use import_coupon_info import_favor_info import_order_refund_info import_order_status_log import_spu_info import_activity_rule import_base_dic import_order_detail_activity import_order_detail_coupon import_refund_payment import_sku_attr_value import_sku_sale_attr_value ;; esac
(2)增加腳本執行權限
[atguigu@hadoop102 bin]$ chmod +x mysql_to_hdfs.sh
2)腳本使用
[atguigu@hadoop102 bin]$ mysql_to_hdfs.sh all 2020-06-15
2.5.4 項目經驗
Hive中的Null在底層是以“\N”來存儲,而MySQL中的Null在底層就是Null,爲了保證數據兩端的一致性。在導出數據時採用--input-null-string和--input-null-non-string兩個參數。導入數據時採用--null-string和--null-non-string。
第三章 數據環境準備
3.1 Hive安裝部署
安裝過程參見:https://www.cnblogs.com/wkfvawl/p/15594717.html