说过不少次,不要拘泥于某一个技术的一点,技术是相通的。重要的是编程思想,思想是最重要的。当数据量大的时候,须要具备分的思想去细化粒度。当数据量太碎片的时候,须要具备合的思想来粗化粒度。html
不少技术都运用了分的编程思想,这里来举几个例子,这些都是分的思想mysql
不少技术也运用到了合的编程思想,这里举几个例子,这些都是合的思想算法
本文一切基于MySql InnoDBsql
说了这么多,接下来讲主体,先说分区,由于以前博主写过一篇MySql分区的博客因此这里不会多费笔墨来写,具体见:http://www.javashuo.com/article/p-myhkzsfl-ho.html数据库
具体如何实现上面连接里有写,这里只需记住若是表中存在主键或惟一索引时,分区列必须是惟一索引的一个组成部分。编程
这个是数据库分的,应用透明,代码无需修改任何东西。缓存
先去data目录,若是不知道目录位置的能够执行:安全
接下来看下内部文件:网络
从上图咱们能够看出,有2中类型的文件,.frm文件和.ibd文件多线程
分区表后,提升了MySql性能。若是一张表的话,那就只有一个.ibd文件,一颗大的B+树。若是分表后,将按分区规则,分红不一样的区,也就是一个大的B+树,分红多个小的树。
(PS:若是想研究一颗汇集索引B+树能够放多少行数据,请看:http://www.javashuo.com/article/p-cktkdfzo-bh.html)
读的效率确定提高了,若是走分区键索引的话,先走对应分区的辅助索引B+树,再走对应分区的汇集索引B+树。
若是没有走分区键,将会在全部分区都会执行一次。会形成屡次逻辑IO!平时开发若是想查看sql语句的分区查询可使用explain partitons select xxxxx语句。能够看到一句select语句走了几个分区。
mysql> explain partitions select * from TxnList where startTime>'2016-08-25 00:00:00' and startTime<'2016-08-25 23:59:00'; +----+-------------+-------------------+------------+------+---------------+------+---------+------+-------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------------------+------------+------+---------------+------+---------+------+-------+-------------+ | 1 | SIMPLE | ClientActionTrack | p20160825 | ALL | NULL | NULL | NULL | NULL | 33868 | Using where | +----+-------------+-------------------+------------+------+---------------+------+---------+------+-------+-------------+ row in set (0.00 sec)
当一张表随着时间和业务的发展,库里表的数据量会愈来愈大。数据操做也随之会愈来愈大。一台物理机的资源有限,最终能承载的数据量、数据的处理能力都会受到限制。这时候就会使用分库分表来承接超大规模的表,单机放不下的那种。
区别于分区的是,分区通常都是放在单机里的,用的比较多的是时间范围分区,方便归档。只不过度库分表须要代码实现,分区则是mysql内部实现。分库分表和分区并不冲突,能够结合使用。
分库分表字段取值很是重要
通常使用userId,能够知足上述条件
分布式数据库中间件分为两种,proxy和客户端式架构。proxy模式有MyCat、DBProxy等,客户端式架构有TDDL、Sharding-JDBC等。那么proxy和客户端式架构有何区别呢?各自有什么优缺点呢?其实看一张图即可知晓。
proxy模式的话咱们的select和update语句都是发送给代理,由这个代理来操做具体的底层数据库。因此必需要求代理自己须要保证高可用,不然数据库没有宕机,proxy挂了,那就走远了。
客户端模式一般在链接池上作了一层封装,内部与不一样的库链接,sql交给smart-client进行处理。一般仅支持一种语言,若是其余语言要使用,须要开发多语言客户端。
各自的优缺点以下:
找了一个分库分表+分区的例子,基本上和分区表的差很少,只是多了多了不少表的.ibd文件,上面有文件的解释:
[miaojiaxing@Grim testmydata]# ls | grep 'base_info' base_info_00.frm base_info_00#P#p_2018.ibd base_info_00#P#p_2019.ibd base_info_00#P#p_2020.ibd base_info_00#P#p_2021.ibd base_info_00#P#p_init.ibd base_info_00#P#p_max.ibd base_info_01.frm base_info_01#P#p_2018.ibd base_info_01#P#p_2019.ibd base_info_01#P#p_2020.ibd base_info_01#P#p_2021.ibd base_info_01#P#p_init.ibd base_info_01#P#p_max.ibd base_info.frm base_info.ibd
既然分库分表了,那么确定涉及到分布式事务,如何保证插入到不一样库的多条记录可以要么同时成功,要么同时失败。有些同窗可能想到XA,XA性能差并且不须要使用mysql5.7。柔性事务是目前主流的方案,TCC模式就属于柔性事务。
对于分布式事务问题每家公司有本身的实现,华为用saga,阿里用TXC,蚂蚁用DTX,支持FMT模式和TCC模式。
tddl、MyCAT等都支持跨分片join。可是尽力避免跨库join,好比经过字段冗余的方式等。
若是出现了这种状况且中间件支持分片join,那么能够这样使用。若是不支持能够手工查询。
分表和在用途上不同,分表是为了承接超大规模的表,单机放不下那种。分区的话则通常都是放在单机里的,用的比较多的是时间范围分区,方便归档。性能稳定上的话都是一个个子表,差很少,区别应该是分区表是mysql内部实现的,会比分表方案少一点数据交互