您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Model Center   Code  
会员   
   
 
     
   
 订阅
  捐助
在线商城数据库系统设计 思路+效果
 
作者:CyberRye
   次浏览      
2020-9-28
 
编辑推荐:
本文用一个在线商城的例子,介绍了数据库系统设计,展示了设计思路和设计效果,希望能帮助到大家。
本文来自简书,由火龙果软件Linda编辑、推荐。

现在有一个需求,做一个在线商城的系统。需要实现主要流程有:用户登陆,浏览商品,商品加入购物车,选择待支付的商品支付,对商品进行评价。

数据库设计:第一感觉是有用户表,商品表,商家表。然后为了支付,会产生账单表。

现实生活中,用户有很多个不止一个,商品也有很多个,用户表和商品表之间的关系是多对多的关系,多个用户对应多个商品,那么就应该加一个中间表map,这个map在现实生活中的映射其实就是购物车。购物车持有对用户和商品的id引用。所以画出来是这样的。

购物车map作为一个中间表可以解决用户表和商品表的多对多问题

再来看商品表。一个商品,在不同的商家就是不同的商品,不存在一个商品属于两个商家的情况。所以商品和商家应该是多对一的关系。商家表是商品表的父表。商品表是商家表的子表,商品持有商家的id引用。

商品表持有对商家的引用

接下来就是订单表。选好了将要支付的商品,就会生成一张待支付订单。

订单包含的内容包括收货人信息,商品信息。

一张订单对应一个用户,多个商品。

订单和商品的关系是多对多的关系,订单和用户的关系是一对一的关系。

是否订单和商品需要一张中间表关联?先加一张试试。

(一开始我以为订单和购物车关联,因为淘宝的购物流程是从购物车里选择以后提交订单,但后来发现购物车其实只是用户对商品的一个集合的暂存和选择,提交订单并不依赖于购物车的存在与否)

订单表和商品表我理解它们之间的关系是多对多的关系

想要知道某一笔订单有哪些商品,只要select m.* from map m where id = order_id 就可以了。

最后在订单表内加上用户的引用,指明某笔订单是哪个用户的订单。

在订单表内增加对于用户的引用

现实生活中,提交订单后生成订单记录,接下来就是支付订单了。支付订单会产生一笔账单,所以这里新增账单表。但是支付订单真的会产生一笔帐单吗?我看了淘宝的设计,好像是在订单里面加上一笔交易号。而且订单不止交易号,还包括很多状态,

例如付款状态,收货状态,评价状态等。所以先不考虑增加账单表,由订单表完成上述所说的功能。

那付款的内容需要记录下来吗?肯定需要,我认为可能需要一张交易表来完成。一笔订单对应一笔交易。谁持有对于对方的访问呢?从逻辑上看应该是先有订单,再有交易吧。所以是订单持有对交易的访问

增加一个交易表,关联订单表

对商品的评价呢?一个商品可能有多个人来评价,现实中有多个人,所以人和商品评价是多对多的关系?应该是有一张商品--用户中间map表来 记录用户对某个商品的评价。

如果是这样的话,

查看某个商品有哪些用户评价的sql语句可能就是这样写:

SELECT m.* FROM map m where map.product_id =

查看用户评价了哪些商品可能是这样写 :

SELECT m.* FROM map m where m.user_id =

先暂时这样处理。看看后续是否还能改进,或者后续怎样改进。

最后加一张商品评价表,用来记录多对多的用户--商品关系

商品评价表,用于记录用户对于商品的评价

实现的效果:

1.查看所有可见的店铺:

可购买商品的店铺

2.选择一家店铺,查看该店铺所有的商品

共有两个商品可以购买,id 分别为8和9

3.加入一件商品到购物车

id为1的用户增加一个id为8的商品成功

数据库内多了一条购物车记录信息

4.查看某用户的购物车添加记录

id为1的用户分别添加了两条id为3,8的商品记录

5.用户下单购买这两个商品

手动添加两条数量为1的商品

添加订单成功,订单的记录id为6

6.查看订单下有哪些产品

可以看到,订单下的商品是刚刚的两件商品

7.支付一笔订单

调用支付的接口,修改trade的状态位

修改前的交易单状态位

修改后的交易单状态位

8.评价本次交易

可以看到,本次交易可以评价(由于字符原因,显示为问号)

9.评价某件商品

评价某件商品之前会进行user和商品的校验

10.查看某人的所有商品评价

查看某人的商品的评价

11.查看某件商品的所有人的评价

查看某件商品的所有人的评价以上就是在线商城系统从查看 -- 选中 -- 下单 -- 购买 -- 评价 的主要流程。这条主流程会有很多问题,包括操作的可逆性,例如下单后想删除某个商品,或者从购物车中删除某个商品,是我之前没有考虑过的。还有就是订单的取消,需要商铺的同意,包括发货前取消,发货前取消等区别。

