程序员过关斩将--你的业务是可变的吗(福利你领了吗)

温馨提示

周末菜菜送的书,你领了吗?没领的话,关注公众号之后参加活动哦!

菜菜哥,我又让领导骂了

来,哥安慰一下你,说说你挨骂的原因,让哥乐一乐

....是这样的,我做的商城有一个订单统计的功能,我除了记录订单之外,还记录了下单人的信息,其中有省市区县id的信息

倾听中.......

然后业务部门会有根据区域(省市区县)订单的各种统计需求,比如xx省的订单数,订单总金额等统计。

倾听中...

由于人员的区域信息可能会变动,用户区域信息就算是同步或者不同步都会出现差错

每个用户信息只存在一条记录?

是的。比如用户A现在属于省id为1000的省,生成了一个订单,这个省的订单数统计会加1,假如订单总数变为了20001,然后用户A所属的省的Id变为了1001,那Id是1000的省的订单总数又变成了20000

我明白你的问题了,来,妹子,哥给你好好说说这个事

请不要跟我说用ES或者其他,其实很多中小公司的业务就是如此,就是基于mysql或者sqlserver 来搞这样的业务

业务场景


        不知道通过D妹子的阐述,大家了解情况了没。这里菜菜再详细说一下。D妹子的程序记录了订单的log来供其他业务(比如统计)使用,这里就以统计业务来说,OrderLog表设计如下:


列名数据类型描述
OrderIdnvarchar(100)订单号,主键
UserIdint下单用户id
Amountint订单的金额
其他字段省略...


除此之外还有一个用户信息表UserInfo,设计如下:

列名数据类型描述
UserIdint用户id,主键
ProvinceIdint用户省的id
CityIdint用户市的id
CountyIdint用户区县的id

涉及到拆单等复杂的订单操作,表的设计可能并非如此,但是不影响菜菜要说的事

变数的业务


现在假如要统计某个省的订单总数,sql如下:


select count(0from OrderLog o inner join UserInfo u on o.UserId=u.UserId where ProvinceId=@ProvinceId


        有问题吗,sql没问题,这时候用户A的省市区县信息突然变了(也许是在其他地区买房,户口迁移了),也就是说UserInfo表里的信息变了,那用以上的sql统计用户A以前省市区县的订单信息是不是就会出错了呢?(产品狗说在哪下的订单就属于哪的订单)

业务的定位


        以上的问题你觉得是不是很简单呢?只要稍微修改一下表也许就够了。但是,菜菜要说的不是针对这一个业务场景,而是所有的业务场景的设计。那你有没有想过为什么D妹子的设计会出现这样的问题呢?

        深刻理解业务才能避免以上类似的错误发生,一定要深刻理解不变和可变的业务点。 拿D妹子的统计来说,你的业务是统计区域的订单数,这个业务在产品设计上定义的是不变性,也就是说在行为产生的那个时间点就确定了业务性质,这个业务的性质不会随着其他变而变。具体到当前业务就是:用户在X省下的订单不会随着用户区域信息的变化而变化,说白了就是说用户在X省生成的订单永远属于X省。

        谈到业务性质的不变性,对应的就有业务的可变性。假如你开发过类似于QQ空间这样的业务,那肯定也做过类似访客的功能。当要显示访客记录的时候,访客的名称在多数情况的设计中属于可变性的业务。什么意思呢?也就是说一个用户修改了姓名,那所有显示这个用户访问记录的的地方姓名都会同时改变。

        说到这里,各位再回头看一下D妹子的业务,这里又牵扯到一个系统设计的问题,众所周知,一个好的系统设计需要把业务的变化点抽象提取出来,D妹子订单统计的业务变化点在于用户的省市区县会变化,订单的金额、订单号等信息不会变化。所以你们觉得是不是D妹子的数据表可以修改一下呢?


数据表的改进

01

改进用户信息

按照以上的阐述,D妹子业务的变化点在于用户的省市区域信息,所以可以把用户信息的表抽象提取出来,主键不再是用户id


列名数据类型描述
Idint主键Id,主键
UserIdint用户id
ProvinceIdint用户省的id
CityIdint用户市的id
CountyIdint用户区县的id


这样的话用户订单log表中就变为

列名数据类型描述
OrderIdnvarchar(100)订单号,主键
UserBIdint对应用户表中的主键id
Amountint订单的金额
其他字段省略...


这样设计的话,如果用户的省市区县信息有变动,相应的用户信息表中会存在多条用户省市区县数据

这里的用户信息表并非是用户对象的主表,而是根据订单业务衍生出来的表

02

改进业务数据表

根据业务的变性和不变性,既然把订单区域统计的业务定义为不变的业务性质,那订单的log表完全可以这样设计

列名数据类型描述
OrderIdnvarchar(100)订单号,主键
UserIdint下单用户id
ProvinceIdint用户省的id
CityIdint用户市的id
CountyIdint用户区县的id
Amountint订单的金额
其他字段省略...


写在最后

各位读到这里,可能会感觉菜菜这次写的其实很鸡肋,但是,D妹子的场景却是真实环境中遇到的问题。问题的本质还是变性业务和非变性业务的定义和划分,和架构设计一样,数据库的设计其实也需要把变动的业务存储点进行抽象,其实应该说是抽离出来。


希望大家有所收获 --菜菜

互联网之路,菜菜与君一同成长

长按识别二维码关注

你点的每个推荐,我都认真当成了喜欢

转载于:https://www.cnblogs.com/zhanlang/p/10626528.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值