订单表的分库分表方案设计(大数据) (2)

缺点在于:数据分散不均匀,某些表的数据量特别大,某些表的数据量很小。因为某些用户下单量多,打个比方,1000-2000这个范围内的用户,下单特别多,

而他们的id根据计算规则,都是分到了x库x表。造成这个表的数据量大,单表的数据量撑到极限后,咋办呢?

总结一下:每种分库分表方案也不是十全十美,都是有利有弊的。目前来说,这种使用用户id来切分订单数据的方案,还是被大部分公司给使用。实际效果还不错。程序员省事,至于数据量暴涨,以后再说呢。毕竟公司业务发展到什么程度,不知道的,项目存活期多久,未来不确定。先扛住再说。

比较好的方案是不是:又能均匀分散、又能避免单表数据量暴涨方便扩容。以前看过一篇文章介绍过使用节点来存储分库分表。笔者暂时没完整的思路。

二、查询需求的考虑

 

  

方案一的查询问题

方案一的情况下,由于是按照订单号做分散数据到多个库、多个表。如果需要查询a用户的所有订单,咋办?需要跨库、跨表查询。

这样效率低。不可行。

方案二的查询问题

如果是按照uid来切分订单数据,在实际应用中一些很频繁的查询需求像下面这样:

1、后台、前台,往往是输入一个订单号,查询这个订单的数据。select操作

2、然后修改这个订单的相关状态。update操作。

由于是,按照用户编号将订单数据分散在各个库、各个表中。

那输入订单号,怎么知道去哪个库、哪个表查询呢?不可能所有的库、所有表都查询一遍,效率太低,不可行。

 三、解决办法:建立用户id和订单号的索引关系表

无论是根据用户id来切分订单,还是根据订单号切分数据。总不能十全十美的。

写到这里,发现真的没有一种技术方案是十全十美的,看,使用用户id来切分订单,好处是有了,坏处也出来了。

不过没关系,早要有心里承受:不要觉得技术是完美无缺的。针对这种情况,想办法去解决办法。

思路:既然是根据订单号分散订单数据,如果需要知道某个用户所有的订单。只要我能知道了a用户的所有的订单号,那么就可以根据订单号定位到表名称了。

思路:既然是根据用户id来分散订单数据的。那么只要知道了这个订单号是谁的(得到了用户id),就能知道去哪个库、哪个表查询数据了。

那怎么知道是谁的呢?建立一个索引关系表,暂且叫做订单用户关系索引表order_user_idx。咱们命名为了保持维护性,还是一看能够知道是干嘛用的。

存储的数据包括两项:订单号、用户编号。

这样输入订单号,可以去查询索引关系表,获取到用户编号。

得到了用户编号,问题解决了。订单信息是根据用户编号分库分表的,可以直接定位到x库x表了。

当创建订单的时候,就要把关系插入到表里面去了。保存关系记录时,为了减低用户等待时间,不需要实时,做成异步。加入到消息队列中去操作。

 订单用户索引关系表的性能优化

 

     

考虑到,一个用户的下的订单可能是几十个,也可能是几百个,随着时间的推移,会越来越多。这个索引关系表,也不能使用单表存储。

所以对这个订单用户关系索引表,也要进行分库分表:直接根据订单号取模进行分库分表。是不是感觉挺麻烦了。确实麻烦。不过能解决问题就好。暂时没想到其他办法了。

一个订单,在创建的时候,就已经分配好给指定用户了。只是一个关系对应,以后也不会变化。

根据这个特点。订单用户索引关系表,其实可以放到内存中缓存起来应对查询需求(数据库那张索引关系表也要有,数据要持久化)。

平时查询的时候,走内存缓存查询。如果查询不到,再走数据库查询一下关系。这样速度就很快了。

结语:水平分表,其实折腾起来工作量挺大的,切分了后,出现新的问题,代码查询又得改,要提供其他解决办法。所以经常看到别人说,能不水平分表,尽量不要分,业务没达到瓶颈,先用硬件扛住,后面再考虑水平切分数据。看银行、联通这些有钱的企业,使用性能强劲的oracle搭配小型机服务器,单表的数据量达到十多亿。小型机是专门定制的,几十万一台。性能很强。分库分表是很耗费时间、当你交易量做到上亿规模的时候,那时,公司的实力应该可以了,经济方面有足够的实力聘请经验丰富的技术来重构。

思考一、b2b平台的订单分卖家和买家的时候,选择什么字段来分库分表呢?

上面讨论的情况是,b2c平台。订单的卖家就一个,就是平台自己。

b2b平台,上面支持开店,买家和卖家都要能够登陆看到自己的订单。

先来看看,分表使用买家id分库分表和根据卖家id分库分表,两种办法出现的问题

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzyxpf.html