mysql分表的一些方案

2020-06-21 13:55:55

写在前面

  1. 为什么要分表呢?这个看似不是问题的问题先埋个点

进入主题吧

**ps: 这里只分享一下业务上面进行分表的一些方法吧

一. 垂直分表

垂直分表在业务开发过程中应该是随处可见的,比如:用户相关的表

CREATE TABLE `user` (
  `uid` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `user_name` varchar(50) DEFAULT '' COMMENT '用户登录名',
  `password` char(32) DEFAULT '' COMMENT '用户登录密码',
  `is_del` tinyint(1) unsigned DEFAULT '1' COMMENT '1,正常 2,删除',
  `create_time` char(10) DEFAULT '0' COMMENT '录入时间',
  `update_time` char(10) DEFAULT '0' COMMENT '更新时间',
  PRIMARY KEY (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用户基本表';

CREATE TABLE `user_info` (
  `uid` int(11) unsigned NOT NULL,
  `head_img` varchar(50) DEFAULT '' COMMENT '头像',
  `nick_name` varchar(50) DEFAULT '' COMMENT '昵称',
  `sign_content` varchar(255) DEFAULT '' COMMENT '个性签名',
  `update_time` char(10) DEFAULT '0' COMMENT '更新时间',
  PRIMARY KEY (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用户信息表';

......

如上所见,垂直分表就是把一个实体按照某种属性进行分类划分成多个表。


.

二.水平分表

1. 范围取表方式

比如用户联系信息: 我们可以按照范围分表

1-100w: user_info_1 100w-200w: user_info_2

CREATE TABLE `user_info_{{1+}}` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `uid` int(11) NOT NULL DEFAULT '0' COMMENT '用户uid',
  `mobile` varchar(20) NOT NULL DEFAULT '' COMMENT '手机号',
  `address` varchar(50) NOT NULL DEFAULT '' COMMENT '住址',
  ......
  `is_del` tinyint(1) unsigned DEFAULT '1' COMMENT '1,正常 2,删除',
  `create_time` char(10) DEFAULT '0' COMMENT '录入时间',
  `update_time` char(10) DEFAULT '0' COMMENT '更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uid_index` (`uid`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用户联系信息表';

.

2. 特定的算法分表(取模、哈希)

取模:比如用户ID%100,分100张表

CREATE TABLE `visit_record_{{1-100}}` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `uid` int(11) NOT NULL DEFAULT '0' COMMENT '所属人uid',
  `source_id` int(11) NOT NULL DEFAULT '0' COMMENT '资源id',
  `type_mark` int(10) NOT NULL DEFAULT '0' COMMENT '资源类型',
  ......
  `create_time` char(10) DEFAULT '0' COMMENT '录入时间',
  `update_time` char(10) DEFAULT '0' COMMENT '更新时间',
  PRIMARY KEY (`id`),
 UNIQUE KEY `st_index` (`source_id`,`type_mark`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用户资源访问记录';

优缺点:

取模方式:

冷热数据比较均衡,但扩展性比较差,一但数据量超过预期,原定表数量就无法承载,再加表就比较麻烦

范围方式:

扩展性比较强,但是一般新用户是比较活跃的,大部分都查询到新表上面,就导致冷热数据不均衡要解决这样的问题可以两者结合互补, 首先根据范围进行分组: 比如用户1~1000w,分为10张表,然后 uid%10 得到具体表、相当于1-10表的总数据量已经确定了,先取范围再取模,扩展性问题就不存在了

本文由"putyy"原创,转载无需和我联系,但请注明来自putyy
您的浏览器不支持canvas标签,请您更换浏览器