概述
数据库子数据库和子表的用处:数据库的数据量不一定可控。没有子数据库和子表,随着时间和业务的发展,数据库中的表会越来越多,表中的数据量会越来越大,相应的数据操作、增删改也会越来越大;另外,由于无法分布式部署,一台服务器的资源(CPU、IO、磁盘、内存)是有限的,最后数据库所能承载的数据量和数据处理能力都会遇到瓶颈。基于以上原因,我们需要使用数据库子数据库和子表操作。
一、基本思想
数据库子表的目的是将一个数据库分成多个部分,放在不同的数据库上,以缓解单个数据库的性能问题。
比如,当你面对一个海量数据的数据库时,如果由于表的数量多而导致数据量大,建议采用垂直分段,即把紧密相关的表(比如某个应用模块的表)放在一个数据库(服务器)中。如果表格不多,但是每个表格中的数据很多,就需要使用水平分段。即按照一定的规则将表拆分到多个数据库(服务器)中(常见的方法是按ID哈希)。当然,这只是一个例子,因为现实要比这复杂得多,需要结合两种拆分方式才能让系统性能更好(因为一个表的数据量可能非常大,超出了一个服务器的容量,所以需要在垂直拆分的基础上进行水平拆分)。下面详细描述垂直分段和水平分段。
二、数据库的垂直切分和水平切分
垂直细分:分为功能模块,如订单库、商品库、用户库等。垂直细分最大的特点就是简单,容易实现。
水平分段:同一个表的数据被分区保存到不同的数据库。
三、案例分析
案例:简单的购物系统,涉及以下表格
1.产品表(数据量10w,稳定)
2.订单(数据量为200W,且有增加趋势)
3.用户表(数据量100w,有增加趋势)
以mysql为例来描述水平拆分和垂直拆分。mysql数据库可以容忍的数据从几百万静态数据到几千万都有。
垂直拆分:
解决问题:表之间的io竞争。
未解决的问题:但是表中数据增长的压力。
方案:将产品表和用户表放在一台服务器上,订单表分别放在一台服务器上。
水平拆分:
解决问题:单个表中数据增长的压力。
未解决的问题:表之间的io竞争
方案:用户表按性别分为男性用户表和女性用户表;订单表通过已完成和已完成分为已完成订单和未完成订单;产品表未完成的订单放在一台服务器上,完成的订单表和男性用户表放在一台服务器上,女性用户表放在一台服务器上(女性爱购物,数据增量大)。
四、拆分策略
如上所述,拆分的一般顺序是先垂直拆分,再水平拆分。
垂直拆分的结果正好为水平拆分做了铺垫。垂直拆分的思路是分析表与表之间的聚合关系,把紧密相关的表放在一个服务器上(大多数情况下可能是同一个模块,也可能是同一个“聚合”,指的是域驱动设计中的“聚合根”)。这个“聚合根”也是水平拆分的基础,所有与聚合根相关的数据都会被水平拆分成它们的shard片段。这样跨分片关联的可能性很小,应用也不必中断已有的表间关联。
五、拆分所带来的问题
1.交易问题
解决问题的一般方法有两种:分布式事务和通过应用程序和数据库的联合控制来实现事务。
方案一;使用分布式事务
优点:交友数据库管理简单有效。
缺点:性能成本高,尤其是碎片越来越多的时候
选项2:由应用程序和数据库控制。
原理:将一个跨多个数据库的分布式事务分成多个只在单个数据库上的小事务,通过应用程序控制每个小事务。
优点:性能上有优势。
缺点:应用程序在事务控制上需要灵活设计。
2.跨节点连接问题
避免join操作,将操作分成多个步骤。在第一次查询的结果集中找出关联数据的id,根据这些id发起第二次请求获取关联数据。
3.跨节点计数、排序依据、分组依据和聚合函数。
解决方案:类似于解决跨节点连接的问题,在每个节点上获得结果,然后在应用程序端进行合并。
六、总结
数据库划分的原因是为了避免数据库表之间的eio竞争,数据库划分的原因是为了避免单个表的数据量增加带来的压力。在实际项目中,首先要整理出整个数据秀逗魔导士的er图,然后进行拆分。此外,我们需要适当地拆分和优化一些sql语句。
篇幅有限,这里介绍一下数据库子数据库和子表。后面会有更多DBA内容分享,感兴趣的朋友可以关注一下。