精华内容
下载资源
问答
  • 一、背景 随着零售门店数量的增长,库存表,优惠劵表,消息表,订单表数据量不断的增多,目前一主(写)多从的MySQL 架构难于支撑公司业务的爆发式增长 二、调研 前期在于重点解决 MySQL 的单机...目前生产数据库架构
  • 数据库分库分表

    2014-03-28 17:50:27
    数据库分库分表 数据库分库分表 数据库分库分表
  • 为什么要做读写分离?减少主库的压力 数据库分库分表

    在这里插入图片描述
    在这里插入图片描述

    • 为什么要做读写分离?减少主库的压力
    • 数据库的分库分表
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

    在这里插入图片描述

    展开全文
  • 一:Mysql的分库分表 二:为什么要进行分库分表 三:分库分表的原则 1.分库分表的结构视图,这里列出几种数据依赖结构来说明。 2.分库分表的类型 3.垂直分割(分库/分表) (1)垂直分库的演构 (2)垂直分...

    目录

     

      一:Mysql的分库分表

    二:为什么要进行分库分表

    三:分库分表的原则

    1.分库分表的结构视图,这里列出几种数据依赖结构来说明。

    2.分库分表的类型

    3.垂直分割(分库/分表)

    (1)垂直分库的演构

    (2)垂直分表演构

    (3)垂直分库分表分割原则以及特征

    4.水平分割

     (1)水平拆分的演构

    (2)水平拆分的依据原则

    (3)水平拆表产生的难点

    5.垂直拆分和水平拆分的各自的区别联系

      (1)侧重点不同:

      (2)数据完整性:

     (3)产生问题的复杂程度

     6.总结

    四:分库分表问题以及解决方案

    1.事务问题

    2.跨库跨表查询统计分页等


     

      一:Mysql的分库分表

     

      对于Mysql进行分库分表我们需要明白以下几点,整个学习过程都是基于以下:

    (1)为什么要进行分库分表

    (2)分库分表的原则

    (3)分库分表产生额外的技术难点

    二:为什么要进行分库分表

      我们来讨论分库分表的原因就是为什么要进行分库分表?什么样的场景下要分库分表?

     首先要说明,分库分表实在数据库层面产生了瓶颈。简而言之,数据库的分库分表一定是在应用程序的合理架构下,才需要考虑这样的技术实现。在生产中,一定是先应用层次解决瓶颈然后在对数据库层面优化,也就是说,在应用层面,如果项目还是个单体或者垂直应用,我们强烈建议先对项目进行结构优化(比如集群或者Soa或者微服务化)。

      其次,我们在什么样的场景下实现数据库的分库分表?基于数据库的存储型性能这里仅对Mysql做讨论,毕竟Mysql是大多数公司使用的,在Mysql的官方文档上说明过 500W数据量是Mysql承载的极限,超过500W性能会大幅度降低。但是在实际生成中我们曾经测试过200W数据量是Mysql的性能转折点。因此在数据量超过200w我们建议分库分表。

      最后,也是可能比较使用的一点,更具实际上产场景分库分表。这种情况这里制作一个简单的说明,因为这种是基于公司实际的胜场业务来实现的。我们这里在后面会做一个简单的讨论。

    三:分库分表的原则

    1.分库分表的结构视图,这里列出几种数据依赖结构来说明。

        (1)完全不相干的表(这种表依赖基本不存在的,即使是不相关的模块)

           

        (2)包含关系的表(表B完全包含A的,这里使用也不符哦)

           

         (3)交际关系的表

          

    2.分库分表的类型

         数据库分库分表分为2中分割原则:水平分割和垂直分割

          垂直分割:又称结构分割,通常是模块表之间分割

          水平分割:又称业务分割,通常将一个表数据按照一定的规则分割到不同的表中

    3.垂直分割(分库/分表)

      可以这么说,很多公司在进行组建分割原则时,垂直分割一定是优先于水平分割,也就说分割时优先考虑先进性垂直分割。

    垂直分割又称结构分割,这是我们之前公司的叫法,是指将业务模块关联最小的表之间进行分割。比如一个后管系统最后可以拆分成CMS,CRM,财务系统等,那么这几个系统的表就可以进行垂直分割。但是垂直分割的事务不容易控制,比如说某一个操作同时设计到大系统的各个小模块,一旦分库分表那么事务如何控制?后面我们将集中讨论。

      (1)垂直分库的演构

      

                                                                                   (传统的单体垂直系统的结构)

                                                                             (垂直分库)

    (2)垂直分表演构

     

                                                                               (传统形式的单标结构)

         

                

                                                                                           (垂直分表)

    (3)垂直分库分表分割原则以及特征

       分割原则:按照业务结构拆分(分库)或者逻辑结构拆分(分表)

       分库特点:库表之间关联性较小,其中某一个库挂了,不会影响其他。

       分表特点:一个表切割成多个表,且多个表数据需要一一对应。

       缺点:事务的提交出现问题。(后面讨论)

    4.水平分割

       水平分割爱分库分表中优先级是小于垂直分割,应为水平分割产生的问题是大于垂直的。水平分割又称业务分割,讲起来比较抽象,我们直接用实例说明。比如一个日志表,我们按照月份来拆分(log_1,log_2 ...)等。

     (1)水平拆分的演构

                                                         

       

    (2)水平拆分的依据原则

        ①hash取模:

         更具某一个字段进行MD5(或者其他方式)转化成数字,取余查表。比如用户表根据用户id进行取余(以2分表为例)。

         第一步:用户表被拆分为t_user_1和t_user_2一共2个表

         第二步:在查询(其他操作)时,根据id取余去查询某一个表。如

                           select * from    t_user_#{userId}%2  where ........

        ②根据范围

         常见的就是更具日期去取不同的表,上面日志表就是一个例子。这种方式就不用我说了吧。

        ③根据预设

        如果一开始我们就定好20张表,那么在查询时就可以按照规则查询等

    (3)水平拆表产生的难点

         ①事务问题

                这是无论垂直还是水平的一个老大难的问题

         ②统计

               在上面的依据原则中我们边开了一点,如果同时需要查询所有的表怎么办?

         ③功能性

              水平分表的分页,排序都是一个摆在面前的问题

          这些问题是我们在拆表时需要考虑的问题

    5.垂直拆分和水平拆分的各自的区别联系

      (1)侧重点不同:

              垂直侧重拆库,水平侧重拆表。细心的同学应该发现在说垂直拆分我们也说道了拆表,我们考虑一下在举例中用户信息扩战表顶多是用户表的一个功能扩展,而不是严格意义上的拆表。

      (2)数据完整性:

            垂直拆库最大程度保证同表数据不拆分,水平拆分则是同表数据按照规则拆到不同的表中。

     (3)产生问题的复杂程度

              水平拆分问题复杂远大于垂直。原因是垂直保证了同表数据的一致性完整性。

     6.总结

      在实际生产中,我们提到的都是分库分表,也就是说垂直分库和水平分表我们需要结合使用,但是我们就要去解决其中产生的问题。

    四:分库分表问题以及解决方案

    我们这里来总结一下在分库分表中产生的问题:

    1.事务问题

       不得不说只要进行拆分事务问题一定是一个老大难的问题,这里我们采用分布式事务去实现,在下面一章会单独讲这个问题以及解决方案。

    2.跨库跨表查询统计分页等

       在上面的分库分表中解决方案中,遇到跨库跨表查询分页等就就需要借助第三方中间件proxy或者mycat。我们会在后面将分库分表的中间件详细说明

     

    展开全文
  • 主要介绍了MyBatis实现Mysql数据库分库分表操作和总结,需要的朋友可以参考下
  • java分库分表源码

    2018-03-06 20:07:21
    项目形式源代码,含数据库脚本,仅供参考,下载后可任意修改
  • 作者 |butterfly100来源 |cnblogs.com/butterfly100/p/9034281.html一. 数据切分关系型数据库本身比较容易成为系统瓶颈,单机存储容量...

    作者 | butterfly100

    来源 | cnblogs.com/butterfly100/p/9034281.html

    一. 数据切分

    关系型数据库本身比较容易成为系统瓶颈,单机存储容量、连接数、处理能力都有限。当单表的数据量达到1000W或100G以后,由于查询维度较多,即使添加从库、优化索引,做很多操作时性能仍下降严重。此时就要考虑对其进行切分了,切分的目的就在于减少数据库的负担,缩短查询时间。

    数据库分布式核心内容无非就是数据切分(Sharding),以及切分后对数据的定位、整合。数据切分就是将数据分散存储到多个数据库中,使得单一数据库中的数据量变小,通过扩充主机的数量缓解单一数据库的性能问题,从而达到提升数据库操作性能的目的。

    数据切分根据其切分类型,可以分为两种方式:垂直(纵向)切分和水平(横向)切分。

    1、垂直(纵向)切分

    垂直切分常见有垂直分库和垂直分表两种。

    垂直分库就是根据业务耦合性,将关联度低的不同表存储在不同的数据库。做法与大系统拆分为多个小系统类似,按业务分类进行独立划分。与"微服务治理"的做法相似,每个微服务使用单独的一个数据库。如图:

    垂直分表是基于数据库中的"列"进行,某个表字段较多,可以新建一张扩展表,将不经常用或字段长度较大的字段拆分出去到扩展表中。在字段很多的情况下(例如一个大表有100多个字段),通过"大表拆小表",更便于开发与维护,也能避免跨页问题,MySQL底层是通过数据页存储的,一条记录占用空间过大会导致跨页,造成额外的性能开销。另外数据库以行为单位将数据加载到内存中,这样表中字段长度较短且访问频率较高,内存能加载更多的数据,命中率更高,减少了磁盘IO,从而提升了数据库性能。

    垂直切分的优点:

    • 解决业务系统层面的耦合,业务清晰

    • 与微服务的治理类似,也能对不同业务的数据进行分级管理、维护、监控、扩展等

    • 高并发场景下,垂直切分一定程度的提升IO、数据库连接数、单机硬件资源的瓶颈

    缺点:

    • 部分表无法join,只能通过接口聚合方式解决,提升了开发的复杂度

    • 分布式事务处理复杂

    • 依然存在单表数据量过大的问题(需要水平切分)

    2、水平(横向)切分

    当一个应用难以再细粒度的垂直切分,或切分后数据量行数巨大,存在单库读写、存储性能瓶颈,这时候就需要进行水平切分了。

    水平切分分为库内分表和分库分表,是根据表内数据内在的逻辑关系,将同一个表按不同的条件分散到多个数据库或多个表中,每个表中只包含一部分数据,从而使得单个表的数据量变小,达到分布式的效果。如图所示: 

    库内分表只解决了单一表数据量过大的问题,但没有将表分布到不同机器的库上,因此对于减轻MySQL数据库的压力来说,帮助不是很大,大家还是竞争同一个物理机的CPU、内存、网络IO,最好通过分库分表来解决。

    水平切分的优点:

    • 不存在单库数据量过大、高并发的性能瓶颈,提升系统稳定性和负载能力

    • 应用端改造较小,不需要拆分业务模块

    缺点:

    • 跨分片的事务一致性难以保证

    • 跨库的join关联查询性能较差

    • 数据多次扩展难度和维护量极大

    水平切分后同一张表会出现在多个数据库/表中,每个库/表的内容不同。几种典型的数据分片规则为:

    1、根据数值范围

    按照时间区间或ID区间来切分。例如:按日期将不同月甚至是日的数据分散到不同的库中;将userId为1~9999的记录分到第一个库,10000~20000的分到第二个库,以此类推。某种意义上,某些系统中使用的"冷热数据分离",将一些使用较少的历史数据迁移到其他库中,业务功能上只提供热点数据的查询,也是类似的实践。

    这样的优点在于:

    • 单表大小可控

    • 天然便于水平扩展,后期如果想对整个分片集群扩容时,只需要添加节点即可,无需对其他分片的数据进行迁移

    • 使用分片字段进行范围查找时,连续分片可快速定位分片进行快速查询,有效避免跨分片查询的问题。

    缺点:

    • 热点数据成为性能瓶颈。连续分片可能存在数据热点,例如按时间字段分片,有些分片存储最近时间段内的数据,可能会被频繁的读写,而有些分片存储的历史数据,则很少被查询

    2、根据数值取模

    一般采用hash取模mod的切分方式,例如:将 Customer 表根据 cusno 字段切分到4个库中,余数为0的放到第一个库,余数为1的放到第二个库,以此类推。这样同一个用户的数据会分散到同一个库中,如果查询条件带有cusno字段,则可明确定位到相应库去查询。

    优点:

    • 数据分片相对比较均匀,不容易出现热点和并发访问的瓶颈

    缺点:

    • 后期分片集群扩容时,需要迁移旧的数据(使用一致性hash算法能较好的避免这个问题)

    • 容易面临跨分片查询的复杂问题。比如上例中,如果频繁用到的查询条件中不带cusno时,将会导致无法定位数据库,从而需要同时向4个库发起查询,再在内存中合并数据,取最小集返回给应用,分库反而成为拖累。

    二. 分库分表带来的问题

    分库分表能有效的缓解单机和单库带来的性能瓶颈和压力,突破网络IO、硬件资源、连接数的瓶颈,同时也带来了一些问题。下面将描述这些技术挑战以及对应的解决思路。 

    1、事务一致性问题

    分布式事务

    当更新内容同时分布在不同库中,不可避免会带来跨库事务问题。跨分片事务也是分布式事务,没有简单的方案,一般可使用"XA协议"和"两阶段提交"处理。

    分布式事务能最大限度保证了数据库操作的原子性。但在提交事务时需要协调多个节点,推后了提交事务的时间点,延长了事务的执行时间。导致事务在访问共享资源时发生冲突或死锁的概率增高。随着数据库节点的增多,这种趋势会越来越严重,从而成为系统在数据库层面上水平扩展的枷锁。

    最终一致性

    对于那些性能要求很高,但对一致性要求不高的系统,往往不苛求系统的实时一致性,只要在允许的时间段内达到最终一致性即可,可采用事务补偿的方式。与事务在执行中发生错误后立即回滚的方式不同,事务补偿是一种事后检查补救的措施,一些常见的实现方法有:对数据进行对账检查,基于日志进行对比,定期同标准数据来源进行同步等等。事务补偿还要结合业务系统来考虑。

    2、跨节点关联查询 join 问题

    切分之前,系统中很多列表和详情页所需的数据可以通过sql join来完成。而切分之后,数据可能分布在不同的节点上,此时join带来的问题就比较麻烦了,考虑到性能,尽量避免使用join查询。

    解决这个问题的一些方法:

    1)全局表

    全局表,也可看做是"数据字典表",就是系统中所有模块都可能依赖的一些表,为了避免跨库join查询,可以将这类表在每个数据库中都保存一份。这些数据通常很少会进行修改,所以也不担心一致性的问题。

    2)字段冗余

    一种典型的反范式设计,利用空间换时间,为了性能而避免join查询。例如:订单表保存userId时候,也将userName冗余保存一份,这样查询订单详情时就不需要再去查询"买家user表"了。

    但这种方法适用场景也有限,比较适用于依赖字段比较少的情况。而冗余字段的数据一致性也较难保证,就像上面订单表的例子,买家修改了userName后,是否需要在历史订单中同步更新呢?这也要结合实际业务场景进行考虑。

    3)数据组装

    在系统层面,分两次查询,第一次查询的结果集中找出关联数据id,然后根据id发起第二次请求得到关联数据。最后将获得到的数据进行字段拼装。

    4)ER分片

    关系型数据库中,如果可以先确定表之间的关联关系,并将那些存在关联关系的表记录存放在同一个分片上,那么就能较好的避免跨分片join问题。在1:1或1:n的情况下,通常按照主表的ID主键切分。如下图所示:

    这样一来,Data Node1上面的order订单表与orderdetail订单详情表就可以通过orderId进行局部的关联查询了,Data Node2上也一样。

    3、跨节点分页、排序、函数问题

    跨节点多库进行查询时,会出现limit分页、order by排序等问题。分页需要按照指定字段进行排序,当排序字段就是分片字段时,通过分片规则就比较容易定位到指定的分片;当排序字段非分片字段时,就变得比较复杂了。需要先在不同的分片节点中将数据进行排序并返回,然后将不同分片返回的结果集进行汇总和再次排序,最终返回给用户。如图所示:

    上图中只是取第一页的数据,对性能影响还不是很大。但是如果取得页数很大,情况则变得复杂很多,因为各分片节点中的数据可能是随机的,为了排序的准确性,需要将所有节点的前N页数据都排序好做合并,最后再进行整体的排序,这样的操作是很耗费CPU和内存资源的,所以页数越大,系统的性能也会越差。

    在使用Max、Min、Sum、Count之类的函数进行计算的时候,也需要先在每个分片上执行相应的函数,然后将各个分片的结果集进行汇总和再次计算,最终将结果返回。如图所示:

    4、全局主键避重问题

    在分库分表环境中,由于表中数据同时存在不同数据库中,主键值平时使用的自增长将无用武之地,某个分区数据库自生成的ID无法保证全局唯一。因此需要单独设计全局主键,以避免跨库主键重复问题。有一些常见的主键生成策略:

    1)UUID

    UUID标准形式包含32个16进制数字,分为5段,形式为8-4-4-4-12的36个字符,例如:550e8400-e29b-41d4-a716-446655440000

    UUID是主键是最简单的方案,本地生成,性能高,没有网络耗时。但缺点也很明显,由于UUID非常长,会占用大量的存储空间;另外,作为主键建立索引和基于索引进行查询时都会存在性能问题,在InnoDB下,UUID的无序性会引起数据位置频繁变动,导致分页。

    2)结合数据库维护主键ID表

    在数据库中建立 sequence 表:

    CREATE TABLE `sequence` (
      `id` bigint(20) unsigned NOT NULL auto_increment,
      `stub` char(1) NOT NULL default '',
      PRIMARY KEY  (`id`),
      UNIQUE KEY `stub` (`stub`)
    ) ENGINE=MyISAM;

    stub字段设置为唯一索引,同一stub值在sequence表中只有一条记录,可以同时为多张表生成全局ID。sequence表的内容,如下所示:

    +-------------------+------+
    | id | stub |
    +-------------------+------+
    | 72157623227190423 | a |
    +-------------------+------+

    使用 MyISAM 存储引擎而不是 InnoDB,以获取更高的性能。MyISAM使用的是表级别的锁,对表的读写是串行的,所以不用担心在并发时两次读取同一个ID值。

    当需要全局唯一的64位ID时,执行:

    REPLACE INTO sequence (stub) VALUES ('a');
    SELECT LAST_INSERT_ID();

    这两条语句是Connection级别的,select last_insert_id() 必须与 replace into 在同一数据库连接下才能得到刚刚插入的新ID。

    使用replace into代替insert into好处是避免了表行数过大,不需要另外定期清理。

    此方案较为简单,但缺点也明显:存在单点问题,强依赖DB,当DB异常时,整个系统都不可用。配置主从可以增加可用性,但当主库挂了,主从切换时,数据一致性在特殊情况下难以保证。另外性能瓶颈限制在单台MySQL的读写性能。

    flickr团队使用的一种主键生成策略,与上面的sequence表方案类似,但更好的解决了单点和性能瓶颈的问题。

    这一方案的整体思想是:建立2个以上的全局ID生成的服务器,每个服务器上只部署一个数据库,每个库有一张sequence表用于记录当前全局ID。表中ID增长的步长是库的数量,起始值依次错开,这样能将ID的生成散列到各个数据库上。如下图所示:

    由两个数据库服务器生成ID,设置不同的auto_increment值。第一台sequence的起始值为1,每次步长增长2,另一台的sequence起始值为2,每次步长增长也是2。结果第一台生成的ID都是奇数(1, 3, 5, 7 ...),第二台生成的ID都是偶数(2, 4, 6, 8 ...)。

    这种方案将生成ID的压力均匀分布在两台机器上。同时提供了系统容错,第一台出现了错误,可以自动切换到第二台机器上获取ID。但有以下几个缺点:系统添加机器,水平扩展时较复杂;每次获取ID都要读写一次DB,DB的压力还是很大,只能靠堆机器来提升性能。

    可以基于flickr的方案继续优化,使用批量的方式降低数据库的写压力,每次获取一段区间的ID号段,用完之后再去数据库获取,可以大大减轻数据库的压力。如下图所示:

    还是使用两台DB保证可用性,数据库中只存储当前的最大ID。ID生成服务每次批量拉取6个ID,先将max_id修改为5,当应用访问ID生成服务时,就不需要访问数据库,从号段缓存中依次派发0~5的ID。当这些ID发完后,再将max_id修改为11,下次就能派发6~11的ID。于是,数据库的压力降低为原来的1/6。

    3)Snowflake分布式自增ID算法

    Twitter的snowflake算法解决了分布式系统生成全局ID的需求,生成64位的Long型数字,组成部分:

    • 第一位未使用

    • 接下来41位是毫秒级时间,41位的长度可以表示69年的时间

    • 5位datacenterId,5位workerId。10位的长度最多支持部署1024个节点

    • 最后12位是毫秒内的计数,12位的计数顺序号支持每个节点每毫秒产生4096个ID序列

    这样的好处是:毫秒数在高位,生成的ID整体上按时间趋势递增;不依赖第三方系统,稳定性和效率较高,理论上QPS约为409.6w/s(1000*2^12),并且整个分布式系统内不会产生ID碰撞;可根据自身业务灵活分配bit位。

    不足就在于:强依赖机器时钟,如果时钟回拨,则可能导致生成ID重复。

    综上结合数据库和snowflake的唯一ID方案,可以参考业界较为成熟的解法:Leaf——美团点评分布式ID生成系统,并考虑到了高可用、容灾、分布式下时钟等问题。

    5、数据迁移、扩容问题

    当业务高速发展,面临性能和存储的瓶颈时,才会考虑分片设计,此时就不可避免的需要考虑历史数据迁移的问题。一般做法是先读出历史数据,然后按指定的分片规则再将数据写入到各个分片节点中。此外还需要根据当前的数据量和QPS,以及业务发展的速度,进行容量规划,推算出大概需要多少分片(一般建议单个分片上的单表数据量不超过1000W)。

    如果采用数值范围分片,只需要添加节点就可以进行扩容了,不需要对分片数据迁移。如果采用的是数值取模分片,则考虑后期的扩容问题就相对比较麻烦。

    三. 什么时候考虑切分

    下面讲述一下什么时候需要考虑做数据切分。

    1、能不切分尽量不要切分

    并不是所有表都需要进行切分,主要还是看数据的增长速度。切分后会在某种程度上提升业务的复杂度,数据库除了承载数据的存储和查询外,协助业务更好的实现需求也是其重要工作之一。

    不到万不得已不用轻易使用分库分表这个大招,避免"过度设计"和"过早优化"。分库分表之前,不要为分而分,先尽力去做力所能及的事情,例如:升级硬件、升级网络、读写分离、索引优化等等。当数据量达到单表的瓶颈时候,再考虑分库分表。

    2、数据量过大,正常运维影响业务访问

    这里说的运维指:

    1)对数据库备份,如果单表太大,备份时需要大量的磁盘IO和网络IO。例如1T的数据,网络传输占50MB时候,需要20000秒才能传输完毕,整个过程的风险都是比较高的

    2)对一个很大的表进行DDL修改时,MySQL会锁住全表,这个时间会很长,这段时间业务不能访问此表,影响很大。如果使用pt-online-schema-change,使用过程中会创建触发器和影子表,也需要很长的时间。在此操作过程中,都算为风险时间。将数据表拆分,总量减少,有助于降低这个风险。

    3)大表会经常访问与更新,就更有可能出现锁等待。将数据切分,用空间换时间,变相降低访问压力

    3、随着业务发展,需要对某些字段垂直拆分

    举个例子,假如项目一开始设计的用户表如下:

    id                   bigint #用户的ID
    name varchar #用户的名字
    last_login_time datetime #最近登录时间
    personal_info text #私人信息
    ..... #其他信息字段

    在项目初始阶段,这种设计是满足简单的业务需求的,也方便快速迭代开发。而当业务快速发展时,用户量从10w激增到10亿,用户非常的活跃,每次登录会更新 last_login_name 字段,使得 user 表被不断update,压力很大。而其他字段:id, name, personal_info 是不变的或很少更新的,此时在业务角度,就要将 last_login_time 拆分出去,新建一个 user_time 表。

    personal_info 属性是更新和查询频率较低的,并且text字段占据了太多的空间。这时候,就要对此垂直拆分出 user_ext 表了。

    4、数据量快速增长

    随着业务的快速发展,单表中的数据量会持续增长,当性能接近瓶颈时,就需要考虑水平切分,做分库分表了。此时一定要选择合适的切分规则,提前预估好数据容量。

    5、安全性和可用性

    鸡蛋不要放在一个篮子里。在业务层面上垂直切分,将不相关的业务的数据库分隔,因为每个业务的数据量、访问量都不同,不能因为一个业务把数据库搞挂而牵连到其他业务。利用水平切分,当一个数据库出现问题时,不会影响到100%的用户,每个库只承担业务的一部分数据,这样整体的可用性就能提高。

    四. 案例分析

    1、用户中心业务场景

    用户中心是一个非常常见的业务,主要提供用户注册、登录、查询/修改等功能,其核心表为:

    User(uid, login_name, passwd, sex, age, nickname)

    uid为用户ID,  主键

    login_name, passwd, sex, age, nickname, 用户属性

    任何脱离业务的架构设计都是耍流氓,在进行分库分表前,需要对业务场景需求进行梳理:

    用户侧:前台访问,访问量较大,需要保证高可用和高一致性。主要有两类需求:

    • 用户登录:通过login_name/phone/email查询用户信息,1%请求属于这种类型

    • 用户信息查询:登录之后,通过uid来查询用户信息,99%请求属这种类型

    运营侧:后台访问,支持运营需求,按照年龄、性别、登陆时间、注册时间等进行分页的查询。是内部系统,访问量较低,对可用性、一致性的要求不高。

    2、水平切分方法

    当数据量越来越大时,需要对数据库进行水平切分,上文描述的切分方法有"根据数值范围"和"根据数值取模"。

    "根据数值范围":以主键uid为划分依据,按uid的范围将数据水平切分到多个数据库上。例如:user-db1存储uid范围为0~1000w的数据,user-db2存储uid范围为1000w~2000wuid数据。

    优点是:扩容简单,如果容量不够,只要增加新db即可。

    不足是:请求量不均匀,一般新注册的用户活跃度会比较高,所以新的user-db2会比user-db1负载高,导致服务器利用率不平衡

    "根据数值取模":也是以主键uid为划分依据,按uid取模的值将数据水平切分到多个数据库上。例如:user-db1存储uid取模得1的数据,user-db2存储uid取模得0的uid数据。

    优点是:数据量和请求量分布均均匀

    不足是:扩容麻烦,当容量不够时,新增加db,需要rehash。需要考虑对数据进行平滑的迁移。

    3、非uid的查询方法

    水平切分后,对于按uid查询的需求能很好的满足,可以直接路由到具体数据库。而按非uid的查询,例如login_name,就不知道具体该访问哪个库了,此时需要遍历所有库,性能会降低很多。

    对于用户侧,可以采用"建立非uid属性到uid的映射关系"的方案;对于运营侧,可以采用"前台与后台分离"的方案。

    3.1、建立非uid属性到uid的映射关系

    1)映射关系

    例如:login_name不能直接定位到数据库,可以建立login_name→uid的映射关系,用索引表或缓存来存储。当访问login_name时,先通过映射表查询出login_name对应的uid,再通过uid定位到具体的库。

    映射表只有两列,可以承载很多数据,当数据量过大时,也可以对映射表再做水平切分。这类kv格式的索引结构,可以很好的使用cache来优化查询性能,而且映射关系不会频繁变更,缓存命中率会很高。

    2)基因法

    分库基因:假如通过uid分库,分为8个库,采用uid%8的方式进行路由,此时是由uid的最后3bit来决定这行User数据具体落到哪个库上,那么这3bit可以看为分库基因。

    上面的映射关系的方法需要额外存储映射表,按非uid字段查询时,还需要多一次数据库或cache的访问。如果想要消除多余的存储和查询,可以通过f函数取login_name的基因作为uid的分库基因。生成uid时,参考上文所述的分布式唯一ID生成方案,再加上最后3位bit值=f(login_name)。当查询login_name时,只需计算f(login_name)%8的值,就可以定位到具体的库。不过这样需要提前做好容量规划,预估未来几年的数据量需要分多少库,要预留一定bit的分库基因。

    3.2、前台与后台分离

    对于用户侧,主要需求是以单行查询为主,需要建立login_name/phone/email到uid的映射关系,可以解决这些字段的查询问题。

    而对于运营侧,很多批量分页且条件多样的查询,这类查询计算量大,返回数据量大,对数据库的性能消耗较高。此时,如果和用户侧共用同一批服务或数据库,可能因为后台的少量请求,占用大量数据库资源,而导致用户侧访问性能降低或超时。

    这类业务最好采用"前台与后台分离"的方案,运营侧后台业务抽取独立的service和db,解决和前台业务系统的耦合。由于运营侧对可用性、一致性的要求不高,可以不访问实时库,而是通过binlog异步同步数据到运营库进行访问。在数据量很大的情况下,还可以使用ES搜索引擎或Hive来满足后台复杂的查询方式。

    五. 支持分库分表中间件

    站在巨人的肩膀上能省力很多,目前分库分表已经有一些较为成熟的开源解决方案:

    • sharding-jdbc(当当)

    • TSharding(蘑菇街)

    • Atlas(奇虎360)

    • Cobar(阿里巴巴)

    • MyCAT(基于Cobar)

    • Oceanus(58同城)

    • Vitess(谷歌)

    六. 参考

    [1] 数据库分布式架构扫盲——分库分表(及银行核心系统适用性思考) 

    [2] 分库分表的思想 

    [3] 水平分库分表的关键步骤以及可能遇到的问题 

    [4] 从原则、方案、策略及难点阐述分库分表 

    [5] Leaf——美团点评分布式ID生成系统 

    [6] 架构师之路公众号

    琐碎时间想看一些技术文章,可以去公众号菜单栏翻一翻我分类好的内容,应该对部分童鞋有帮助。同时看的过程中发现问题欢迎留言指出,不胜感谢~。另外,有想多了解哪些方面内容的可以留言(什么时候,哪篇文章下留言都行),附菜单栏截图(PS:很多人不知道公众号菜单栏是什么)

    END

    我知道你 “在看”
    
    展开全文
  • 需要对Mysql数据库进行分库分表,故而最近一直在整理分库分表的相关知识,现手上的工作也告一段落了,抽空将自己最近的学习结果转化为博文,分享给大家,本博文打算做成一个系列的,首先是分库分表的理论知识的了解...

    由于业务需要,需要对Mysql数据库进行分库分表,故而最近一直在整理分库分表的相关知识,现手上的工作也告一段落了,抽空将自己最近的学习结果转化为博文,分享给大家,本博文打算做成一个系列的,首先是分库分表的理论知识的了解,其次是基于Java编程语言的分库分表的框架的开发,最后是分库分表的编制。让大家不仅仅从理论上了解mysql的分库分表,通过代码来更深层次的了解,理论是如何落地到实践的。最后非常感谢《可伸缩服务架构 框架与中间件》这本书的作者么,本博文的代码实现是参考此书,然后结合当前系统平台框架开发而成。

    坚持我写作的一贯风格,我们先需要带着问题来了解mysql的分库分表

    • 什么是分库分表,为什么我们需要分库分表
    • 如何进行分库分表,有什么优缺点
    • 对于分库分表有哪些架构设计,对于后期的扩容扩展怎么样
    • 目前行业内流行的解决方案有哪些?各自有什么特点
    • 自己设计一个数据库分库分表的框架,如何设计,需要考虑哪些因素

    为什么需要分库分表

    随着我们的系统运行,存储在关系型数据库的数据量会越来越大,系统的访问的压力也会随之增大,如果一个库中的表数据超过了一定的数量,比如说mysql中的表数据达到千万级别,就需要考虑进行分库分表;

    其次随着表数据的不断增大,会发现,查询也随着变得缓慢,如果添加索引的话,会发现影响到了新增和删除的性能,如果我们将数据库分散到不同的表上,单表的索引大小就得到了控制,对索引以及表结构的变更会变得很方便和高效;

    当数据库实例的吞吐量达到性能的瓶颈时,我们需要扩展数据库实例,让每个数据库实例承担其中一部分数据库的请求,分解总体的大请求量的压力;

    在数据库进行扩容的时候对应用层的配置改变最少, 就需要在每个数据库实例中预留足够的数据库数量

    以上的情况我们都可以使用分库分表,那么什么是分库分表呢?

    简而言之就是数据拆分:将一个表结构分为多个表,或者将一个表数据分片后放入多个表,这些表可以放在同一个数据库里,也可以放到不同的数据库中,甚至可以放到不同的数据库实例中

    数据拆分的方式

    数据拆分有两种方式:

    • 垂直拆分: 根据业务的维度,将原本一个库中的表拆分多个表,每个库中表与原有的结构不同
    • 水平拆分: 根据分片算法,将一个库拆分成多个库,每个库依旧保留原有的结构

    在实际的开发过程中,通常是先进行维度拆分形成微服务结构,然后再进行水平拆分

    分库分表

    比如我们有一张表,随着业务的不断进行,mysql中表中数据量达到了10亿,若是将数据存放在一张表中,则性能一定不会太好,根据我们使用的经验,mysql数据库一张表的数据记录极限一般在5000万左右,所以我们需要对进行分片存储(水平拆分),按照5000万一个单位来拆分的话,需要切片数量20个,也就是20个数据库表

    如果将20个相同业务表存放在同一个数据库中,那么单个数据库实例的网卡I/O、内存、CPU和磁盘性能是有限的,随着数据库访问频率的增加,会导致单个数据库实例和数据库达到性能瓶颈,因此我们需要将20个表分到多个数据库和多个数据库实例中,具体的评估如下:
    【TODO 对数据库实例和数据库表的数量的评估】

    image

    如何进行分库分表

    分库分表是对数据库拆分的一种解决方案,根据实施切片逻辑的层次不同,我们将分库分表方案大致分为三大类:客户端分片、代理分片和支持事务的分布式数据库

    • 客户端分片

    所谓的客户端分片即在使用数据库的应用层直接操作分片逻辑,分片规则需要在同一个应用的多个节点间进行同步,每个应用层嵌入一个操作切片的逻辑实现。

    image

    在客户端分片,目前主要有以下三种方式:

    1. 在应用层直接实现

    这是一种非常通用的解决方案,直接在应用层读取分片规则,解析分片规则,根据分片规则实现切分的路由逻辑,从应用层直接决定每次操作应该使用哪个数据库实例中的对应的数据库

    这种解决方案虽然有一定的代码侵入,但是实现起来比较简单,但是切片的逻辑是自己开发的, 如果生产上遇到了问题,能快速定位解决;

    当然这种方式也存在缺点:代码的耦合度比较高,其次这种实现方式会让数据库保持的链接比较多,这要看应用服务的节点数量,需要提前进行容量上的评估

    1. 通过定制JDBC协议实现

    这种解决方案主要是为了解决1中解决方案中的代码耦合,通过定制JDBC协议来实现(主要是针对业务逻辑层提供与JDBC一致的接口),让分库分表在JDBC的内部实现

    目前当当网开源的框架:Sharding JDBC 就是使用这种解决方案来实现的

    1. 通过定制ORM框架实现

    目前ORM框架非常流行,流行的JPA、Mybatis和Hibernate都是优秀的ORM框架,通过定制ORM框架来实现分库分表方案,常见的有基于Mybatis的分库分表方案的解决;

        <select id="selectUser" parameterType="java.util.Map" resultType="User">
            select user_id as userId,user_name as userName
            from user_#{index}
            where user_id = #{userId}
        </select>
    
    • 代理分片

    代理分片就是在应用层和数据库层之间添加一个代理层,把分片的路由规则配置在代理层,代理层对外提供与JDBC兼容的接口给应用层,在业务实现之后,在代理层配置路由规则即可;

    image

    这种方案的优点:让应用层的开发人员专注于业务逻辑的实现,把分库分表的配置留给代理层处理
    同样的业务存在缺点:增加了代理层,这样的话对每个数据库操作都增加了一层网络传输,这对性能是有影响的,同时需要维护增加的代理层,也有了硬件成本,线上生产环境出现了问题,不能迅速定位,需要有一定的技术专家来维护

    我们常见的 Mycat就是基于此种解决方案来实现的

    • 支持事务的分布式数据库

    支持分布式事务的框架,目前有OceanBase、TiDB框架,这些框架将可伸缩特定和分布式事务的实现包装到了分布式数据库内部实现,对使用者透明,使用者不需要直接控制这些特性,但是对事务的支持不如关系型数据,适合大数据日志系统、统计系统、查询系统、社交网站等

    分库分表的架构设计

    上面我们介绍过数据拆分的两种方式:垂直拆分和水平拆分;

    拆分方式优点缺点
    垂直拆分1. 拆分后业务清晰,拆分规则明确
    2. 系统之间进行整合或扩展容易
    3. 按照成本、应用等级、应用的类型等将表放到不同的机器上,便于管理
    4.便于实现动静分离、冷热分离的数据库表的设计模式
    5. 数据维护简单
    1. 部分业务表无法进行关联、只能通过接口的方式来解决,提高了系统的复杂度
    2. 受每种业务不同的限制,存在单库性能瓶颈,对数据扩展和性能提升不友好
    3. 事务处理复杂
    水平拆分1. 单裤单表的数据保持一定的量级,有助于性能的提高
    2. 切分的表的结构相同,应用层改造较少,只需要增加路由规则即可
    3. 提高了系统的稳定性和负载能力
    1. 切分后数据是分散的,很难利用数据库的关联查询,跨库查询性能较差
    2. 拆分规则难以抽象
    3. 分片数据的一致性难以解决
    4. 数据扩容的难度和维护量极大

    综上所述,我们发现垂直拆分和水平拆分具有共同点:

    1. 存在分布式事务问题
    2. 存在跨节点join的问题
    3. 存在跨节点合并排序、分页的问题
    4. 存在多数据源管理的问题

    垂直拆分更偏向于业务拆分的过程,在技术上我们更倾向于水平切分的方案;

    常见的分片策略:

    • 按照哈希切片

    对数据库的某个字段进行来求哈希,再除以分片总数后取模,取模后相同的数据为一个分片,这样将数据分成多个分片的方法叫做哈希分片

    我们大多数在数据没有时效性的情况下使用哈希分片,就是数据不管是什么时候产生的,系统都需要处理或者查询;

    优点缺点
    数据切片比较均匀,数据压力分散的效果好数据分散后,对于查询需求需要进行聚合处理
    • 按照时间切片

    按照时间的范围将数据分布到不同的分片上,比如我们可以将交易数据按照与进行切片,或者按照季度进行切片,由交易数据的多少来决定按照什么样的时间周期来进行切片

    这种切片方式适合明显时间特点的数据,常见的就是订单历史查询

    分布式事务

    本博文不进行分布式事务的分析和实践,后期我会更新一系列的分布式事务的博文,一起探讨分布式事务的原理、解决方案和代码实践等,本博文简单介绍了分布式事务的解决方案;

    上面说到的,不管是垂直拆分还是水平拆分,都有一个共同的问题:分布式事务

    我们将单表的数据切片后存储在多个数据库甚至是多个数据库实例中,所以依靠数据库本身的事务机制不能满足需要,这时就需要用到分布式事务来解决了

    三种解决方案

    • 两阶段提交协议

    两阶段提交协议中的两阶段是:准备阶段和提交阶段,两个阶段都是由事务管理器(协调者)发起,事务管理器能最大限度的保证跨数据库操作的事务的原子性。

    具体的交互逻辑如下:

    image

    优点缺点
    是分布式系统环境下最严格的事务实现防范,
    保证了数据一致性和操作原子性
    1. 难以进行水平伸缩,因为在提交事务过程中,事务管理器需要和每个参与者进行准备和提交的操作协调
    2.每个参与者之间的协调需要时间,参与者一多的话,则锁定资源和消费资源之间的时间差就边长
    3. 两阶段提交协议是阻塞协议,在极端情况下不能快速响应的话,会造成阻塞问题
    • 最大努力保证模式

    这是一种非常通用的保证分布式一致性的模式,适合对一致性要求不是十分严格的但是对性能要求比较高的场景

    最大努力保证模式:在更新多个资源时,将多个资源的提交尽量延后到最后一刻进行处理,这样的话,如果业务流程出现问题,则所有的资源更新都可以回滚,事务仍然保持一致。

    最大努力保证模式在发生系统问题,比如网络问题等会出现问题,造成数据一致性的问题 ,这是就需要进行实时补偿,将已提交的事务进行回滚

    一般情况下,使用消息中间件来完成消费者之间的事务协调,客户端从消息中间件的队列中消费消息,更新数据库,此时会涉及到两个操作,一是从消息中间件消费消息,二是更新数据库,具体的操作步骤如下:

    1. 开启消息事务
    2. 接收消息
    3. 开启数据库事务
    4. 更新数据库
    5. 提交数据库事务
    6. 提交消息事务

    上述步骤最关键的地方在5和6,如果5成功了,但是6出现了问题,导致消息中间件认为消息没有被成功消费,既有的机制会重新再消费消息,就会出现消息重复消费,这是需要幂等处理来避免消息的重新消费

    其次我们还需要注意消息消费的顺序性问题,以及消费过程中是否调用远程接口等耗时操作

    优点缺点
    性能较高1. 数据一致性不能完美保证,只能是最大保证
    2. 可能出现消息重复消费(幂等处理)
    3. 数据库事务可能存在远程操作嵌套,互相影响
    • 事务补偿机制

    以上提到的两种解决方案:两阶段提交协议对系统的性能影响较大,最大努力保证模式会是多个分布式操作互相嵌套,有可能互相影响,那么我们采用事务补偿机制:

    事务补偿即在事务链中的任何一个正向事务操作,都必须存在一个完全符合回滚规则的可逆事务。如果是一个完整的事务链,则必须事务链中的每一个业务服务或操作都有对应的可逆服务。对于Service服务本身无状态,也不容易实现前面讨论过的通过DTC或XA机制实现的跨应用和资源的事务管理,建立跨资源的事务上下文.

    我们通过跨银行转账来说明:

    首先调用取款服务,完全调用成功并返回,数据已经持久化。然后调用异地的存款服务,如果也调用成功,则本身无任何问题。如果调用失败,则需要调用本地注册的逆向服务(本地存款服务),如果本地存款服务调用失败,则必须考虑重试,如果约定重试次数仍然不成功,则必须log到完整的不一致信息。也可以是将本地存款服务作为消息发送到消息中间件,由消息中间件接管后续操作。

    最后添加的重试机制是最大程度的确保补偿服务执行,保持数据的一致性,如果重试之后还是失败,则将操作保存在消息中间件中,等待后续处理,这样就更多了一重保障

    image

    分库分表引起的问题

    由于将完整的数据分成若干份,在以下的场景中会产生多种问题

    • 扩容与迁移

    在分库分表中,如果涉及的分片已经达到了承载数据的最大值,就需要对集群进行扩容,通常包括以下的步骤

    1. 按照新旧分片规则,对新旧数据库进行双写
    2. 将双写前按照旧分片规则写入的历史数据,根据新分片规则迁移写入新的数据库
    3. 将按照旧的分片规则查询改为按照新的分片规则查询
    4. 将双写数据库逻辑从代码中下线,只按照新的分片规则写入数据
    5. 删除按照旧分片规则写入的历史数据

    2步骤中迁移数据时,数据量非常大,通常会导致不一致,因此需要先迁移旧的数据,洗完后再迁移到新规则的新数据库下,再做全量对比,对比评估在迁移过程中是否有数据的更新,如果有的话就再清洗、迁移,最后以对比没有差距为准

    • 分库分表维度导致的查询问题

    进行了分库分表以后,如果查询的标准是分片的主键,则可以通过分片规则再次路由并查询,但是对于其他主键的查询、范围查询、关联查询、查询结果排序等,并不是按照分库分表维度查询的;

    这样的话,解决方案有以下三种:

    1. 在多个分片表中查询后合并数据集,这种方式的效率最低
    2. 冗余记录多份数据,方便查询, 缺点是需要额外维护一份数据,浪费资源
    3. 通过搜索引擎解决,但如果实时性要求很高,就需要实现实时搜索,可以利用大数据相关特性来解决
    • 跨库事务难以实现

    同时操作多个库,则会出现数据不一致的情况,此时可以引用分布式事务来解决

    • 同组数据跨库问题

    要尽量把同一组数据放到同一数据库服务器上,不但在某些场景下可以利用本地事务的强一致性,还可以是这组数据自治

    主流的解决方案

    目前针对mysql的分库分表,行业内主流的解决方案有:ShardingJDBC、Mycat

    Mycat代理分片框架

    Mycat是一款面向企业级应用的开源数据库中间件产品,他目前支持数据库集群,分布式事务与ACID,被普遍视为基于Mysql技术的集群分布式数据库解决方案

    Mycat支持多种分片规则:

    • 枚举法
    • 固定分片的hash算法
    • 范围约定
    • 求模法
    • 日期列分区法
    • 通配取模
    • ASCII码求模通配
    • 编程指定
    • 截取数据哈希解析
    • 一致性Hash

    具体的Mycat使用方法,以后应该会有一博文来整理,敬请期待啊~~~

    展开全文
  • 别再问什么是数据库分库分表了,看这里!

    千次阅读 多人点赞 2019-06-16 17:20:49
    编者语:为了避免被误解为:「手里有把锤子,看什么都是钉子!」,说明一下不是什么业务都...本文主要是通过几道关于分库分表的常问面试题带你深入了解数据库分库分表,希望对大家能够有所帮助! 一:面试题 为什...
  • 在对数据库中的数据进行拆分的时候,也会带来以下问题: 事务问题;...而单库分表和分库分表会涉及到分布式事务,目前数据库并不支持跨库事务,所以在这一块需要解决分布式事务可能带来的不一致性。 分
  • 数据库分库分表架构选型

    千次阅读 2018-11-30 15:20:56
    我是一个地道的java程序员,由于我们公司没有DBA,所以只能我来研究,这也是公司交给我的一个重要的任务,我利用做完手头项目的空余时间分析并研究了目前市场上很多的数据库架构,进行一次总结、体会。 请谨记: ...
  • Mycat是基于开源cobar演变而来,我们对cobar的代码进行了彻底的重构,使用NIO重构了网络模块,并且优化了Buffer内核,增强了聚合,Join等基本特性,同时兼容绝大多数数据库成为通用的数据库中间件。
  • 一、自定义注解实现分库 为什么会有数据库切库一说 首先,许多项目都有主库与从库,有的主库后面甚至会有很多个从库,主从库之间的通常同步也很快,这为数据库切库提供了一个基础,因为可以去不同的数据库查询,...
  • 下载地址MYCAT官方网站 jdk安装配置 首先去oracle官网下载并安装jdk8,添加环境变量,JAVA_HOME设置为D:WorksoftwareJavajdk1.8 CLASSPATH设置为.;%JAVA_HOME%lib;%JAVA_HOME%lib ools.jar path系统变量追加%JAVA_...
  • 使用PHP实现MySQL的分库分表,10个库,每个库10个表,程序自动创建表,插入数据,让你真正感受大数据,分库分表的好处
  • 当单表的数据量达到1000W或100G以后,由于查询维度较多,即使添加从、优化索引,做很多操作时性能仍下降严重。此时就要考虑对其进行切分了,切分的目的就在于减少数据库的负担,缩短查询时间。 数据库分布式核心...
  • 采用了读写分离主从复制(数据库读写分离方案,实现高性能数据库集群)的方案去应对,后来又面临了大并发写入的时候,系统数据库采用了分库分表的方案(数据库分库分表方案,优化大量并发写入所带来的性能问题),...
  • Java+Springboot+mybatis+sharding jdbc 实现分库分表
  • 昨天我们分享了怎么不停机进行分库分表数据迁移(数据库分库分表,生产环境不停机数据迁移)后来有好多朋友问我,说他们的系统虽然也到了差不多分表的地步了,但是,不知道具体拆分多少张表,分多了又怕浪费公司资源...
  • 数据库分库分表是缓解数据库服务器压力和增加并发量的途径之一,但是随着分库分表之后,也不可避免的带来了一些问题,很显而易见的问题就是如何解决分库后的查询统计。分库之后没有SQL可以用了,简单的过滤后再合并...
  • 数据库分库分表)中间件对比 分区:对业务透明,分区只不过把存放数据的文件分成了许多小块,例如mysql中的一张表对应三个文件.MYD,MYI,frm。根据一定的规则把数据文件(MYD)和索引文件(MYI)进行了分割,分区后...
  • 数据库分库分表的面试连环炮 面试题 为什么要分库分表?(设计高并发系统的时候,数据库层面该如何设计) 用过哪些分库分表中间件? 不同的分库分表中间件都有什么优缺点? 你们具体是如何对数据库如何进行垂直拆分...
  • 本资源对应博文:http://blog.csdn.net/buchengbugui/article/details/60972176,可以通过博文进行学习,博文有详细教程,以及代码。
  • 点击▲关注 “数据和云” 给公众号标星置顶更多精彩 第一时间直达1.阿里巴巴分布式数据层发展和演变业务数据从原来的单单表模式变成了数据被拆分到多个数据库,甚至多个表...
  • 前端用户可以把它看作是一个数据库代理,用 MySQL 客户端工具和命令行访问,而其后端可以用 MySQL 原生协议与多个 MySQL 服务器通信,也可以用JDBC协议与大多数主流数据库服务器通信,其核心功能是分库分表。...
  • 作为一个数据库,作为数据库中的一张表,随着用户的增多随着时间的推移...MyBatis实现分表最简单步骤 1、我们模拟用户表数据量超过千万(虽然实际不太可能) 2、用户表原来的名字叫做user_tab,我们切分为user_tab...
  • 数据库分库分表实现结构

    千次阅读 2016-11-25 17:17:21
    数据库分库分表实现结构,主要分为客户端和服务器端,文章简单介绍了各自的优缺点。
  • 数据库分库分表是缓解数据库服务器压力和增加并发量的途径之一,但是随着分库分表之后,也不可避免的带来了一些问题,很显而易见的问题就是如何解决分库后的查询统计。分库之后没有SQL可以用了,简单的过滤后再合并...
  • Java分库分表 最简单的判断逻辑 全代码 (个人梳理) 需求:根据ID首位奇偶性分库 根据ID末位奇偶性分表 文章目录【Java分库分表 最简单的判断逻辑 全代码 (个人梳理)前言一、分库分表前提:配置多数据源...
  • 春风如贵客,一到便繁华。各位看官点赞再看,养成好习惯(●´∀`●) ...为了提高查询速度,我们可以优化sql语句,优化表结构和索引,不过对那些百万级千万级的数据库表,即便是优化过后,查询速度还...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 39,764
精华内容 15,905
关键字:

java数据库如何分库分表

java 订阅