面试题答案
一键面试整体架构设计
- MySQL部分:
- 数据库表设计:保留原有的订单表、用户表、商品表等。订单表存储订单的详细信息,通过外键关联用户表和商品表,例如订单表中有
user_id
关联用户表的主键,product_id
关联商品表的主键。订单表还应包含订单状态字段status
和订单创建时间字段create_time
。 - 数据持久化:MySQL作为主要的数据存储,负责长期保存所有业务数据。
- 数据库表设计:保留原有的订单表、用户表、商品表等。订单表存储订单的详细信息,通过外键关联用户表和商品表,例如订单表中有
- Redis部分:
- 有序集合设计:使用Redis的有序集合(Sorted Set)来辅助查询。有序集合的成员(member)可以设计为订单ID,分值(score)设置为订单的创建时间的时间戳。这样可以根据时间范围快速定位订单ID。同时,可以针对不同的订单状态分别创建有序集合,例如名为
orders_status_1
,orders_status_2
等,分别对应不同状态的订单,集合中的成员同样为订单ID,分值为订单创建时间戳。
- 有序集合设计:使用Redis的有序集合(Sorted Set)来辅助查询。有序集合的成员(member)可以设计为订单ID,分值(score)设置为订单的创建时间的时间戳。这样可以根据时间范围快速定位订单ID。同时,可以针对不同的订单状态分别创建有序集合,例如名为
数据同步机制
- 新增订单:
- 当有新订单生成时,首先在MySQL的订单表中插入完整的订单记录,同时获取生成的订单ID。
- 根据订单状态,将订单ID添加到对应的Redis有序集合中,分值为订单的创建时间戳。例如,如果订单状态为
status_1
,则执行ZADD orders_status_1 [时间戳] [订单ID]
。
- 订单状态更新:
- 在MySQL中更新订单状态。
- 从旧状态对应的Redis有序集合中移除该订单ID,然后添加到新状态对应的Redis有序集合中。例如,订单从
status_1
变为status_2
,先执行ZREM orders_status_1 [订单ID]
,再执行ZADD orders_status_2 [时间戳] [订单ID]
。
查询流程
- 获取某一日期范围内不同状态的订单:
- 计算日期范围对应的时间戳范围,假设开始时间戳为
start_timestamp
,结束时间戳为end_timestamp
。 - 对于每种订单状态,在对应的Redis有序集合中查询符合时间范围的订单ID。例如,对于
status_1
状态的订单,执行ZRANGEBYSCORE orders_status_1 start_timestamp end_timestamp
,获取符合条件的订单ID列表。
- 计算日期范围对应的时间戳范围,假设开始时间戳为
- 获取订单关联的用户及商品信息:
- 利用得到的订单ID列表,在MySQL的订单表中查询订单的详细信息。由于订单表关联了用户表和商品表,可以通过外键约束在查询订单时,使用
JOIN
操作同时获取关联的用户及商品信息。例如:
SELECT orders.*, users.*, products.* FROM orders JOIN users ON orders.user_id = users.id JOIN products ON orders.product_id = products.id WHERE orders.id IN ([订单ID列表]);
- 利用得到的订单ID列表,在MySQL的订单表中查询订单的详细信息。由于订单表关联了用户表和商品表,可以通过外键约束在查询订单时,使用
通过这种方式,利用Redis有序集合的快速范围查询能力,结合MySQL的强大数据存储和关联查询能力,能够高效地实现复杂电商业务系统中的订单查询需求。