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

1元 10元 50元





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



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Model Center   Code  
会员   
   
 
     
   
 订阅
  捐助
在线商城数据库系统设计 思路+效果
 
作者:CyberRye
  1757  次浏览      47
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行代码就可以写为下面的两行:

改写前后,效果一样

 

 

   
1757 次浏览       47
相关文章

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

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

数据治理、数据架构及数据标准
MongoDB实战课程
并发、大容量、高性能数据库设计与优化
PostgreSQL数据库实战培训
最新课程计划
 
最新文章
InfluxDB概念和基本操作
InfluxDB TSM存储引擎之数据写入
深度漫谈数据系统架构——Lambda architecture
Lambda架构实践
InfluxDB TSM存储引擎之数据读取
最新课程
Oracle数据库性能优化、架构设计和运行维护
并发、大容量、高性能数据库设计与优化
NoSQL数据库(原理、应用、最佳实践)
企业级Hadoop大数据处理最佳实践
Oracle数据库性能优化最佳实践
更多...   
成功案例
某金融公司 Mysql集群与性能优化
北京 并发、大容量、高性能数据库设计与优化
知名某信息通信公司 NoSQL缓存数据库技术
北京 oracle数据库SQL优化
中国移动 IaaS云平台-主流数据库及存储技术
更多...