订单表的分库分表方案设计

一般业界,对订单数据据笔者了解,有两类思路:

第一类:按照订单号来做hash计算。订单号看作是一个字符串,做hash,分散到多个服务器去。

具体到哪个库、哪个表存储数据呢?订单号里面的数字来记录着。比如微信红包,订单号末尾的3位数记录是哪个库、哪个表。

第二类:按照用户id作为切分的key,打散订单数据。

下面笔者,分析一下按照用户id的方式分库分表。

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

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

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

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

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

Dev表示除以一个数,取结果的整数。比如得到结果是25.6,取整就是25。

代码用/来表示:$get_int = floor(15/4)。15除以4,是一个小数3.75,向下取整就是3。一定是向下取整,向上取整就变成了4了。

按照上面的规则:总共可以表示多少张表呢?32个库*每个库32个表=1024张表。如果想表的数量小,就把32改小一些。

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

 

1、库名称计算

用户id的后4位数,取32的模(取模就是除以这个数后,余多少)。余下的数,是0-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:19408064,用最后4位数字8064除以32,得到是251.9,取它的整数是251。

接着将251除以32,取余数,余数为27。

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

思考:优点和缺点

优点

订单水平分库分表,为什么要按照用户id来切分呢?

好处:查询指定用户的所有订单,避免跨库跨表查询。

原因在于:

根据一个用户的id来计算节点,用户的id是规定不变的,那么计算出的值永远是固定的(x库的x表)

那么保存订单的时候,a用户的所有订单,都是在x库x表里面。需要查询a用户所有订单时,就不用进行跨库、跨表去查询了。

缺点

这种方式也不是没有缺点。

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

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

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

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

后续一些考虑

在实际应用中一些很频繁的查询需求:

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

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

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

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

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

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

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

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

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

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

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

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

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

 

     

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

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

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

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

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

结语:水平分表,其实折腾起来工作量挺大的,切分了后,出现新的问题,代码查询又得改,要提供其他解决办法。所以经常看到别人说,能不水平分表,尽量不要分。看银行、联通这些有钱的企业,使用性能强劲的oracle搭配小型机服务器,单表的数据量达到十多亿。小型机是专门定制的,几十万一台。性能很强。

时间: 2024-11-06 10:49:01

订单表的分库分表方案设计的相关文章

【转】mysql分库分表,数据库分库分表思路

原文:https://www.cnblogs.com/butterfly100/p/9034281.html 复制过来收藏 一. 数据切分 关系型数据库本身比较容易成为系统瓶颈,单机存储容量.连接数.处理能力都有限.当单表的数据量达到1000W或100G以后,由于查询维度较多,即使添加从库.优化索引,做很多操作时性能仍下降严重.此时就要考虑对其进行切分了,切分的目的就在于减少数据库的负担,缩短查询时间. 数据库分布式核心内容无非就是数据切分(Sharding),以及切分后对数据的定位.整合.数据

为什么会决定进行分库分表,分库分表过程中遇到什么难题,如何解决的?

一.为什么决定进行分库分表? 根据业务类型,和业务容量的评估,来选择和判断是否使用分库分表 当前数据库本事具有的能力,压力的评估 数据库的物理隔离,例如减少锁的争用.资源的消耗和隔离等 热点表较多,并且数据量大,可能会导致锁争抢,性能下降 数据库的高并发,数据库的读写压力过大,可能会导致数据库或系统宕机 数据库(MySQL5.7以下)连接数过高,会增加系统压力 单表数据量大,如SQL使用不当,会导致io随机读写比例高.查询慢(大表上的B+树太大,扫描太慢,甚至可能需要4层B+树) 备份和恢复时间

分库分表?如何做到永不迁移数据和避免热点?

