一、需求背景
最近接手的項目是個電商項目,一開始只是商品購買支付這樣的常規功能。經過了n多個版本的迭代,錢包系統的需求終歸還是被PM提了出來。對於這樣的需求後,雖然在我的意料之中,但是卻感覺很蛋疼。畢竟說起來,涉及錢的東西,稍微哪一筆流水出個差錯什麼的,那麼作爲程序猿的我們絕對來說是脫不了干係的。因此,此時此刻的我深感責任重大。
二、需求詳情
爲了方便講解,我們此處簡化需求,實際上會複製很多。不過大體的設計思路是一致的。
操作 | 結果 |
---|---|
用戶下單 | 商家可用餘額增加 |
商家提現 | 商家可用餘額減少 |
簡單的說,就兩個需求
- 用戶下單,多個用戶同時下單,存在併發數據同步問題,需要保證商家餘額的準確性。
- 商家提現,商家提現是一筆一筆進行,基本不會存在併發問題。商家餘額容易保證其準確性。
三、實現思路
從三個賬戶視角去記錄錢包流水,一個是用戶(消費者)的視角,另一個是商家餘額的視角,最後一個現金的視角。那麼只要這三個賬戶的餘額加起來,是0,說明賬目是沒問題的,帳是平的。所以錢包流水實際上需要設計三個數據表。
最終,只要保證錢包流水的準確性。那麼類似用戶錢包餘額等各種賬目的計算都可以依據錢包流水統計出其準確值。
四、數據庫設計
以下數據表可根據自身業務適當新增一些字段,如備註,操作類型,關聯id等等。此處爲了方便講解,儘量簡化了。
1.商家流水錶
CREATE TABLE `user_statements` (
`user_statements_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
`user_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '用戶id',
`available_vary_amount` decimal(11,2) DEFAULT '0.00' COMMENT '可用餘額的變動金額(包含正負)',
`created_time` bigint(20) DEFAULT '0' COMMENT '創建時間',
PRIMARY KEY (`user_statements_id`),
KEY `user_id` (`user_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商家流水錶';
2.消費流水錶
CREATE TABLE `consume_statements` (
`consume_statements_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
`user_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '用戶id',
`consume_vary_amount` decimal(11,2) DEFAULT '0.00' COMMENT '消費的變動金額(包含正負)',
`created_time` bigint(20) DEFAULT '0' COMMENT '創建時間',
PRIMARY KEY (`consume_statements_id`),
KEY `user_id` (`user_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='消費流水錶';
3.現金流水錶
CREATE TABLE `cash_statements` (
`cash_statements_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
`user_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '用戶id',
`cash_vary_amount` decimal(11,2) DEFAULT '0.00' COMMENT '現金的變動金額(包含正負)',
`created_time` bigint(20) DEFAULT '0' COMMENT '創建時間',
PRIMARY KEY (`cash_statements_id`),
KEY `user_id` (`user_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='現金流水錶';
五、具體實現
用戶下單
- 商家流水錶插入數據。
- 消費流水錶插入數據。
商家提現
- 商家流水錶插入數據。
- 現金流水錶插入數據。
總結
本文提供了錢包系統的大致實現思路。