数据库分表

一,先说一下为什么要分表

当一张的数据达到几百万时,你查询一次所花的时间会变多,如果有联合查询的话,我想有可能会死在那儿了。分表的目的就在于此,减小数据库的负担,缩短查询时间。

根据个人经验,mysql执行一个sql的过程如下:
1,接收到sql;2,把sql放到排队队列中 ;3,执行sql;4,返回执行结果。在这个执行过程中最花时间在什么地方呢?第一,是排队等待的时间,第二,sql的执行时间。其实这二个是一回事,等待的同时,肯定有sql在执行。所以我们要缩短sql的执行时间。

 

mysql中有一种机制是表锁定和行锁定,为什么要出现这种机制,是为了保证数据的完整性,我举个例子来说吧,如果有二个sql都要修改同一张表的同一条数据,这个时候怎么办呢,是不是二个sql都可以同时修改这条数据呢?很显然mysql对这种情况的处理是,一种是表锁定(myisam存储引擎),一个是行锁定(innodb存储引擎)。表锁定表示你们都不能对这张表进行操作,必须等我对表操作完才行。行锁定也一样,别的sql必须等我对这条数据操作完了,才能对这条数据进行操作。如果数据太多,一次执行的时间太长,等待的时间就越长,这也是我们为什么要分表的原因。

二,分表

1,做mysql集群,例如:利用mysql cluster ,mysql proxy,mysql replication,drdb等等

有人会问mysql集群,根分表有什么关系吗?虽然它不是实际意义上的分表,但是它启到了分表的作用,做集群的意义是什么呢?为一个数据库减轻负担,说白了就是减少sql排队队列中的sql的数量,举个例子:有10个sql请求,如果放在一个数据库服务器的排队队列中,他要等很长时间,如果把这10个sql请求,分配到5个数据库服务器的排队队列中,一个数据库服务器的队列中只有2个,这样等待时间是不是大大的缩短了呢?这已经很明显了。所以我把它列到了分表的范围以内,我做过一些mysql的集群:

linux mysql proxy 的安装,配置,以及读写分离

mysql replication 互为主从的安装及配置,以及数据同步

优点:扩展性好,没有多个分表后的复杂操作(php代码)

缺点:单个表的数据量还是没有变,一次操作所花的时间还是那么多,硬件开销大。


1. 先了解一下你是否应该用MySQL集群。

减少数据中心结点压力和大数据量处理,采用把MySQL分布,一个或多个application对应一个MySQL数据库。把几个MySQL数据库公用的数据做出共享数据,例如购物车,用户对象等等,存在数据结点里面。其他不共享的数据还维持在各自分布的MySQL数据库本身中。


2. 集群MySQL中名称概念.(如上图)

1)Sql结点(SQL node--上图对应为MySQLd):分布式数据库。包括自身数据和查询中心结点数据.

2)数据结点(Data node -- ndbd):集群共享数据(内存中).

3)管理服务器(Management Server – ndb_mgmd):集群管理SQL node,Data node.


方法二、

2,预先估计会出现大数据量并且访问频繁的表,将其分为若干个表

(1)预先估计某个大表的数据量,按实际情况将其均分为固定数量表

根据分表算法,将数据平均分散到不同的数据表中,常见处理方式有对自增id取模、对某个字段进行hash。比如某系统用户预计支持1亿用户数,分100个表存储用户数据,按照自增id的最后2位来分表,对100取模,那么用户数据表就是user_01~user_99。

(2)按时间拆分

对于那种根据时间增长较快的数据可以按时间拆分,根据业务实际情况按天、按月、按年等进行拆分。比如进销存数据,我们可以按月分表,形如jxc_data_201201、jxc_data_201202

(3)按每个表固定记录行数拆分

一般根据自增长ID拆表,每张表存储指定数量的数据。一张表的数据行数到了指定数量,就自动保存到新的表里。

优点:避免一张表出现几百万条数据,缩短了一条sql的执行时间

缺点:当一种规则确定时,打破这条规则会很麻烦,上面的例子中我用的hash算法是crc32,如果我现在不想用这个算法了,改用md5后,会使同一个用户的消息被存储到不同的表中,这样数据乱套了。扩展性很差。

三、分表之后的处理

分表之后,麻烦的事情来了,业务数据分散在各个分表中,之前的业务功能如何保证呢?比如说我要插入一条记录、更新一条记录、删除一条记录、查询统计数据,现在要怎么处理呢。

如何你用的user分表的存储引擎是MyISAM,那么恭喜你,这里有一种很简单的处理方法。

利用merge存储引擎将拆分的表合并成一张表

 MERGE存储引擎可以将N个子表联合在一起,看成是一个整表,实际上还是N个真实的子表。

在我们查询这个merge表就相当于查询所有字表的数据了,非常方便。当然merge表还是有一定的限制的,具体请查看mysql官方手册。

这里引用MYSQL参考手册中的片段来说明如何操作

下面例子说明如何创建一个MERGE表:

mysql> CREATE TABLE t1(

   ->   a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,

   ->   message CHAR(20));

mysql> CREATE TABLE t2(

   ->   a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,

   ->   message CHAR(20));

mysql> INSERT INTO t1(message) VALUES ('Testing'),('table'),('t1');

mysql> INSERT INTO t2(message) VALUES ('Testing'),('table'),('t2');

mysql> CREATE TABLEtotal (

   ->   a INT NOT NULL AUTO_INCREMENT,

   ->   message CHAR(20), INDEX(a))

   ->   TYPE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST;

注意,一个列在MERGEN表中被索引,但没有被宣告为一个PRIMARY KEY,因为它是在更重要的MyISAM表中。这是必要的,因为MERGE表在更重要的表中的设置上强制非唯一性。

创建MERGE表之后,你可以发出把一组表当作一体来操作的查询:

mysql> SELECT * FROMtotal;

+---+---------+

| a | message |

+---+---------+

| 1 | Testing |

| 2 | table  |

| 3 | t1     |

| 1 | Testing |

| 2 | table  |

| 3 | t2     |

+---+---------+

 

根据这个方法的介绍,我们可以创建一张user的合并表,然后对这张表进行查询即可达到查询分表所有的数据的效果。

-----------------------------------------我是分割线---------------------------------

实际使用中,会限制页面的显示记录,理论上数据库操作100w条记录(联合查询)延迟时间可以接受,对于分表,页面会对每一张表分别联合查询,将每一张表的数据分别显示。

如果要对所有的数据一起操作,要建一个日志服务器单独处理日志。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值