现在围绕主流程进行需求的变更。需求发生变更,需要在主要流程上增加以下功能

1.用户购买一件商品以后,商家对应的该商品的库存量减一。

2.用户取消一笔订单。订单取消了,需要商品的商家确认才可以进行订单取消。

3.删除订单内已存在的商品

4.会员折扣。折扣在订单无法支付的情况会退回到该会员的账户。

5.会员积分,每次购买以后都会有积分记入该会员账户。

6.用户提交一笔订单,锁定该商品,十五分钟内不支付即释放该商品。

先来做稍微简单的一部操作,第一个需求变更:用户购买一件商品以后,商品库存量减一。

步骤:

1.在数据库更改商品表product,增加字段stock表示库存余量

2.在domain里增加商品DO的一条属性,也就是private Integer stock;

3.在用到DO的地方,也就是购买商品,需要save操作数据库的地方修改剩余量。

程序的业务代码

封装的函数

效果:

商品加入订单前

商品加入订单后,剩余数量被修改

然后来做第二个需求变更:用户取消一笔订单。订单取消了,需要商品的商家确认才可以进行订单取消。

首先我之前定义过了订单Order的状态。我设想过是否可以通过设置order 的state状态来达到以下几个状态:

0,1 待付款,已付款。

2,3 待发货,已发货

4,5 待收货,已收货

6,7 待评价,已评价

8,9 用户发起取消订单请求,商家确认订单已取消。

对应的,交易表的state 可以定义三种状态:

0待付款

1已付款

2交易取消

是否可以通过这样人为的设定state来达到所希望的效果?

如果可以的话,那么状态的取消就可以通过程序中状态位的改变来实现了。

第三个需求变更:删除订单内已存在的商品

数据库内已经定义好了订单order--商品product 的中间表。

我从订单内删除定义的商品,实质就是删除这张中间表map的记录

中间表的定义

将中间表的记录删除后,就达到了删除订单内商品的目的。

需要注意的是,当该笔订单删除完所有的商品,也就是订单内不包含任何商品了以后,订单的状态会发生变化。

删除产品前的订单状态,包含一瓶红牛

删除时的操作,id=3是红牛的id

删除后的效果,红牛已不在id为22的订单中

第四个需求变更:会员折扣。折扣在订单无法使用折扣的时候会退回到该会员的账户。

这个需求可能需要一张记录用户的会员身份的表了。

对于会员,会有会员积分,会员折扣券等记录。

会员折扣券应该也是一张表,在会员表和折扣券表中间会有一张中间表map用来记录会员和折扣券的多对多关系。然后会员表和用户表关联。

会员模块的数据库概要设计

以下是几点大概思路:

看一个用户是不是会员:select v.* from vip_table v where user_id = :userId 接收到的是null,则不是会员

判断用户是否为会员的效果

看一个会员有哪些折扣券:

selectc.* from map m , coupons c where m .vip_id = :vipId and m.coupons_id = c.id

查看一个会员有哪些优惠券

看一种折扣券被哪些会员持有:

selectc.* from map m , vip_table v where m .coupons_id = :cId and m.vip_id= vipId

用户有了会员,就可以有折扣。在买东西前查看有哪些折扣。

一开始折扣可以是总价减五元,或者总价打八折这样简单的折扣。后续可能会扩展到优惠券叠加等复杂情况。

考虑最简单的情况,传入一个折扣参数discount到计算总价的函数里面。但这样就没有体现用户对于折扣券的选择动作了。如果既想要用户选择折扣券,又可以对于总价进行操作,那么在Controller层传入一个List<Long> idList 也就是折扣券的id列表可以吗?应该是可以的。

5.会员积分,每次购买以后都会有积分记入该会员账户。

会员积分这个字段现有数据库容纳不下这个字段了。只能改表了。

会员账户表内新增score字段容纳会员积分数据

然后在每一次支付完成以后修改这个score字段,而不是在添加订单的时候就修改这个字段。

会员增加积分的实现效果

6.用户提交一笔订单,锁定该商品,十五分钟内不支付即释放该商品。

我这里有两种选择,一个是当一笔订单提交时,启动一个线程,在支付结束或者半小时结束那一刻线程结束,修改订单的状态位state为相应的状态。但用线程的话是否会系统资源开销比较大?

还有一个就是做一个定时器,每当有一个新的订单生成时加入订单列表,每隔固定时间遍历订单列表来排除掉十五分钟未支付的订单,置订单状态位为未支付,取消订单。并且释放之前占用的商品资源。达到时间上的资源一致性。

今天的问题(11.4):

1.用户使用何种方式来完成折扣券的使用

2.十五分钟的商品锁定使用哪种方式进行实现?

