【转】分布式数据库拆表拆库的常用策略

转载:http://www.cnblogs.com/VipBin/archive/2011/07/12/2104690.html

在大容量,高负荷的web系统中,对数据库进行一系列拆分,可有效提升数据库容量和性能。在初学程序的早期,程序员通常都喜欢按传统数据库设计模式,设计为单库和单一功能表的结构,这样的结构在数据量和并发量达到一定程度之后,会出现严重性能问题和维护问题。在出现问题的时候才着手进行优化,会非常痛苦,所以应该在系统架设之初就考虑好之后会出现的问题。

目前有些数据库策略是采用单库结构,然后通过同步分发到数台服务器实现读写分离。个人觉得这样的策略非常笨拙,还是想办法将其分隔开来好,否则每台机器的内存都很容易超支。

一般只对数据量比较大的表进行拆分,这应该没有什么异议;还有一种是有可能会进行维护的比较重要的表,比如文章目录表,如果有从其它系统倒数据进来的可能的话,也要拆掉,不然倒数据时一不小心把目录表弄坏了,发现忘了备份,那真是欲哭无泪。

下面来分析一下:

一、时间结构

如果业务系统对时效性较高,比如新闻发布系统的文章表,可以把数据库设计成时间结构,按时间分有几种结构:

1) 平板式

表类似: 
article_200901 
article_200902 
article_200903

用年来分还是用月可自定,但用日期的话表就太多了,也没这必要。一般建议是按月分就可以。

这种分法,其难处在于,假设我要列20条数据,结果这三张表里都有2条,那么业务上很有可能要求读三次表。如果时间长了,有几十张表,而每张表是0条,那不就是要读完整个系统的表才行么?另外这个结构,要作分页是比较难实现的。

主键:在这个系统中,主键是13位带毫秒的时间戳,不要用自动编号,否则难以通过主键定位到表,也可以在查询时带上时间,但比较烦琐。

2) 归档式

表类似: 
article_old 
article_new

为了解决平板式的缺点,可以采用时间归档式设计,可以看到这个系统只有两张表。一张是旧文章表,一张是新文章表,新文章表放2个月的信息,每天定期把2个月中的最早一天的文章归入旧表中。这样一方面可以解决性能问题,因为一般新闻发布系统读取的都是新的内容,旧的内容读取少;第二可以委婉地解决功能问题,比如平板式所说的问题,在归档式中最多也只需要读2张表就完成了。

归档式的缺点在于旧表容量还是相对比较大,如果业务允许,可对旧表中的超旧内容进行再归档或直接清理掉。

二、版块结构

如果按照文章的所属版块进行拆表,比如新闻、体育版块拆表,一方面可以使每个表数据量分离,另一方面是各版块之间相互影响可降到最低。假如新闻版块的数据表损坏或需要维护,并不会影响到体育版块的正常工作,从而降低了风险。版块结构同时常用于bbs这样的系统。

板块结构也有几种分法:

1) 对应式

对于版块数量不多,而且较为固定的形式,就直接对应就好。比如新闻版块,可以分出新闻的目录表,新闻的文章表等。

news_category 
news_article 
sports_category 
sports_article

可看到每一个版块都对应着一组相同的表结构,好处就是一目了然。在功能上,因为版块之间还是有一些隔阂,所以需要联合查询的需求不多,开发上比时间结构的方式要轻松。

主键:依旧要考虑的,在这个系统中,主键是版块 时间戳,单纯的时间戳或自动编号也能用,查询时要记得带上版块用于定位表。

2) 冷热式

对应式的缺点是,如果版块数量很大而且不确定,那要分出的表数量就太多了。举个例子:百度贴吧,如果按一个词条一个表设计,那得有多少张表呢?

用这样的方式吧。

tieba_汽车 
tieba_飞机 
tieba_火箭 
tieba__unite

这个表汽车、火箭表是属于热门表,定义为新建的版块放在unite表里面,待到其超过一万张主贴的时候才开对应表结构。因为在贴吧这种系统中,冷门版块肯定比热门版块多得多,这些冷门版块通常只有几张帖子,为它们开表也太浪费了;同时热门版块数量和访问量等,又比冷门版块多得多,非常有特点。

unite表还可以扩展成哈希表,利用词条的md5编码,可以分成n张表,我算了一下,md5前一位可分36张表,两位即是1296张表,足够了。

