后端存储实战课总结(上)

news/2024/4/26 7:44:10/文章来源:https://blog.csdn.net/MrBaymax/article/details/127877796

创建和更新订单

表设计

最少应该有以下几张表:

  1. 订单主表:保存订单基本信息
  2. 订单商品表:保存订单中的商品信息
  3. 订单支付表:保存订单支付和退款信息
  4. 订单优惠表:保存订单的优惠信息

订单主表和字表是一对多关系,关联的外键是订单主表的主键(订单号)。

幂等性

可能出现重复下单的场景:一种是就是用户多点了,另外就是网络错误导致(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 直接访问,省事不占带宽,同时,对象存储云服务也提供了自带 CDN(Content Delivery Network)服务,响应时间比直接请求业务服务器更短。云服务厂商还会提供针对性优化,比如说缩放和转码服务。

商品介绍在商详页中占得比重是最大的,包含了大量的带格式文字、图片和视频。其中图片和视频自然要存放在对象存储里面,商品介绍的文本,一般都是随着商详页一起静态化,保存在 HTML 文件中。

静态化是相对于动态页面来说的。一般我们部署到 Tomcat 中的 Web 系统,返回的都是动态页面,也就是在 Web 请求时,动态生成的。比如说商详页,一个 Web 请求过来,带着 SKUID,Tomcat 中的商详页模块,再去访问各种数据库、调用后端服务,动态把这个商详页拼出来,返回给浏览器。
商详页的绝大部分内容都是商品介绍,它是不怎么变的。那不如就把这个页面事先生成好,保存成一个静态的 HTML,访问商详页的时候,直接返回这个 HTML。这就是静态化。
商详页静态化之后,不仅仅是可以节省服务器资源,还可以利用 CDN 加速,把商详页放到离用户最近的 CDN 服务器上,让商详页访问更快。
至于商品价格、促销信息等这些需要频繁变动的信息,不能静态化到页面中,可以在前端页面使用 AJAX 请求商品系统动态获取。这样就兼顾了静态化带来的优势,也能解决商品价格等信息需要实时更新的问题。

购物车

场景

  1. 未登录,浏览器加购,关闭浏览器再打开,加购商品应该存在
  2. 未登录,浏览器加购,然后登录,加购的物品存在
  3. 登录后再注销,关闭浏览器,步骤 2 中加购的商品不登录看不到(未登录特定账号看到的购物车是空的)
  4. 手机登录,步骤 2 中的加购的存在

原则

用户未登录,需要临时暂存购物车中的商品;

用户登录,将暂存购物车的商品加入到用户购物车,清空暂存购物车;

用户登录后,各端同步用户购物车。

设计

暂存购物车

如果存在服务端,需要唯一标识存储,浪费服务端资源,故需要存储在客户端。

存在客户端的途径:SESSION 不合适(时间短,SESSION 数据其实还是在服务端);Cookie 存储的话,实现简单,通过服务端读写 Cookie 实现具体的加减购物车合并购物车逻辑;LocalStorage 存储的话,实现复杂(客户端和服务端都需要实现逻辑),但是容量大,不用每次请求都携带,节省带宽。

用户购物车

还是推荐 MySQL,如果用 Redis 存在丢数据的情况,查询方式和事务都不如 MySQL。

引入 Redis 需考虑问题:

  1. 不同用户不同购物车,缓存命中率不高,为了维护缓存,还提高了系统复杂度,有没有必要
  2. Redis 的缓存更新策略

账户系统

目的

对账系统存在的目的:来核对、矫正账户系统和其他系统之间的数据差异。

每个账户系统都不是孤立存在的,至少要和财务、订单、交易这些系统有着密切的关联。理想情况下,账户系统内的数据应该是自洽的。所有用户的账户余额加起来,应该等于这个电商公司在银行专用账户的总余额。账户系统的数据也应该和其他系统的数据能对的上。比如说,每个用户的余额应该能和交易系统中充值记录,以及订单系统中的订单对的上。

记录流水,可以修改由于系统 bug 或者认为篡改导致的账户余额的问题。流水的数据模型至少要包含:流水 ID、交易金额、交易时间戳、交易双方的系统、账户、交易单号等信息。

原则

  1. 流水记录只能新增,一旦记录成功不允许修改和删除。即使是由于正当原因需要取消一笔已经完成的交易,也不应该去删除交易流水。正确的做法是再记录一笔“取消交易”的流水。
  2. 流水号必须是递增的,我们需要用流水号来确定交易的先后顺序。

在对账的时候,一旦出现了流水和余额不一致,并且无法通过业务手段来确定到底是哪儿记错了的情况,一般的处理原则是以交易流水为准来修正余额数据,这样才能保证后续的交易能“对上账”。

方案

首先要保证只有记录流水的时候更新余额,不可以将更新余额单独提供;其次使用数据库事务,记录流水和修改余额两个操作要么都成功,要么都失败。

MySQL 事务和 ACID 相关内容不在此赘述

分布式事务

背景

分布式环境下跨系统数据一致性问题。

方案

2PC、3PC、TCC、Saga、本地消息表都是分布式事务的解决方案

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_39017.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1.1 统计学习方法的定义与分类

统计学习方法的定义与分类统计学习的概念统计学习的定义统计学习运用到的领域统计学习的步骤统计学习的分类统计学习的概念 统计学习的定义 统计学习 (Statistical Machine Learning) 是关于计算机基于数据构建概率统计模型并运用模型对数据进行预测与分析的一门学科。 以计…

第五站:操作符(终幕)(一些经典的题目)

目录 一、分析下面的代码 二、统计二进制中1的个数 解一:(求出每一个二进制位,来统计1的个数) 解二:(利用左我们移或右移操作符和按位与) 解三:(效率最高的解法&…

【iOS】—— GET和POST以及AFNetworking框架

GET和POST以及AFNetworking框架 文章目录GET和POST以及AFNetworking框架GET和POSTGET和POST区别GETGET请求步骤GET请求代码POSTPOST请求步骤POST请求代码AFNetworking简介添加头文件GETGET方法GET方法参数GET方法代码样例POSTPOST方法第一种:第二种:先来…

C++:STL之Vector实现

vector各函数 #include<iostream> #include<vector> using namespace std;namespace lz {//模拟实现vectortemplate<class T>class vector{public:typedef T* iterator;typedef const T* const_iterator;//默认成员函数vector(); …

Netty进阶——粘包与半包(代码示例)

目录一、消息粘包和消息半包的概述1.1、消息粘包1.2、消息半包二、粘包现象代码示例2.1、粘包现象服务端示例代码2.2、粘包现象客户端示例代码2.3、分别启动服务端&#xff0c;客户端&#xff0c;查看服务端结果输出三、半包现象代码示例3.1、半包现象服务端示例代码3.2、半包现…

【强化学习论文】小样本策略泛化的提示决策转换器

文献题目&#xff1a;Prompting Decision Transformer for Few-Shot Policy Generalization 摘要 人类可以利用先前的经验并从少量演示中学习新任务。与旨在通过更好的算法设计实现快速适应的离线元强化学习相比&#xff0c;我们研究了架构归纳偏差对少样本学习能力的影响。我…

不懂单链表? 这篇文章就帮你搞明白

坚持看完&#xff0c;结尾有思维导图总结 链表对指针的操作要求不低链表的概念链表的特性链表的功能(最重要)定义和初始化头插头删细节说明尾插尾删寻找链表元素与打印链表在 某位置后插入删除在某位置的插入删除销毁链表链表的概念 什么是链表 官方概念&#xff1a;链表是一种…

显卡---显卡驱动---CUDA---Cudnn

1. 背景 最近在follow百度的CAE这篇论文时&#xff0c;源码需要的环境为&#xff1a; python 3.7 cuda: 11.0 cudnn: 8.0.4 gcc 8.2 该版本要求与我目前使用的服务器上的CUDA版本不相符合。因此搜索了一篇国外小哥的文章&#xff0c;讲述了如何在一台服务器上安装多个CUDA和Cud…

Node之Express学习笔记

一.Express 1.1什么是Express Express的作用和Node.js内置的http模块类似 专门用来创建Web服务器的 本质&#xff1a;npm上的第三方包&#xff0c;提供快速创建Web服务器的便捷方法 1.2Express能做什么 Web网站服务器&#xff1a;专门提供Web网页资源的服务器 API接口服务器&…

FPGA----ZCU106基于axi-hp通道的pl与ps数据交互(全网唯一最详)

1、大家好&#xff0c;今天给大家带来的内容是&#xff0c;基于AXI4协议的采用AXI-HP通道完成PL侧数据发送至PS侧&#xff08;PS侧数据发送至PL侧并没有实现&#xff0c;但是保留了PL读取PS测数据的接口&#xff09; 2、如果大家用到SoC这种高级功能&#xff0c;那大家应该对于…

Linux进阶-进程间通信(ipc)

进程间通信&#xff1a;数据传输、资源共享、事件通知、进程控制。 Linux系统下的ipc 早期unix系统 ipc&#xff1a;管道&#xff08;数据传输&#xff09;、信号&#xff08;事件通知&#xff09;、fifo&#xff08;数据传输&#xff09;。 system-v ipc&#xff08;贝尔实…

Kubernetes之Pod初始化容器

Kubernetes之Pod初始化容器 概述 ​ 初始化是很多编程语言普遍关注的问题&#xff0c;甚至有些编程语言直接支持模式构造来生成初始化程序&#xff0c;这些用于进行初始化的程序结构称为初始化器或初始化列表。初始化代码要首先运行&#xff0c;且只能运行一次&#xff0c;它们…

CAPM资产定价模型

本文是Quantitative Methods and Analysis: Pairs Trading此书的读书笔记。 CAPM(Capital Asset Pricing Model)资产定价模型 这个模型在金融界的影响就是beta这个词的使用。CAPM模型用两个部分的回报之和来解释一个资产的回报。其中一个部分是指市场&#xff08;称为market)…

时间序列:时间序列模型---自回归过程(AutoRegressive Process)

本文是Quantitative Methods and Analysis: Pairs Trading此书的读书笔记。 这次我们构造一个由无限的白噪声实现&#xff08;white noise realization) 组成的时间序列&#xff0c;即。这个由无限数目的项组成的值却是一个有限的值&#xff0c;比如时刻的值为&#xff0c; 而…

Magic Leap 2设计和开发幕后花絮

Magic Leap今年发布新款AR头显Magic Leap 2&#xff0c;相比于上一代Magic Leap 1&#xff0c;新品更专注于B端场景&#xff0c;自公布以来&#xff0c;Magic Leap不仅对公司策略、理念更加透明&#xff0c;也不断公开ML2产品设计背后的思考。相比于ML1&#xff0c;ML2的设计有…

粒子群算法查找函数最小值

实现 函数 F01、F06 的优化测试 以下内容是现有算法的运行结果、调参分析、及代码实现&#xff0c;用于给其他人提供参考&#xff0c;懒得改了hh 1. 运行结果 参数 w 0.5 &#xff08;可更改&#xff09; c1 2.0 &#xff08;可更改&#xff09; c2 2.0 &#xff08;可更改&…

Echart 柱状图,X轴斜着展示

option { color: [‘#3398DB’], tooltip: { trigger: ‘axis’, axisPointer: { // 坐标轴指示器&#xff0c;坐标轴触发有效 type: ‘shadow’ // 默认为直线&#xff0c;可选为&#xff1a;‘line’ | ‘shadow’ } }, grid: { left: ‘3%’, right: ‘4%’, bottom: ‘3%’…

iPhone升级iOS 16后出现提示“面容ID不可用”怎么办?

最近&#xff0c;很多用户在苹果社区反馈&#xff0c;iPhone升级iOS 16后Face ID不能用了&#xff0c;尝试重置Face ID时&#xff0c;系统会弹窗提示“面容ID不可用&#xff0c;稍后尝试设置面容ID。” 如果你的iPhone在没有摔落手机或是手机进水的情况下出现这个弹窗&#xff…

【uniapp小程序】路由跳转navigator传参封装

文章目录&#x1f34d;前言&#x1f34b;正文1、看官网1.1 navigator API 介绍1.2、路由跳转参数传递1.3、五种常见的跳转方式1.3.1 uni.navigateTo(OBJECT)1.3.2 uni.redirectTo(OBJECT)1.3.3 uni.reLaunch(OBJECT)1.3.4 uni.switchTab(OBJECT)1.3.5 uni.navigateBack(OBJECT)…