(11.5) 商品锁定通过定时器来实现。定时器每隔一分钟扫描一次数据库中trade=未支付状态的交易单,并判断该交易单的创建时间是否大于十五分钟。若大于十五分钟,关闭本次交易单的交易,设置state=关闭,然后将商品回退到未锁定的状态。各个商品的数量与原来相比没有发生改变。

交易单的状态发生改变

交易单的状态发生改变以后,我想回过头去修改订单的状态,发现交易单没有持有对于订单的引用。

那么可以遍历订单查找交易单id=?的订单吗?好像不太合理

遂询问亚哥,订单持有交易单的引用合理吗?不合理。

11.6 11.7

新增用户的账户表,用来动态展现用户购买商品/退款后账户内余额的变化。

首先一个用户肯定对应一个账户,所以是用户引用账户还是账户引用用户?

应该是用户引用账户吧。

支付一笔订单时:

可以在json中添加折扣券的使用

程序将会判断该用户是否是会员,以及是否有对应类型的折扣券,以及是否使用的折扣券数量超过了拥有的数量。

付款后的效果:会对几处产生影响:

付款时订单的状态受限

会员的积分会有影响。

会员的积分可以累加

用户的账户余额会有影响(优惠券叠加后的金额)

账户余额发生了改变

用户的优惠券会被删除

使用后的优惠券会被置为1

交易单的状态会有影响,包括实际应收,付款状态

交易单的状态有三处受影响

订单的状态会有影响

订单的状态受到了影响

付款后,用户等待货物的过程中可以发起退款,发起退款有几种情况,

1.未发货时退款

2.已发货时退款

3.已收货时退款

第一种情况将会直接退款并且关闭订单。

第2,3种情况将会发起退款申请,等待商家的同意。商家的同意将改变订单的状态位。若用户在商家未同意时退款,将会受到非法请求的提示。

分布在多处的退款限制,只有限定条件下可以退款

商家对已发货订单退款请求的回复

在等待退款的时候,退款将会影响以下几个部分:

交易单,订单的状态:

退款前的状态为等待发货待态

退款后状态为发起退款态,状态码为111。并且完成退款,不需要经过商家的同意。

会员的积分受到影响

会员积分因为退款减少了

用户的余额

用户的余额因为退款而增加

商家的货物库存量

货物库存量因为退货而增加相应的数量

十五分钟未付款将会影响:

商家的货物库存量

交易单,订单的状态

回滚超时未付款的影响因子

11.4回过头来看前天写的代码,有一段其实很有问题。

这一段的逻辑大概是:找出历史订单,顺带查出对应订单的商品列表的商品名和商品id。

service层展现orderVO的逻辑代码

Dao层展现product_order_map的sql语句

我感觉这样的话,逻辑代码就太复杂了。如果把这段逻辑代码放在sql语句里面处理,应该会方便很多

sql语句写得好,程序都可以少写大段。

现在我希望写sql语句,直接returnHistoryOrderVO

但这样好像不太行。因为结果集里面不仅包含一对一的关系,还有一对多的关系。

所以考虑在dao层实现一个功能,根据orderid找出来所有对应该订单的商品DO的list

根据订单id找到商品的列表sql语句

然后原来的9行代码就可以写为下面的两行:

改写前后,效果一样

 

 

   
次浏览       
相关文章

基于EA的数据库建模
数据流建模(EA指南)
“数据湖”:概念、特征、架构与案例
在线商城数据库系统设计 思路+效果
 
相关文档

Greenplum数据库基础培训
MySQL5.1性能优化方案
某电商数据中台架构实践
MySQL高扩展架构设计
相关课程

数据治理、数据架构及数据标准
MongoDB实战课程
并发、大容量、高性能数据库设计与优化
PostgreSQL数据库实战培训
最新活动计划
LLM大模型应用与项目构建 12-26[特惠]
QT应用开发 11-21[线上]
C++高级编程 11-27[北京]
业务建模&领域驱动设计 11-15[北京]
用户研究与用户建模 11-21[北京]
SysML和EA进行系统设计建模 11-28[北京]
 
最新文章
InfluxDB概念和基本操作
InfluxDB TSM存储引擎之数据写入
深度漫谈数据系统架构——Lambda architecture
Lambda架构实践
InfluxDB TSM存储引擎之数据读取
最新课程
Oracle数据库性能优化、架构设计和运行维护
并发、大容量、高性能数据库设计与优化
NoSQL数据库(原理、应用、最佳实践)
企业级Hadoop大数据处理最佳实践
Oracle数据库性能优化最佳实践
更多...   
成功案例
某金融公司 Mysql集群与性能优化
北京 并发、大容量、高性能数据库设计与优化
知名某信息通信公司 NoSQL缓存数据库技术
北京 oracle数据库SQL优化
中国移动 IaaS云平台-主流数据库及存储技术
更多...