关系型数据库本身比较容易称为系统性能瓶颈,单机存储容量、链接数、处理能力有限,如果在高并发和大数据量的访问下就需要分库分表(分布式系统中间件如:mongodb自身支持分区),分库分区是指把数据库数据物理拆分到多个实例或多台机器上
分库分表需要数据的合并,查询或更新条件的分离、事物的分离等待后果业务实现也会复杂,所以在分库分表之前不要为分而分可以做,硬件和网络升级、数据库版本升级、读写分离、负载均衡等
什么时候考虑运用分库分表
1:数据量大
如果单表和某个实例太大在做备份的时候需要大量的磁盘IO或者网络IO资源
如果某个表过大当对表的DDL的时候 mysql锁表的影响
整个表热点,数据访问和更新频繁,只有把其中数据物理拆开,变相降低访问压力
2:表设计不合理,需要垂直拆分
比如user表 用户活跃度增加每登录一次都要更新login_time字段 表的压力变大,就需要垂直拆分了
一个数据条数无穷增长,增加或提升机器配置物理了,就需要水平拆分
3:每个业务数据库区分开,出问题不会相互影响
分库分表不要为分而分,去做其他力所能及的事情吧,例如升级硬件,升级,升级网络,升级数据库版本,读写分离,负载均衡等等
垂直分表通俗的说法叫大表拆小表,水平拆分也叫横向拆分
分库分表引发的问题
1、跨库join问题:
在拆分之前,系统中很多列表和详情页所需的数据是可以通过sql join来完成的。而拆分后,数据库可能是分布式在不同实例和不同的主机上,join将变得非常麻烦 (表的关联受限制 ,join分表粒度不同的表,结果原本一次查的 有可能变多次查询)。
基于架构规范,性能,安全性等方面考虑,一般是禁止跨库join的。那该怎么办呢?首先要考虑下垂直分库的设计问题,如果可以调整,那就优先调整。如果无法调 整 的情况,下总结几种常见的解决思路,并分析其适用场景。
1、全局表:就是所有模块可能会依赖的表,比如数据字典表 为了避免跨库join查询,我们可以将这类表在其他每个数据库中均保存一份
2、字段冗余:频繁关联的表字段 冗余到当前表中(反范式),以空间换时间
3、ER分片:确定好表关系,把关联关系的表放在同一个分片上即可避免分片join
2、事物问题:
分库分表后数据库事物应用程序增加编程负担
后台报表系统中join表又N个了,分库后怎么查:
一般互联网业务系统中,本来尽量避免join,报表类的系统在传统BI时代都是通过OLAP数据仓库去实现的
分区分库规则:
分片的数据主键ID避免重复 1、雪花算法(twitter的snowflake) 2、uuid/guid 3、mongodb objectID (类似UUID)
分片字段一般采用int类型ID或者时间字段进行拆分
摘自:http://www.ywnds.com/?p=7239