按照用户id打散订单数据。

以uid来切分数据,有两种思路:

1,某个范围的uid订单到哪些库。0到2千万uid,对应的订单数据到a库、a表。2千万到4千万对应的订单到b库。

为什么这种方案用得比较少呢?
容易出现瓶颈吗。某个范围内的用户,下单量比较多,那么造成这个库的压力特别大。其他库却没什么压力。

2,使用uid取模运算。第二种方案业界用得比较多。

一方面、处理简单,程序上做取模运算就好了。

另一方面、使用取模的方式,数据比较均匀分散到多个库去了。不容易出现单个库性能瓶颈。

但是不好处也有:即要扩容的时候,比较麻烦。就需要迁移数据了。

要扩容的时候,为了减少迁移的数据量,一般扩容是以倍数的形式增加。比如原来是8个库,扩容的时候,就要增加到16个库,再次扩容,就增加到32个库。这样迁移的数据量,就小很多了。这个问题不算很大问题,毕竟一次扩容,可以保证比较长的时间,而且使用倍数增加的方式,已经减少了数据迁移量。

按照用户id作为key来切分订单数据,具体如下:

1、 库名称定位:用户id末尾4位 Mod 32。

Mod表示除以一个数后,取余下的数。比如除以32后,余下8,余数就是8。

代码符号是用%表示:15%4=3。

2、表名称定位:(用户id末尾4位 Dev 32) Mod 32。

上面是用计算机术语来表示, 下面用通俗的话描述。

1、库名称计算

用户id的后4位数,取32的模(取模就是除以这个数后,余多少)。余下的数,是0-31之间。
比如用户id:19408064,用最后4位数字8063除以32,余数是31,则定位到底31库。

这样可以表示从0-31之间,总共32个数字。用这个32个数字代表着32个库名称:order_db_0、order_db_2…order_db_31

2、表名称计算

用户id的最后4位数,除以32,取整数。将整数除以32,得到余数,能够表示从0-31之间32个数字,表示表名称。

表名称类似这样:order_tb_1、order_tb_2…order_tb_31。一个库里面,总共32个表名称。

比如用户id:19408063,用最后4位数字8063除以32,得到是251.9,取它的整数是251。
接着将251除以32,取余数,余数为27。

为了保持性能,每张表的数据量要控制。单表可以维持在一千万-5千万行的数据。1024*一千万。哇,可以表示很多数据了。

三、思考优点和缺点

1,优点
订单水平分库分表,为什么要按照用户id来切分呢?
好处:查询指定用户的所有订单,避免了跨库跨表查询。
因为,根据一个用户的id来计算节点,用户的id是规定不变的,那么计算出的值永远是固定的(x库的x表)
那么保存订单的时候,a用户的所有订单,都是在x库x表里面。需要查询a用户所有订单时,就不用进行跨库、跨表去查询了。

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

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

总结一下:每种分库分表方案也不是十全十美,都是有利有弊的。目前来说,这种使用用户id来切分订单数据的方案,还是被大部分公司给使用。实际效果还不错。程序员省事,至于数据量暴涨,以后再说呢。毕竟公司业务发展到什么程度,不知道的,项目存活期多久,未来不确定。先扛住再说。
比较好的方案是不是:又能均匀分散、又能避免单表数据量暴涨方便扩容。以前看过一篇文章介绍过使用节点来存储分库分表。笔者暂时没完整的思路。

二、查询需求的考虑

方案一的查询问题

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

这样效率低。不可行。

方案二的查询问题

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

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

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

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

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

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

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

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

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

这样输入订单号,可以去查询索引关系表,获取到用户编号。得到了用户编号,问题解决了。订单信息是根据用户编号分库分表的,可以直接定位到x库x表了。当创建订单的时候,就要把关系插入到表里面去了。保存关系记录时,为了减低用户等待时间,不需要实时,做成异步。加入到消息队列中去操作。

订单用户索引关系表的性能优化:直接根据订单号取模进行分库分表

一个订单,在创建的时候,就已经分配好给指定用户了。只是一个关系对应,以后也不会变化。 根据这个特点。订单用户索引关系表,其实可以放到内存中缓存起来应对查询需求(数据库那张索引关系表也要有,数据要持久化)。平时查询的时候,走内存缓存查询。如果查询不到,再走数据库查询一下关系。这样速度就很快了。

思考

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

上面讨论的情况是,b2c平台。订单的卖家就一个,就是平台自己。
b2b平台,上面支持开店,买家和卖家都要能够登陆看到自己的订单。

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

如果按买家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、某个时间集中写入数据,出现瓶颈。如一个月一张表。这个月的订单量暴涨呢。那么写入新的订单数据都会操作这张表。造成性能低下。影响整个业务系统交易。

真正好的分表方案,尽量将写数据分散到多个表去,达到分流效果,系统的并发能力就提高了。

参考:分库分表设计

