1.分布式ID生成解决方案
一.数据库分片
- 如何实现数据库分片?我们通常会使用mycat数据库中间件来解决。
MyCat是一个开源的分布式数据库系统,是一个实现了MySQL协议的服务器,前端用户可以把它看作是一个数据库代理,用MySQL客户端工具和命令行访问,而其后端可以用MySQL原生协议与多个MySQL服务器通信,也可以用JDBC协议与大多数主流数据库服务器通信,其核心功能是分表分库,即将一个大表水平分割为N个小表,存储在后端MySQL服务器里或者其他数据库里。 - MyCat发展到目前的版本,已经不是一个单纯的MySQL代理了,它的后端可以支持MySQL、SQL Server、Oracle、DB2、PostgreSQL等主流数据库,也支持MongoDB这种新型NoSQL方式的存储,未来还会支持更多类型的存储。而在最终用户看来,无论是那种存储方式,在MyCat里,都是一个传统的数据库表,支持标准的SQL语句进行数据的操作,这样一来,对前端业务系统来说,可以大幅降低开发难度,提升开发速度。
二.分布式ID生成解决方案
- UUID
优点 :
1)简单,代码方便。
2)生成ID性能非常好,基本不会有性能问题。
3)全球唯一,在遇见数据迁移,系统数据合并,或者数据库变更等情况下,可以从容应对。
缺点 :
1)没有排序,无法保证趋势递增。
2)UUID往往是使用字符串存储,查询的效率比较低。
3)存储空间比较大,如果是海量数据库,就需要考虑存储量的问题。
4)传输数据量大
5)不可读。 - Redis生成ID
当使用数据库来生成ID性能不够要求的时候,我们可以尝试使用Redis来生成ID。这主要依赖于Redis是单线程的,所以也可以用生成全局唯一的ID。可以用Redis的原子操作INCR和INCRBY来实现。
优点 :
1)不依赖于数据库,灵活方便,且性能优于数据库。
2)数字ID天然排序,对分页或者需要排序的结果很有帮助。
缺点 :
1)如果系统中没有Redis,还需要引入新的组件,增加系统复杂度。
2)需要编码和配置的工作量比较大。
3)网络传输造成性能下降。 - 开源算法snowflak
snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个ID),最后还有一个符号位,永远是0
三.snowflake快速入门
- 快速入门
- 新建工程,将资料/工具类下的IdWorker.java拷贝到工程中
- 编写代码
- 配置分布式ID生成器
- 将IdWorker.java拷贝到qingcheng_common_service工程com.qingcheng.util包中
- 在qingcheng_service_goods工程resources下新增applicationContextservice.xml
2.新增和修改商品
一.概念与表结构分析
- SPU与SKU
(一)SPU = Standard Product Unit (标准产品单位)
SPU是商品信息聚合的最小单位,是一组可复用、易检索的标准化信息的集合,该集合描述了一个产品的特性。
通俗点讲,属性值、特性相同的商品就可以称为一个SPU。
(二)SKU=stock keeping unit(库存量单位)
SKU即库存进出计量的单位, 可以是以件、盒、托盘等为单位。
SKU是物理上不可分割的最小存货单元。在使用时要根据不同业态,不同管理模式来处理。在服装、鞋类商品中使用最多最普遍。 - 表结构分析
- tb_spu 表
- tb_sku 表
- tb_spu 表
二.需求与实现思路
- 实现思路
前端传递给后端的数据格式
三.SPU与SKU列表的保存
- qingcheng_pojo工程创建组合实体类
- qingcheng_interface工程SpuService新增方法定义
- qingcheng_service_goods工程SpuServiceImpl实现此方法
注意!!!这个方法要对两个表进行操作,需要添加事务。
我们在类上添加@Transactional注解
在@Service注解中指定接口为SpuService.class - qingcheng_web_manager工程SpuController修改add方法
四.建立分类与品牌的关联
- 需求:
(1)为什么要建立分类与品牌的关联?因为我们在前台搜索时需要通过分类找到品牌列表。
(2)分类与品牌是什么关系? 多对多。
(3)在什么地方添加关系?我们不在后台单独实现分类与品牌的关联,而是在添加商品时自动添加关联。 - 实现思路:
(1)设计中间表tb_category_brand表
(2)创建实体类、数据访问接口
(3)在添加商品的saveGoods方法中添加代码逻辑 ,将SPU的品牌编号和分类编号 一起插入到(中间表)中。 - 创建实体类
这个表是联合主键,所以templateId和brandId都有@Id注解 - 新建数据访问接口
- 修改saveGoods方法,添加以下代码
五.根据ID查询商品
- 需求 : 根据id 查询SPU和SKU列表 ,显示效果如下:
- qingcheng_interface工程SpuService新增方法定义
- qingcheng_service_goods工程SpuServiceImpl实现此方法
- qingcheng_web_manager工程SpuController新增方法
六.保存修改
- 思路 :
(1)修改与新增共用同一个方法
(2)通过spu的id判断当前操作是新增还是修改
(3)如果是新增需要设置spu的id,对spu执行的是insert操作
(4) 如果修改则需要删除原来的sku列表,对spu执行的是updateByPrimaryKeySelective操作。
(5)sku列表的插入部分的代码要判断sku是否有id,如果有id则不重新生成id - 代码实现 :
修改SpuServiceImpl的saveGoods方法,修改后代码如下:
七.未启用规格的sku处理
- 需求分析:
有些商品是没有区分规格的,也就是一个spu对应一个sku ,这种情况下sku列表只传递一条记录,并且没有规格(spec)属性,我们要对其进行判断,避免因空值产生 - 实现思路:
在saveGoods方法的sku列表循环中添加代码,判断
3.商品审核与上下架
一.商品审核
- 需求分析与实现思路
商品审核:新录入的商品是未审核状态,也是未上架状态。
实现思路:
(1)修改审核状态,如果审核状态为1则上架状态也修改为1
(2)记录商品审核记录
(3)记录商品日志 - SpuService新增方法定义
- SpuServiceImpl实现方法
- SpuController新增方法
二.下架商品
- 需求与实现思路
下架商品,修改上下架状态为下架。下架商品不修改审核状态。
下架商品需要记录商品日志。 - SpuService新增方法定义
- SpuServiceImpl实现方法
- SpuController新增方法
三.上架商品
- 需求分析
将商品修改为上架状态,需要验证该商品是否审核通过,未审核通过的商品不能上架。
上架商品需要记录商品日志。 - 必须是通过审核的商品才能上架
SpuService新增方法定义 - SpuServiceImpl实现方法
- SpuController新增方法
四.批量上下架
- 需求分析
前端传递一组商品ID,后端进行批量上下架处理,处理后给前端返回处理的条数 - SpuService新增方法定义
- SpuServiceImpl实现方法
- SpuController新增方法
4.删除与还原商品
一.需求分析
- 删除商品并非物理删除(真正的执行删除数据),而是通过将表中某字段标记为删除状态。
还原商品实际就是将删除状态再修改回来。
如果商品需要物理删除,必须是先逻辑删除才能进行物理删除,删除前需要检查状态。
二.实现思路
- 逻辑删除商品,修改spu表is_delete字段为1
商品回收站显示spu表is_delete字段为1的记录
回收商品,修改spu表is_delete字段为0