tieba_unite_ab 
tieba_unite_ac 
...

三、哈希结构

哈希结构通常用于博客之类的基于用户的场合,在博客这样的系统里有几个特点,1是用户数量非常多,2是每个用户发的文章数量都较少,3是用户发文章不定期,4是每个用户发得不多,但总量仍非常之大。基于这些特点,用以上所说的任何一种分表方式都不合适,一没有固定的时效不宜用时间拆,二用户很多,而且还偏偏都是冷门,所以也不宜用版块(用户)拆。

哈希结构在上面有所提及,既然按每个用户不好直接拆,那就把一群用户归进一个表好了。

blog_aa 
blog_ab 
blog_ac 
...

如上所说,md5取前两位哈希可以达到1296张表,如果觉得不够,那就再加一位,总数可达46656张表,还不够?

表的数量太多,要创建这些表也是挺麻烦的,可以考虑在程序里往数据库insert之前,多执行一句判断表存在与否并创建表的语句,很实用,消耗也并不很大。

主键:依旧要考虑的,在这个系统中,主键是用户ID 时间戳,单纯的时间戳或自动编号也能用,但查询时要记得带上用户名用于定位表。

四、总分结构

以上的这些结构,根据每个业务系统,能想出的估计还有很多。不过现在互联网业务越来越复杂了,有些时候,单一的拆分法还不能实现需求,需要几种拆分方案一起实施,多管齐下,这时候其中的逻辑会让人绕晕。我就开发过一个系统,仅仅是将哈希结构和时间结构混着一用,觉得逻辑就相当复杂。

所以,除了拆表之外,按最原始的单库单表,再建一个总表,是非常有利的架构。在这个架构中,每次往数据库会写入两倍数据,读取主要依赖拆表提升性能,总表用于实现拆表后难以实现的功能并且用于每天的定时备份;另外总表和分表还相互是一个完整的备份,任何一个分表损坏或数据不正常,都可以从总表中读到正确的数据并恢复,反之亦然。

在总分结构中,让人感到质疑的是总表的性能和可维护性。我的方案是总表可采用相对能保证稳定的一些服务软件和架构,例如oracle,或lvs pgpool PostgreSQL,重点保证数据稳定;相对的,分表就用轻量级的mysql,重点在于速度。能够对总分表各采用不同的软件和方案,也是总分结构的一大特点。

总结:

如何通过拆表来优化系统,最基本的是要按业务需求和特点分析。本文仅仅是提供了几种基本方法,具体工作要先动脑好好想,千万不可乱套,用错了工作量要加十倍噢。

时间: 2024-10-15 23:11:10

【转】分布式数据库拆表拆库的常用策略的相关文章

分布式数据库中全局唯一主键

[相关文章] <分布式数据库中全局唯一主键生成策略的设计与实现><activiti5.10解决分布式集群部署的主键问题><分布式环境下数据库主键方案><如何在高并发分布式系统中生成全局唯一Id><分布式环境下ID生成方法总结> <分布式环境下数据库主键方案> [ http://www.2cto.com/database/201309/243195.html ] 在只使用单数据库时,使用自增主键ID无疑是最适合的.但在集群.主从架构上时

分布式数据库MVCC读写设计

分布式数据库数据表分成多个parition,分布在不同server上,拓扑是每个server维护不同的版本时间戳,相比单机数据库,提供MVCC要复杂很多,当然,你如果有spanner的原子钟,那会简单很多. 现描述一种可行的实现方案,抛砖引玉. 此方案可以做如下保证: 1.单Partition读(分分布式事务读)可以保重repeated read. 2同一个server上的分布式事务可以保证repeated read,并且对外保证因果序列: 3.跨partition不能保证因果序,但可保证rep

数据库水平切分(拆库拆表)的实现原理解析(转)

第1章  引言 随着互联网应用的广泛普及,海量数据的存储和访问成为了系统设计的瓶颈问题.对于一个大型的互联网应用,每天几十亿的PV无疑对数据库造成了相当 高的负载.对于系统的稳定性和扩展性造成了极大的问题.通过数据切分来提高网站性能,横向扩展数据层已经成为架构研发人员首选的方式.水平切分数据库,可 以降低单台机器的负载,同时最大限度的降低了了宕机造成的损失.通过负载均衡策略,有效的降低了单台机器的访问负载,降低了宕机的可能性:通过集群方案, 解决了数据库宕机带来的单点数据库不能访问的问题:通过读

OGG进程拆分(单表拆成多个进程)

OGG进程拆分(单表拆成多个进程) 概要: <OGG进程拆分>介绍了如何将一个入库进程中的多个表拆分到其他进程中.本篇将着重介绍如何使用多个进程同时入库一张表. 适用条件: 1)入库进程只同步一张表,但仍有延时 2)目标段主机CPU.内存压力不大,以便有足够的资源添加新的入库进程 本示例将RZG_CXI2中的HX_SB.SB_CWBB_XQYKJZZ_ZCFZB表拆分到RZG_CXI1-RZG_CXI8这8个进程中 1. 创建新添加进程的配置文件 edit  params RZG_CXI1 #

