拼夕夕購物送錯地址了,這是 bug 嗎?
大家好,我是君哥。
雖然在拼夕夕上購物不多,但每年會有幾次,每次都是看好商品后直接下單。不過這次有趣的是,訂單顯示已簽收,我才發現買的東西被送到了老東家的前臺,這個公司是我 5 年前的公司。
為什么下單會下錯呢?我每次購物都是直接下單,因為已經很久沒有變過默認收貨地址了,這次是因為默認地址被修改了才配送錯誤。
圖片
1.默認地址
對每個電商用戶來說,都會有幾個收貨地址,比如家庭住址、公司地址、老家地址、親戚家地址等。但都會有一個默認地址,這個地址是最常用的一個收貨地址,一般不會修改。
那我的默認地址為什么會被修改了呢?離開老東家已經 5 年了,我修改默認地址也不會改成這個地址啊。況且近兩年我每次在夕夕上買東西都是直接下單。
那一個地址該怎樣保存呢?拼夕夕上添加一個地址如下圖:
圖片
一個地址的數據大概包括:省、市、區/縣、姓名、電話、街道/詳細地址,然后這些數據需要關聯用戶id。我們可以設計一張“用戶收貨地址”表:
CREATE TABLE`user_address` (
`id`BIGINT PRIMARY KEY AUTO_INCREMENT, -- 主鍵 ID
`user_id`BIGINTNOTNULL, -- 用戶 ID
`user_name`VARCHAR(50) NOTNULL, -- 收貨人姓名
`phone`VARCHAR(20) NOTNULL, -- 收貨人電話
`country`VARCHAR(50) NOTNULL, -- 國家(支持國際化)
`province`VARCHAR(50) NOTNULL, -- 省
`city`VARCHAR(50) NOTNULL, -- 市
`district`VARCHAR(50) DEFAULTNULL, -- 區/縣
`street`VARCHAR(255) NOTNULL, -- 街道/詳細地址
`postal_code`VARCHAR(20) DEFAULTNULL, -- 郵編
`is_default`TINYINT(1) DEFAULT 0, -- 是否默認地址(0否,1是)
`create_date` DATETIME DEFAULTCURRENT_TIMESTAMP, --創建時間
`update_date` DATETIME ONUPDATECURRENT_TIMESTAMP,--更新時間
`is_deleted`TINYINT(1) DEFAULT 0 -- 邏輯刪除
);
2.修改原因
上面用戶收貨地址表我們關聯了 user_id, 同時用 is_default 字段用來標識是否是默認地址。這樣只有當前用戶在 app 上操作更改時才能修改這個地址。排除賬號盜用、他人操作我的賬戶,那這個地址突然被修改可能是什么原因呢?
2.1 三方應用
有一種可能,手機上的三方應用同步信息到拼多多,導致了默認地址被修改。
2.2 數據庫同步
數據庫增加新節點,假設 MySQL 一主兩從的集群架構,集群中一個節點數據正在同步,但請求已經發到新節點上,如下圖:
圖片
加入 binlog 中最新的兩條改動 SQL 如下:
--把老公司地址改為默認地址
UPDATE user_address SET is_default = 1 WHERE user_id = {userId} AND id = 1;
--把家庭住址改為默認地址
UPDATE user_address SET is_default = 1 WHERE user_id = {userId} AND id = 2;
這時如果剛剛同步完成第 1 條 SQL,第 2 條 SQL 還沒有同步完成,用戶請求過來了,這時取到的默認地址肯定是錯誤的。
2.3 歷史數據
假如 user_address 表設計之初沒有 is_default 這個字段,后來業務發展過程中,產品經理發現這個默認地址非常必要,就提出增加這個字段,而且是必輸字段。作為程序員,歷史數據怎樣處理呢?
- 隨便取表中一條記錄作為客戶的默認地址,這個設計最簡單,但也很不負責任,選的地址可能并不是客戶想要的默認地址;
- 取最新更新的一條記錄作為客戶的默認地址,這個刷數策略看似比較合理,但是也有問題。插入數據時 update_date 給的是系統時間,那 binlog 同步時,多條記錄的 update_date 時間可能很接近,如果程序根據時間來判斷只精確到秒級,這樣多條記錄更新時間一樣 ,只能隨機選擇一條作為默認地址。
2.4 人為錯誤
程序員解決別的問題時,引入了 bug,把我的默認地址給修改了。
3.其他注意
設計客戶收貨地址時,還有其他幾個點需要注意:
- 手機號、郵政編碼合規校驗;
- 地址省、市、區/縣標準化;
- 詳細地址合法性,驗證這個地址是否真的存在;
- 訂單表冗余地址信息,而不是關聯 id,這樣可以確保收貨地址被修改后,訂單信息的地址保持不變;
- 敏感數據加密,比如傳輸加密、日志脫敏,包括:姓名、住址、手機號等;
- 地址修改做權限控制,每個用戶只能操作自己地址。
從用戶體驗方面看,可以考慮下面幾點:
- 對于查詢頻率高的地址,做緩存,提高查詢性能;
- 智能地址補全,用戶輸入體驗更好;
- 增加地址標簽,比如家、公司、父母家等。
4.總結
一個收貨地址設計,表面看很簡單,但要考慮安全、性能、可擴展和用戶體驗,還是有很多內容的。