2014年2月1日星期六

Architect_005:大容量数据如何分表?(摘录+整理)

有没有想过最简单的一个问题:一张表能存多少数据?
MySQL可以达到百万级别的数据存储,那么如果记录超过一百万条,该如何存储?
对于大容量的数据,我们需要进行分表
那么为什么要分表?分表的好处有哪些?
举个例子来说明一下:比如article表中现在有5000w条数据,此时我们需要在这个表中增加Insert一条新的数据,insert完毕后,数据库会针对这张表重新建立索引,5000w行数据建立索引的系统开销还是不容忽视的。
如果将这个表分成100个表,从article_001一直到article_100,5000w行数据平均下来,每个子表里边就只有50万行数据,这时候我们向一张只有50w行数据的表中Insert数据后建立索引的时间就会呈数量级的下降,极大了提高了DB的运行时效率,提高了DB的并发量。
除了提高建立索引速度,分表还降低了对表进行写操作时的锁时间。
总之,分表提高了数据操作的效率,尤其是写操作的效率。

表的分割方式有以下三种:

1.水平分割
根据一列或多列数据的值把数据行放到几个独立的表中。
水平分区将表分为多个表。每个表包含的列数相同,但是行更少。
例如:可以将一个包含十亿行的表水平分区成 12 个表,每个小表表示特定年份内一个月的数据。任何需要特定月份数据的查询只需引用相应月份的表。
水平分割通常在下面的情况下使用:
(1)表很大,分割后可以降低在查询时需要读的数据和索引的页数,同时也降低了索引的层数,提高查询速度。
(2)表中的数据本来就有独立性,例如表中分别记录各个地区的数据或不同时期的数据,特别是有些数据常用,而另外一些数据不常用。
(3)需要把数据存放到多个介质上。
水平分割会给应用增加复杂度,它通常在查询时需要多个表名,查询所有数据需要union操作。在许多数据库应用中,这种复杂性会超过它带来的优点,因为只要索引关键字不大,则在索引用于查询时,表中增加两到三倍数据量,查询时也就增加读一个索引层的磁盘次数。

2.垂直分割
把主码和一些列放到一个表,然后把主码和另外的列放到另一个表中。
将原始表分成多个只包含较少列的表。如果一个表中某些列常用,而另外一些列不常用,则可以采用垂直分割。
另外垂直分割可以使得数据行变小,一个数据页就能存放更多的数据,在查询时就会减少I/O次数。其缺点是需要管理冗余列,查询所有数据需要join操作。

3. 库表散列
库表散列与水平分割相似,但没有水平分割那样的明显分割界限,采用Hash算法把数据分散到各个分表中。
例子:1亿条数据在PHP中实现MySQL数据库分表100张,步骤如下:
(1)创建100张表
$i=0;
while($i<=99){
echo "$newNumber \r\n";
$sql="CREATE TABLE `code_".$i."` (
`full_code` char(10) NOT NULL,
`create_time` int(10) unsigned NOT NULL,
PRIMARY KEY  (`full_code`),
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
mysql_query($sql);
$i++;
(2)分表规则:以full_code作为主键,我们对full_code做hash函数:get_hash_table
$table_name=get_hash_table('code',$full_code);
function get_hash_table($table,$code,$s=100){
$hash = sprintf("%u", crc32($code));
echo $hash;
$hash1 = intval(fmod($hash, $s));
return $table."_".$hash1;
}
这样,插入数据前通过此函数获取数据存放的表名。
(3)使用MySQL的merge存储引擎来实现一张完整的code表
CREATE TABLE IF NOT EXISTS `code` (
`full_code` char(10) NOT NULL,
`create_time` int(10) unsigned NOT NULL,
INDEX(full_code)
) TYPE=MERGE UNION=(code_0,code_1,code_2.......) INSERT_METHOD=LAST ;        
这样我们就可以通过select * from code得到所有的full_code数据了。

参考文献:
1. http://coach.iteye.com/blog/854354
2. http://wenku.baidu.com/link?url=vDV0ESo1zyWHW83zlHWgOyq3sbEUsCEmIeTkrZ2xAUptrl3fkV1MocctSjs_O8FImiC8-PX-JFRdo7-_uqUrFXVCPqWmHyMk88asdfuTRli
3. http://club.sm160.com/showtopic-925045.aspx

没有评论: