暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

拼夕夕购物送错地址了,这是 bug 吗?

君哥聊技术 2025-04-22
155

大家好,我是君哥。

虽然在拼夕夕上购物不多,但每年会有几次,每次都是看好商品后直接下单。不过这次有趣的是,订单显示已签收,我才发现买的东西被送到了老东家的前台,这个公司是我 5 年前的公司。

为什么下单会下错呢?我每次购物都是直接下单,因为已经很久没有变过默认收货地址了,这次是因为默认地址被修改了才配送错误。

1.默认地址

对每个电商用户来说,都会有几个收货地址,比如家庭住址、公司地址、老家地址、亲戚家地址等。但都会有一个默认地址,这个地址是最常用的一个收货地址,一般不会修改。

那我的默认地址为什么会被修改了呢?离开老东家已经 5 年了,我修改默认地址也不会改成这个地址啊。况且近两年我每次在夕夕上买东西都是直接下单。

那一个地址该怎样保存呢?拼夕夕上添加一个地址如下图:

一个地址的数据大概包括:省、市、区/县、姓名、电话、街道/详细地址,然后这些数据需要关联用户id。我们可以设计一张“用户收货地址”表:

CREATE TABLE`user_address` (
`id`BIGINT PRIMARY KEY AUTO_INCREMENT,        -- 主键 ID
`user_id`BIGINTNOTNULL,                     -- 用户 ID
`user_name`VARCHAR(50NOTNULL,              -- 收货人姓名
`phone`VARCHAR(20NOTNULL,                  -- 收货人电话
`country`VARCHAR(50NOTNULL,                -- 国家(支持国际化)
`province`VARCHAR(50NOTNULL,               -- 省
`city`VARCHAR(50NOTNULL,                   -- 市
`district`VARCHAR(50DEFAULTNULL,           -- 区/县
`street`VARCHAR(255NOTNULL,                -- 街道/详细地址
`postal_code`VARCHAR(20DEFAULTNULL,        -- 邮编
`is_default`TINYINT(1DEFAULT 0,             -- 是否默认地址(0否,1是)
`create_date` DATETIME DEFAULTCURRENT_TIMESTAMP,  --创建时间
`update_date` DATETIME ONUPDATECURRENT_TIMESTAMP,--更新时间
`is_deleted`TINYINT(1DEFAULT 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 这个字段,后来业务发展过程中,产品经理发现这个默认地址非常必要,就提出增加这个字段,而且是必输字段。作为程序员,历史数据怎样处理呢?

  1. 随便取表中一条记录作为客户的默认地址,这个设计最简单,但也很不负责任,选的地址可能并不是客户想要的默认地址;
  2. 取最新更新的一条记录作为客户的默认地址,这个刷数策略看似比较合理,但是也有问题。插入数据时 update_date 给的是系统时间,那 binlog 同步时,多条记录的 update_date 时间可能很接近,如果程序根据时间来判断只精确到秒级,这样多条记录更新时间一样 ,只能随机选择一条作为默认地址。

2.4 人为错误

程序员解决别的问题时,引入了 bug,把我的默认地址给修改了。

3.其他注意

设计客户收货地址时,还有其他几个点需要注意:

  1. 手机号、邮政编码合规校验;
  2. 地址省、市、区/县标准化;
  3. 详细地址合法性,验证这个地址是否真的存在;
  4. 订单表冗余地址信息,而不是关联 id,这样可以确保收货地址被修改后,订单信息的地址保持不变;
  5. 敏感数据加密,比如传输加密、日志脱敏,包括:姓名、住址、手机号等;
  6. 地址修改做权限控制,每个用户只能操作自己地址。

从用户体验方面看,可以考虑下面几点:

  1. 对于查询频率高的地址,做缓存,提高查询性能;
  2. 智能地址补全,用户输入体验更好;
  3. 增加地址标签,比如家、公司、父母家等。

4.总结

一个收货地址设计,表面看很简单,但要考虑安全、性能、可扩展和用户体验,还是有很多内容的。

往期精彩:
又老性能又差,为什么好多公司依然选择 RabbitMQ?

45 个知识点,带你入门消息队列!

引入了 Disruptor 后,系统性能大幅提升!

感谢阅读,如果对你有帮助,请点赞和在看。欢迎加我微信:zhujinjun86。

号内回复 seata,下载《阿里分布式中间件Seata从入门到精通》

号内回复 beijing,下载我总结的北京上百家知名科技公司

号内回复 aqs,下载《40张图精通Java AQS》

文章转载自君哥聊技术,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论