北京SEO

Mysql数据库水平分表实现方案

2019/10/10/17:37:57  阅读:2127  来源:谷歌SEO算法  标签: SEO知识

mysql分表一般是碰到数据量大的业务了才可能做的一个数据优化处理工具了,下面本文章给各位介绍在不同数量量时的一个分表方案,希望这些方案能帮助到各位朋友.

根据经验,Mysql表数据一般达到百万级别,查询效率会很低,容易造成表锁,甚至堆积很多连接,直接挂掉,水平分表能够很大程度较少这些压力.

1.按时间分表

这种分表方式有一定的局限性,当数据有较强的实效性,如微博发送记录、微信消息记录等,这种数据很少有用户会查询几个月前的数据,如就可以按月分表.

2.按区间范围分表

一般在有严格的自增id需求上,如按照user_id水平分表:

table_1 user_id从1~100w

table_2 user_id从101~200w

table_3 user_id从201~300w

...

3.hash分表

通过一个原始目标的ID或者名称通过一定的hash算法计算出数据存储表的表名,然后访问相应的表,按如下分10张表,代码如下:

  1. functionget_hash_table($table,$userid)
  2. {
  3. $str=crc32($userid);
  4. if($str<0){
  5. $hash="0".substr(abs($str),0,1);
  6. }else{
  7. $hash=substr($str,0,2);
  8. }
  9. return$table."_".$hash;
  10. }
  11. echoget_hash_table('message','user18991');//结果为message_10
  12. echoget_hash_table('message','user34523');//结果为message_13

另外,介绍我现在就是采用简单的取模分表,代码如下:

  1. /**
  2. *@paramstring$table_name表名
  3. *@paramint$user_id用户id
  4. *@paramint$total分表总数
  5. *@linkhttp://www.phpfensi.com
  6. */
  7. functionhash_table($table_name,$user_id,$total)
  8. {
  9. return$table_name.'_'.(($user_id%$total)+1);
  10. }
  11. echohash_table("artice",1234,5);//artice_5
  12. echohash_table("artice",3243,5);//artice_4

4.利用merge存储引擎分表

感觉merge存储引擎类似sql中union的感觉,但是查询效率不高,如下举例,拥有1000w记录的old_user表分表:

1),创建new_user表使用merge存储引擎,代码如下:

  1. mysql>CREATETABLEIFNOTEXISTS`user1`(
  2. ->`id`int(11)NOTNULLAUTO_INCREMENT,
  3. ->`name`varchar(50)DEFAULTNULL,
  4. ->`sex`int(1)NOTNULLDEFAULT'0',
  5. ->PRIMARYKEY(`id`)
  6. ->)ENGINE=MyISAMDEFAULTCHARSET=utf8AUTO_INCREMENT=1;
  7. QueryOK,0rowsaffected(0.05sec)
  8. mysql>CREATETABLEIFNOTEXISTS`user2`(
  9. ->`id`int(11)NOTNULLAUTO_INCREMENT,
  10. ->`name`varchar(50)DEFAULTNULL,
  11. ->`sex`int(1)NOTNULLDEFAULT'0',
  12. ->PRIMARYKEY(`id`)
  13. ->)ENGINE=MyISAMDEFAULTCHARSET=utf8AUTO_INCREMENT=1;
  14. QueryOK,0rowsaffected(0.01sec)
  15. mysql>INSERTINTO`user1`(`name`,`sex`)VALUES('张映',0);
  16. QueryOK,1rowaffected(0.00sec)
  17. mysql>INSERTINTO`user2`(`name`,`sex`)VALUES('tank',1);
  18. QueryOK,1rowaffected(0.00sec)
  19. mysql>CREATETABLEIFNOTEXISTS`new_user`(
  20. ->`id`int(11)NOTNULLAUTO_INCREMENT,
  21. ->`name`varchar(50)DEFAULTNULL,
  22. ->`sex`int(1)NOTNULLDEFAULT'0',
  23. ->INDEX(id)
  24. ->)TYPE=MERGEUNION=(user1,user2)INSERT_METHOD=LASTAUTO_INCREMENT=1;
  25. QueryOK,0rowsaffected,1warning(0.00sec)
  26. mysql>selectid,name,sexfromnew_user;
  27. +----+--------+-----+
  28. |id|name|sex|
  29. +----+--------+-----+
  30. |1|张映|0|
  31. |1|tank|1|
  32. +----+--------+-----+
  33. 2rowsinset(0.00sec)
  34. mysql>INSERTINTO`new_user`(`name`,`sex`)VALUES('tank2',0);
  35. QueryOK,1rowaffected(0.00sec)
  36. mysql>selectid,name,sexfromuser2
  37. ->;
  38. +----+-------+-----+
  39. |id|name|sex|
  40. +----+-------+-----+
  41. |1|tank|1|
  42. |2|tank2|0|
  43. +----+-------+-----+

rows in set (0.00 sec)

2),old_user数据进行分表,代码如下:

INSERT INTO user1(user1.id,user1.name,user1.sex) SELECT (user.id,user.name,user.sex)FROM old_user where user.id <= 5000000

INSERT INTO user2(user2.id,user2.name,user2.sex) SELECT (user.id,user.name,user.sex)FROM old_user where user.id > 10000000

广告内容

Mysql数据库水平分表实现方案 Mysql数据库水平分表实现方案 Mysql数据库水平分表实现方案

相关阅读

热门评论

爱互踩 爱互踩

爱互踩流量交换~

总篇数175

精选文章

RMAN中catalog和nocatalog区别介绍 小技巧:为Linux下的文件分配多个权限 zimbra8.5.1安装第三方签名ssl证书的步骤 解决mysql不能远程连接数据库方法 windows服务器mysql增量备份批处理数据库 mysql中slow query log慢日志查询分析 JavaScript跨域问题总结 Linux下负载均衡软件LVS配置(VS/DR)教程 mysql中权限参数说明 MYSQL(错误1053)无法正常启动

SEO最新算法