《后端存储实战课》 的学习笔记,欢迎阅读斧正。
创建和更新订单
表设计
最少应该有以下几张表:
- 订单主表:保存订单基本信息
- 订单商品表:保存订单中的商品信息
- 订单支付表:保存订单支付和退款信息
- 订单优惠表:保存订单的优惠信息
订单主表和字表是一对多关系,关联的外键是订单主表的主键(订单号)。
幂等性
可能出现重复下单的场景:一种是就是用户多点了,另外就是网络错误导致(RPC、网关的重试机制)
解决方案:通过一个专门生成全局唯一订单号的服务,插入数据的时候将其保存
ABA 问题
更新订单相关信息的时候可能出现。
解决方案:在表中加个时间戳或者版本的字段,每次查询的时候将其返回,更新的时候要比较下当前订单数据的版本号,是否和预期的一致。不一致直接拒绝更新,一致的话在一个事务中更新数据的同时将版本号+1。
商品详情页
问题
一是高并发,商品的详情页每天都会有很高的 DAU(日均访问次数)。
二是商品数据规模的问题,比如下图中要存储的:
方案
基本信息相对来说比较固定,可以在数据库中建表存储,也要提供缓存(比如 Redis、Memcached)帮助系统抗一些读请求。另外要注意的是,要保留商品的历史版本,因为订单中关联的商品数据必须是下单哪个时刻的商品数据,可以用一张历史表来保存。
商品参数指商品特征,比如内存大小、屏幕尺寸、口红色号等,和基本属性一样,是结构化的数据,但是不同类型的商品参数也是不一样的。对于属性不固定的数据来说,可以使用 MongoDB 来存储,因为 MongoDB 没有数据表要有固定结构的要求。
MongoDB 中的每一行数据,在存储层就是简单地被转化成 BSON 格式后存起来,这个 BSON 就是一种更紧凑的 JSON。所以,即使在同一张表里面,它每一行数据的结构都可以是不一样的。当然,这样的灵活性也是有代价的,MongoDB 不支持 SQL,多表联查和复杂事务比较孱弱,不太适合存储一般的数据。
图片和视频由于占用空间比较大,一般的存储方式是在数据库中只保留图片视频的 id 或者 url,实际的图片视频以文件方式存储,可以保存在对象存储(Object Storage)中。
对象存储可以简单理解为无限容量的大文件 KV 存储,key 是唯一的,对象是 value,可以通过 key 操作 value(写入、访问、删除)。对象存储提供了客户端 API,可以在 Web 页面或者 app 中直接访问,而不用通过后端服务。页面通过提供的 URL 直接访问,省事不占带宽