一.前言 中大型项目中,一旦遇到数据量比较大,小伙伴应该都知道就应该对数据进行拆分了.有垂直和水平两种.垂直拆分比较简单,也就是本来一个数据库,数据量大之后,从业务角度进行拆分多个库.如下图,独立的拆分出订单库和用户库. 水平拆分的概念,是同一个业务数据量大之后,进行水平拆分. 上图中订单数据达到了4000万,我们也知道mysql单表存储量推荐是百万级,如果不进行处理,mysql单表数据太大,会导致性能变慢.使用方案可以参考数据进行水平拆分.把4000万数据拆分4张表或者更多.当然也可以分库,再

数据库分库分表

1. 数据库分库分表 1.1. 前言 1.1.1. 名词解释 1.2. 数据库架构演变 1.3. 分库分表前的问题 1.3.1. 用户请求量太大 1.3.2. 单库太大 1.3.3. 单表太大 1.4. 分库分表的方式方法 1.4.1. 垂直拆分 1.4.2. 水平拆分 1.5. 分库分表后面临的问题 1.5.1. 事务支持 1.5.2. 多库结果集合并(group by,order by) 1.5.3. 跨库join 1.6. 分库分表方案产品 1.7. 为什么不建议分库分表 1.8. 参考

170123、数据库分库分表策略的具体实现方案

相关文章: 1. 使用Spring AOP实现MySQL数据库读写分离案例分析 2.MySQL5.6 数据库主从(Master/Slave)同步安装与配置详解 :http://blog.csdn.net/xlgen157387/article/details/51331244 3.MySQL主从复制的常见拓扑.原理分析以及如何提高主从复制的效率总结 :http://blog.csdn.net/xlgen157387/article/details/52451613 4.使用mysqlreplic

分库分表的几种常见形式以及可能遇到的难

在谈论数据库架构和数据库优化的时候,我们经常会听到"分库分表"."分片"."Sharding"-这样的关键词.让人感到高兴的是,这些朋友所服务的公司业务量正在(或者即将面临)高速增长,技术方面也面临着一些挑战.让人感到担忧的是,他们系统真的就需要"分库分表"了吗?"分库分表"有那么容易实践吗?为此,笔者整理了分库分表中可能遇到的一些问题,并结合以往经验介绍了对应的解决思路和建议. 垂直分表 垂直分表在日常开

分库分表的几种常见形式以及可能遇到的难题

在谈论数据库架构和数据库优化的时候,我们经常会听到"分库分表"."分片"."Sharding"-这样的关键词.让人感到高兴的是,这些朋友所服务的公司业务量正在(或者即将面临)高速增长,技术方面也面临着一些挑战.让人感到担忧的是,他们系统真的就需要"分库分表"了吗?"分库分表"有那么容易实践吗?为此,笔者整理了分库分表中可能遇到的一些问题,并结合以往经验介绍了对应的解决思路和建议. 垂直分表 垂直分表在日常开

分库分表的几种常见玩法及如何解决跨库查询等问题

在谈论数据库架构和数据库优化的时候,我们经常会听到"分库分表"."分片"."Sharding"-这样的关键词.让人感到高兴的是,这些朋友所服务的公司业务量正在(或者即将面临)高速增长,技术方面也面临着一些挑战.让人感到担忧的是,他们系统真的就需要"分库分表"了吗?"分库分表"有那么容易实践吗?为此,笔者整理了分库分表中可能遇到的一些问题,并结合以往经验介绍了对应的解决思路和建议. 垂直分表 垂直分表在日常开

分库分表中间件Sharding-JDBC

数据库分库分表从互联网时代开启至今,一直是热门话题.在NoSQL横行的今天,关系型数据库凭借其稳定.查询灵活.兼容等特性,仍被大多数公司作为首选数据库.因此,合理采用分库分表技术应对海量数据和高并发对数据库的冲击,是各大互联网公司不可避免的问题. 虽然很多公司都致力于开发自己的分库分表中间件,但截止目前,仍无完美的开源解决方案覆盖此领域. 分库分表适用场景 分库分表用于应对当前互联网常见的两个场景——大数据量和高并发.通常分为垂直拆分和水平拆分两种. 垂直拆分是根据业务将一个库(表)拆分为多个库