【干货】浅谈分布式数据库中间件之分库分表

分库分表,顾名思义就是把原本存储于一个库的数据分块存储到多个库上,把原本存储于一个表的数据分块存储到多个表上.那么关于分库分表,你了解多少呢?接下来,我们将从什么是数据分片及如何进行分片两方面对DDM分库分表做一个阐释.什么是数据分片 分片是解决数据库存储容量限制的直接途径.分片包括垂直分片与水平分片两种方式. 垂直分片 垂直分片又叫纵向分割,即以逻辑表为单位,把原有数据库切分成多个数据库.切分后不同的表存储在不同的数据库上. 垂直分片与业务架构设计有密切的联系.比如从业务领域对系统进行架构优化

第16课-数据库开发及ado.net-数据库SQl,创建数据库和表,增删改语句,约束,top和Distinct,聚合函数介绍

第16课-数据库开发及ado.net 数据库SQl,创建数据库和表,增删改语句,约束,top和Distinct,聚合函数介绍 SQL语句入门(脚本.命令) SQL全名是结构化查询语言(Structured Query Language) SOL语句是和DBMS“交谈”专用的语言,不同的DBMS都认SQL语法. Sql中字符串使用单引号:通过写俩个单引号来转义一个单引号. Sql中的注释“——” 单行注释比较好 判断俩个数据是否相等使用=(单等号) 在sql语句中sql代码不区分大小写 SQL主要

分布式数据库中间件的实现原理介绍一:分库分表【转】

声明:本文并非原创,转自华为云帮助中心的分布式数据库中间件(DDM)服务的产品介绍. 分片是解决数据库存储容量限制的直接途径.分片包括垂直分片与水平分片两种方式. 垂直分片 垂直分片又叫纵向分割,即以逻辑表为单位,把原有数据库切分成多个数据库.切分后不同的表存储在不同的数据库上. 垂直分片与业务架构设计有密切的联系.比如从业务领域对系统进行架构优化,分成多个子业务系统,各个子业务系统耦合度较低.子业务系统间以接口方式进行数据通信和数据交换. 图2 垂直分片示意图  垂直拆分后业务清晰,拆分规则明

MySql重装以后,修改数据库路径,打开以前的数据库报Table &#39;XX库.XX表&#39; doesn&#39;t exist错误的解决办法

因为mysql主流的数据库引擎有MyISAM和InnoDB两种, 如果是MyISAM,直接把以前数据库拷贝到修改后的路径是可以的 但是InnoDB因为存储结构不同,必须还得把备份的innodb数据库表“*.frm”文件和innodb数据“ibdata1”文件拷到修改后的合适路径 参考资料:http://www.bcty365.com/content-35-2928-1.html https://blog.csdn.net/dihuangtian01/article/details/5177353

大型分布式数据库集群的研究

1.为什么要设计成分布式数据库,数据为什么要分区? 当数据量很大的时候,即使服务器在没有任何压力的情况下,某些复杂的查询操作都会非常缓慢,影响了最终用户的体验. 在大数据量下对数据库的装载与导出,备份与恢复,结构的调整,索引的调整等都会让数据库停止服务或者高负荷运转很长时间,影响了数据库的可用性和可管理性. 这个时候靠提升服务器的硬件配置是起不到作用的,只有靠分区把数据分成更小的部分才能提高数据库的可用性和可管理性. 通过分区把各部分数据放到不同的机器中,每次查询可以由多个机器上的CPU,I/O