订单表分库分表的思路相关推荐

  1. 10亿级订单系统分库分表设计思路

    一.背景 随着公司业务增长,如果每天1000多万笔订单的话,3个月将有约10亿的订单量,之前数据库采用单库单表的形式已经不满足于业务需求,数据库改造迫在眉睫. 二.订单数据如何划分 我们可以将订单数据 ...

  2. mysql 多维度分表_亿级订单数据分库分表设计方案(满足多维度查询:订单号、用户、商家、渠道)...

    根据业务初步预估订单业务量,每天500万的数据.我们将订单数据划分为了2大类型:分别为热数据和冷数据. 热数据:1个月内的订单数据,查询实时性较高; 冷数据:归档订单数据,查询频率不高; 根据实际业务 ...

  3. 大众点评订单系统分库分表实践

    原大众点评的订单单表早就已经突破两百G,由于查询维度较多,即使加了两个从库,优化索引,仍然存在很多查询不理想的情况.去年大量抢购活动的开展,使数据库达到瓶颈,应用只能通过限速.异步队列等对其进行保护: ...

  4. mysql 分区 分表 分库分表

    分区 把一张表的数据分成N多个区块,这些区块可以在同一个磁盘上,也可以在不同的磁盘上 mysql数据库中的数据是以文件的形势存在磁盘上的,默认放在/mysql/data下面(可以通过my.ini中的d ...

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

    原创文章,转载注明出处   一.两种方案分库分表 一般业界,对订单数据的分库分表,笔者了解,有两类思路:按照订单号来切分.按照用户id来切分. 方案一.按照订单号来做hash分散订单数据 把订单号看作 ...

  6. 互联网大厂有哪些分库分表的思路和技巧?

    分库分表 分库分表是随着业务的不断发展,单库单表无法承载整体的数据存储时,采取的一种将整体数据分散存储到不同服务器上的不同数据库中的不同数据表的存储方案.分库分表能够有效的缓解数据的存储压力,分库分表 ...

  7. 唯品会订单分库分表的实践总结以及关键步骤--转

    原文地址:http://www.infoq.com/cn/articles/summary-and-key-steps-of-vip-orders-depots-table 随着唯品会业务的快速发展, ...

  8. 数据库 流量切分_互联网大厂有哪些分库分表的思路和技巧?

    写在前面 冰河曾经经历过一个完整电商系统用户从零到上亿的研发过程,在业务的不断发展与变化过程中,演化出电商系统和基于大数据的商品精准实时推荐平台,关于MySQL数据库的架构演进,小伙伴们可以参考< ...

  9. oracle 分表和分区哪个好_互联网大厂有哪些分库分表的思路和技巧?

    点击上方蓝色"冰河技术",关注并选择"设为星标" 持之以恒,贵在坚持,每天进步一点点! 作者个人研发的在高并发场景下,提供的简单.稳定.可扩展的延迟消息队列框架 ...

  10. 唯品会订单分库分表的实践总结以及关键步骤

    随着唯品会业务的快速发展,订单量的不断增长,原有的订单存储架构已经不能满足公司的发展了,特别是在大促高峰期,原订单库已经成为抢购瓶颈,已经严重制约公司的发展. 唯品会旧订单库包含几十张订单相关表,旧订 ...

最新文章

  1. RedHat 关闭selinux
  2. 修改应用程序图标(csdn貌似还没有直接从机器码谈起的文章)
  3. 利用队列实现车厢编组
  4. 转3d视图快捷键_最全Solidworks快捷键,值得收藏!
  5. nginx 配置后网站图片加载出来一半或者不出来
  6. 调参必备---GridSearch网格搜索
  7. 对警报线程池的警报线程_如何建立更好的警报
  8. 可视化数据图表制作注意事项
  9. SQL语法基础篇 —— 常用的SQL标准
  10. R 回归 虚拟变量na_互助问答第92期:虚拟变量问题
  11. wps在Linux上使用命令打开文档的方法
  12. 4.1.1 OS之初识文件管理概念和功能
  13. 后现代婚礼机器人显神通_看机器人“各显神通”
  14. php 各种经典算法
  15. 2021年企业十大科技趋势预测
  16. 变态级JAVA程序员面试32问(附答案)(转载)
  17. 【mysql】mysql 常用建表语句
  18. 二叉树学习笔记(未完待续)
  19. 追赶法的matlab实现,只需要输入A和d
  20. Can‘t exec “autopoint“: No such file or directory at /usr/share/autoconf/Autom4te/FileUtils.pm line

热门文章

  1. python答辩毕设ppt_毕设答辩ppt总结
  2. Linux开发板启动需要登录密码设置方法
  3. 博途/S7-1200 PLC 仿真时线圈得电却不能构成自锁回路解决方法
  4. 用MySQL判断一个数为素数_判断一个数是否是素数
  5. 主板放电之后 mac 无法正常启动之谜
  6. 我算了下教育金的收益率及经验汇总
  7. 回归分析(数据拟合---MATLAB和1stopt软件)
  8. python fundamental structure_Data Structures and Algorithms in Python
  9. CDRX6启动失败 提示尝试重新启动计算机和应用程序的解决方法
  10. 人工智能——深度学习