如果按买家id来分库分表。有卖家的商品,会有n个用户购买,他所有的订单,会分散到多个库多个表中去了,卖家查询自己的所有订单,跨库、跨表扫描,性能低下。
如果按卖家id分库分表。买家会在n个店铺下单。订单就会分散在多个库、多个表中。买家查询自己所有订单,同样要去所有的库、所有的表搜索,性能低下。
所以,无论是按照买家id切分订单表,还是按照卖家id切分订单表。两边都不讨好。
淘宝的做法是拆分买家库和卖家库,也就是两个库:买家库、卖家库。
买家库,按照用户的id来分库分表。卖家库,按照卖家的id来分库分表。
实际上是通过数据冗余解决的:一个订单,在买家库里面有,在卖家库里面也存储了一份。下订单的时候,要写两份数据。先把订单写入买家库里面去,然后通过消息中间件来同步订单数据到卖家库里面去。
买家库的订单a修改了后,要发异步消息,通知到卖家库去,更改状态。
思考二:那可以按订单号来分库分表吗?
这样分库分表的话,用户有10个订单,订单不见得都在一个库、一个表里面。查询a用户的所有订单,就会变得麻烦了。尤其是要进行分页展示,分散在不同的表,甚至不同的数据库服务器,也比较耗费性能。
那么订单号里面,最好是要有分库分表信息。淘宝的是在订单号里面添加了卖家id末2位、买家id末2位。这样的好处是干嘛呢?直接定位到具体的库、具体的表去了?
怎么根据这个呢。因为分库、分表的规则,买家库是按照卖家id末尾2位数分,卖家库是按照卖家id末尾两位分。
所以,只要从订单号里面拿到了这些数字信息,就知道在哪个库,哪个表了。
这种办法,与微信的红包订单号是类似的,末尾三位数包含了库信息、表信息。
按照这样,其实就没必要使用订单号来计算了?
如果是按照用户id的后4位数取模分散订单数据。那么订单号的生成,可以在后面加上用户id的后4位数。
那么,虽然是按照用户id来对订单表分库分表的。其实可以直接根据订单号,知道这个订单在哪个库哪个表了。
如果是b2b系统,涉及到卖家和买家。那么可以把卖家和买家的id后面4位都加进去。不过是不是订单号太长了?
思考三、按照订单的时间来分表如何?
一月一张表。一年一张表。用户的所有订单,会分散在不同的库、不同的表中。
按照时间分,在切分订单数据的时候,业界用得比较少。
出现如下两个问题:
1、如果需要分页查询某个用户的所有订单数据,就会出现跨库、跨表查询。效率低。
可以做折中:限制只能查一个范围内的订单,比如一次只能查询,一年以内或者一个月以内的订单。
2、某个时间集中写入数据,出现瓶颈。如一个月一张表。这个月的订单量暴涨呢。那么写入新的订单数据都会操作这张表。造成性能低下。影响整个业务系统交易。
真正好的分表方案,尽量将写数据分散到多个表去,达到分流效果,系统的并发能力就提高了。