您的位置:首页 > 数据库 > Redis

基于Redis实现邮费存储

2017-07-19 10:08 253 查看

基于Redis实现邮费存储

需求

首先说明一下情景:

有多家供应商在某一平台上出售自己的商品,平台要根据顾客的收货地址,按照供应商是否有针对该地址的特殊计费方式,计算物流信息。

因为每家供应商可以和多家物流公司有合作,假设各家物流公司的计费方式是:一定重量内,按照统一价格收费,超出后,当每超出额定数额,按照该数额计算。而且还可以针对特殊省份,比如港澳台、西藏等设置特殊的计费方式。

其中存在多种一对多的情况:

有多家供应商

有多家物流公司

一个供应商可以和多家快递公司合作

一个供应商可以针对一个家快递公司设置多个特殊省级计费方式(这里只让供应商设置到省级,可以到更具体的区域,但是这里暂时只实现省级)

其次,要根据顾客的收货地址和供应商下所拥有的全部物流公司和是否有针对该收货地址的特殊设置来计算邮费价格。

MySQL存储结构

如果要采用
MySQL
来存储这种结构的话,那么就需要以下几张表

快递公司表

字段名字段说明
shipping_id主键
shipping_name快递公司名称
shipping_code快递公司代码
供应商与物流公司表

字段名字段说明
id主键
supplier_id供应商id
shipping_id物流公司id
shipping_kinds_id配置id
province该配置下的省份id
winthinWeight首重
winthinCost首重内统一价格
beyondPerGram超出一定重量
beyondPerGramCost超出后重量价格
省份的选择一般是用插件来实现的,所以这里是不再记录省名表

但是这样的话,供应商与物流公司表的记录就会特别多,假设供应商有x位,有y家物流公司,每家公司设置z个配置,加上一个默认设置,就是如果供应商不设置特殊的省份计算方式,则按照该设置进行计算。那么总共有多少条记录数:

x∗y∗(z+1)

拿一个具体的值来说,我们可能拥有的供应商有500位,有5家快递公司,每家快递公司推出4款针对港澳台、西藏等的特殊地区的收费套餐,那么记录数有多少

(5∗500∗(4+1))=12500

而且查找时,你需要根据
$supplier_id
,供应商id,
$province
,收货商的收货地址,查找该供应商下是否有关于该省份的特殊设置。而且这里为了减少一个物流配置中有多个省份的一对多的情况,还把省级信息保存成以
,(逗号)
隔开的数组,这样当我们搜索时,只能根据
$supplier_id
,查找出全部数据,再来遍历,这样的效率是比较底的。

Redis结构

关于Redis的基础知识可以参考我的这一篇博客

这里不一定要使用Redis,只是我现在在跟的项目中有使用Redis,于是大哥就说用Redis试试,结果是试虽然试出来了,但是结构比较复杂,没办法,毕竟关联对象比较多:

供应商

物流公司

物流配置

在该配置下的省份

其上每一个关系都是一对多。这时可能第一反应是使用哈希结构来存,比如使用哈希表模拟表之间的关联:

// 模拟供应商与快递公司的关联表
$supplier_id:{
$shipping_id1:$next_hash_key,
$shipping_id2:$next_hash_key2
...
}
// 模拟该快递公司下各物流配置的情况
$next_hash_key:{
$shipping_kinds_id1:json("首重,超出后等配置信息"),
$shipping_kinds_id2:json(""),
...
}


其中以
$supplier_id
Key
,以
$shipping_id
为字段,以另一张存储快递公司多种配置信息的
key
。这样有问题吗?基本没有,但是回到最基础的问题上来,这样可以很方便的根据供应商
$supplier_id
和省级
$province_id
来查找出配置信息吗?

还是很麻烦,因为只是换了个方式去遍历数组而已。这个时候我突然想到一种不是很邪门,但是应该可行的方案:

为什么我不根据已有数据,重新构建他们,方便我的查询呢?

有了这个思路之后,我就想在上面数据的结构上,构建以下格式的数据:

$supplier_id:{
$province_id:{
json(
{$shipping_id=>{'首重等配置信息'}}
)
}
}


这里,我把
$province_id
作为字段进行存储,这样查询时就可以使用
hget key field
,即
hget $supplier_id $shipping_id
的结构进行查询,如果能够查到数据,表名该供应商有关于该省份的特殊设置,如果查不到,则表示没有特殊设置,那么没有办法,只能遍历各家快递的默认设置,然后计算最低价格。但是我们也可以把默认设置保存进上面供查询的数据中,于是数据就变成了这样:

$supplier_id:{
$province_id:{
json({$shipping_id=>{'首重等配置信息'}})
},
'defaults':{
json({$shipping_id=>{'首重等配置信息'}})
}
}


这样的设置其实不适合经常要修改数据的方案,因为你一旦更新数据就要更新给前台查看的数据,就是上面的数据格式。当初这样设想是假设物流配置不会经常更新,而且前台查询比较方便。

到此为止,基本的思路都完成了,在这里总结一下数据结构:

存储数据

# 集合,存储该供应商下全部的物流公司id
"SupplierID".$supplier_id:{$shipping_id1,$shipping_id2}
# 存储该供应商下的物流配置
"SP".$supplier_id."SP".$shipping_id:{
$shipping_kinds_id:json("各种配置信息")
}


上面之所以只用集合,是因为我们可以自己创建关于供应商与物流的
key
,这样就不用多存储多一个值了。下面是我为了优化而多添加的内容:

# 集合,存储该供应商已经设置了特殊的省份
"SP".$supplier_id."SP".$shipping_id."PRO":{
$province_id1,$province_id2,...
}


这样做的目的是为了优化用户的选择,比如当供应商在设置韵达快递的物流配置时,对宁波市,只能设置一个配置信息,否则一家快递公司对同一个地区有不同设置,这样无疑是多余的,这样的辅助功能不一定要,但是有的话,必定是极好的(甄嬛附体!!!我是甄嬛转的脑残粉。。。)

提供功能

有了上面的数据结构,那么可以给供应商开通哪些功能呢?

新建物流公司=>
管理员


修改物流公司信息=>
管理员


(删除物流公司,这个我个人并不赞成给,可以修改,但是删除的话,不能保证是否有别的供应商使用该物流)=>
管理员


配置物流公司计费套餐=>
供应商


删除该计费套餐(这里可以删除)=>
供应商


关闭物流公司配置=>
供应商


其中各个功能与该功能中的使用者也列出来了,接着就是编写具体的代码了,这个我已经在自己的
github
上新建了一个仓库,等到代码完善之后就可以分享出来了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: