1.为何要分表和分区?
平常开发中咱们常常会遇到大表的状况,所谓的大表是指存储了百万级乃至千万级条记录的表。这样的表过于庞大,致使数据库在查询和插入的时候耗时太长,性能低下,若是涉及联合查询的状况,性能会更加糟糕。分表和表分区的目的就是减小数据库的负担,提升数据库的效率,一般点来说就是提升表的增删改查效率。
2.什么是分表?
分表是将一个大表按照必定的规则分解成多张具备独立存储空间的实体表,咱们能够称为子表,每一个表都对应三个文件,MYD数据文件,.MYI索引文件,.frm表结构文件。这些子表能够分布在同一块磁盘上,也能够在不一样的机器上。app读写的时候根据事先定义好的规则获得对应的子表名,而后去操做它。
3.什么是分区?
分区和分表类似,都是按照规则分解表。不一样在于分表将大表分解为若干个独立的实体表,而分区是将数据分段划分在多个位置存放,能够是同一块磁盘也能够在不一样的机器。分区后,表面上仍是一张表,但数据散列到多个位置了。app读写的时候操做的仍是大表名字,db自动去组织分区的数据。
4.mysql分表和分区有什么联系呢?
(1)都能提升mysql的性高,在高并发状态下都有一个良好的表现。
(2)分表和分区不矛盾,能够相互配合的,对于那些大访问量,而且表数据比较多的表,咱们能够采起分表和分区结合的方式(若是merge这种分表方式,不能和分区配合的话,能够用其余的分表试),访问量不大,可是表数据不少的表,咱们能够采起分区的方式等。
(3)分表技术是比较麻烦的,须要手动去建立子表,app服务端读写时候须要计算子表名。采用merge好一些,但也要建立子表和配置子表间的union关系。
(4)表分区相对于分表,操做方便,不须要建立子表。html
1.分区的类型:
(1)Range:把连续区间按范围划分
例:mysql
create table user( id int(11), money int(11) unsigned not null, date datetime ) partition by range(YEAR(date))( partition p2014 values less than (2015), partition p2015 values less than (2016), partition p2016 values less than (2017), partition p2017 values less than maxvalue );
(2)List:把离散值分红集合,按集合划分,适合有固定取值列的表
例:web
create table user( a int(11), b int(11) ) partition by list(b)( partition p0 values in (1,3,5,7,9), partition p1 values in (2,4,6,8,0) );
(3)Hash:随机分配,分区数固定
例:sql
create table user( a int(11), b datetime ) partition by hash(YEAR(b)) partitions 4;
(4)Key:相似Hash,区别是只支持1列或多列,且mysql提供自身的Hash函数
例:数据库
create table user( a int(11), b datetime ) partition by key(b) partitions 4;
2.分区管理
(1)新增分区并发
ALTER TABLE sale_data ADD PARTITION (PARTITION p201710 VALUES LESS THAN (201711));
(2)删除分区app
--当删除了一个分区,也同时删除了该分区中全部的数据。 ALTER TABLE sale_data DROP PARTITION p201710;
(3)分区的合并
下面的SQL,将p201701 - p201709 合并为3个分区p2017Q1 - p2017Q3less
ALTER TABLE sale_data REORGANIZE PARTITION p201701,p201702,p201703, p201704,p201705,p201706, p201707,p201708,p201709 INTO ( PARTITION p2017Q1 VALUES LESS THAN (201704), PARTITION p2017Q2 VALUES LESS THAN (201707), PARTITION p2017Q3 VALUES LESS THAN (201710) );
3.分区应该注意的事项:
(1)作分区时,要么不定义主键,要么把分区字段加入到主键中。
(2)分区字段不能为NULL,要否则怎么肯定分区范围呢,因此尽可能NOT NULL数据库设计
1.垂直分表
把原来有不少列的表拆分红多个表,原则是:
(1)把经常使用、不经常使用的字段分开放
(2)把大字段独立存放在一个表中
2.水平分表
为了解决单表数据量过大的问题,每一个水平拆分表的结构彻底一致。
例:
(1)按时间结构
若是业务系统对时效性较高,好比新闻发布系统的文章表,能够把数据库设计成时间结构,按时间分有几种结构:
(a)平板式
表相似:函数
article_201701
article_201702
article_201703
用年来分仍是用月可自定,但用日期的话表就太多了,也没这必要。通常建议是按月分就能够。
这种分法,其难处在于,假设我要列20条数据,结果这三张表里都有2条,那么业务上颇有可能要求读三次表。若是时间长了,有几十张表,而每张表是0条,那不就是要读完整个系统的表才行么?另外这个结构,要做分页是比较难实现的。
主键:在这个系统中,主键是13位带毫秒的时间戳,不要用自动编号,不然难以经过主键定位到表,也能够在查询时带上时间,但比较烦琐。
(b)归档式
表相似:
article_old
article_new
为了解决平板式的缺点,能够采用时间归档式设计,能够看到这个系统只有两张表。一张是旧文章表,一张是新文章表,新文章表放2个月的信息,天天按期把2
个月中的最先一天的文章纳入旧表中。这样一方面能够解决性能问题,由于通常新闻发布系统读取的都是新的内容,旧的内容读取少;第二能够委婉地解决功能问
题,好比平板式所说的问题,在归档式中最多也只须要读2张表就完成了。
归档式的缺点在于旧表容量仍是相对比较大,若是业务容许,可对旧表中的超旧内容进行再归档或直接清理掉。
(2)按版块结构
若是按照文章的所属版块进行拆表,好比新闻、体育版块拆表,一方面可使每一个表数据量分离,另外一方面是各版块之间相互影响可降到最低。假如新闻版块的数据表损坏或须要维护,并不会影响到体育版块的正常工做,从而下降了风险。版块结构同时经常使用于bbs这样的系统。
板块结构也有几种分法:
(a)对应式
对于版块数量很少,并且较为固定的形式,就直接对应就好。好比新闻版块,能够分出新闻的目录表,新闻的文章表等。
news_category
news_article
sports_category
sports_article
可看到每个版块都对应着一组相同的表结构,好处就是一目了然。在功能上,由于版块之间仍是有一些隔阂,因此须要联合查询的需求很少,开发上比时间结构的方式要轻松。
主键:依旧要考虑的,在这个系统中,主键是版块+时间戳,单纯的时间戳或自动编号也能用,查询时要记得带上版块用于定位表。
(b)冷热式
对应式的缺点是,若是版块数量很大并且不肯定,那要分出的表数量就太多了。举个例子:百度贴吧,若是按一个词条一个表设计,那得有多少张表呢?
用这样的方式吧。
tieba_汽车
tieba_飞机
tieba_火箭
tieba_unite
这个表汽车、火箭表是属于热门表,定义为新建的版块放在unite表里面,待到其超过一万张主贴的时候才开对应表结构。由于在贴吧这种系统中,冷门版块
确定比热门版块多得多,这些冷门版块一般只有几张帖子,为它们开表也太浪费了;同时热门版块数量和访问量等,又比冷门版块多得多,很是有特色。
unite表还能够扩展成哈希表,利用词条的md5编码,能够分红n张表,我算了一下,md5前一位可分36张表,两位便是1296张表,足够了。
tieba_unite_ab
tieba_unite_ac
(3)按哈希结构
哈希结构一般用于博客之类的基于用户的场合,在博客这样的系统里有几个特色,1是用户数量很是多,2是每一个用户发的文章数量都较少,3是用户发文章不定
期,4是每一个用户发得很少,但总量仍很是之大。基于这些特色,用以上所说的任何一种分表方式都不合适,一没有固定的时效不宜用时间拆,二用户不少,并且还
恰恰都是冷门,因此也不宜用版块(用户)拆。
哈希结构在上面有所说起,既然按每一个用户很差直接拆,那就把一群用户归进一个表好了。
blog_aa
blog_ab
blog_ac
如上所说,md5取前两位哈希能够达到1296张表,若是以为不够,那就再加一位,总数可达46656张表,还不够?
表的数量太多,要建立这些表也是挺麻烦的,能够考虑在程序里往数据库insert以前,多执行一句判断表存在与否并建立表的语句,很实用,消耗也并不很大。
主键:依旧要考虑的,在这个系统中,主键是用户ID+时间戳,单纯的时间戳或自动编号也能用,但查询时要记得带上用户名用于定位表。
查看更多:
MySQL优化
MySQL各存储引擎
MySQL锁详解
MySQL事务
MySQL索引类型
参考资料:
http://blog.csdn.net/shmnh/article/details/44055059
http://blog.csdn.net/hijiankang/article/details/9173825
http://blog.csdn.net/feihong247/article/details/8100960
http://niehan.blog.techweb.com.cn/archives/279.html